aboutsummaryrefslogtreecommitdiff
path: root/src/engine.cpp
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2023-11-21 03:11:49 +0100
committervimene <vincent.menegaux@gmail.com>2023-11-21 03:11:49 +0100
commit7b2bb469c13702498a49d6a8a9cf1bd2a4efcfff (patch)
tree248f1926c49e87c8a2dd3f9025beb7ae7e6f63ab /src/engine.cpp
parent5f5d5d07c3ea8bead4241d6cce9ee14be226610b (diff)
downloadengine-7b2bb469c13702498a49d6a8a9cf1bd2a4efcfff.tar.gz
renamed binary from 'main' to 'engine'
Diffstat (limited to 'src/engine.cpp')
-rw-r--r--src/engine.cpp510
1 files changed, 510 insertions, 0 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
new file mode 100644
index 0000000..840d2f9
--- /dev/null
+++ b/src/engine.cpp
@@ -0,0 +1,510 @@
+#include "config.h"
+#include <iostream>
+
+#ifdef ENABLE_NCURSES
+#include <ncurses.h>
+#endif
+
+#ifdef __WINDOWS__
+#include <windows.h>
+#endif
+
+#include <cmath>
+#include <cstdint>
+#include <vector>
+#include <SDL.h>
+#include "chfb.h"
+#include "pixfb.h"
+#include "obj3d.h"
+#include "math_vector.h"
+#include "vertex.h"
+#include "vertex_data.h"
+#include "tri_vertex.h"
+
+#define MKEY_Z 122
+#define MKEY_Q 113
+#define MKEY_S 115
+#define MKEY_D 100
+
+#define MKEY_ESC 27
+
+#define FPS 60
+
+#define PI 3.1415926535f
+
+#ifdef ENABLE_NCURSES
+void main_term() {
+ // init
+ setlocale(LC_ALL, "");
+ initscr();
+ cbreak();
+ noecho();
+ intrflush(stdscr, FALSE);
+ keypad(stdscr, TRUE);
+ set_escdelay(0);
+ curs_set(0);
+
+ int w, h;
+ getmaxyx(stdscr, h, w);
+ CharacterFrameBuffer cfb{static_cast<unsigned int>(w), static_cast<unsigned int>(h)};
+
+ MathVector3 a{0.f, 0.f, 0.f};
+ float dist = 4.f;
+ while (1) {
+ //timeout(1000 / FPS);
+ timeout(10);
+ int c = getch();
+
+ if (c == MKEY_ESC) break;
+ switch (c) {
+ case KEY_UP:
+ // a.x += 0.1f;
+ dist += .1f;
+ break;
+ case KEY_DOWN:
+ // a.x -= 0.1f;
+ dist -= .1f;
+ break;
+ case KEY_LEFT:
+ // a.y += 0.1f;
+ break;
+ case KEY_RIGHT:
+ // a.y -= 0.1f;
+ break;
+ case MKEY_Q:
+ // a.z += 0.1f;
+ break;
+ case MKEY_D:
+ // a.z -= 0.1f;
+ break;
+ }
+
+ a.x += .0050f;
+ a.y += .0065f;
+ a.z += .0080f;
+
+ getmaxyx(stdscr, h, w);
+ cfb.resize(static_cast<unsigned int>(w), static_cast<unsigned int>(h));
+
+ float rad = 5.f;
+ MathVector3 ca{std::cos(a.x), std::cos(a.y), std::cos(a.z)};
+ MathVector3 sa{std::sin(a.x), std::sin(a.y), std::sin(a.z)};
+
+ std::array<MathVector3, 3> rot_x = {{
+ { 1.f, 0.f, 0.f },
+ { 0.f, ca.x, sa.x },
+ { 0.f, -sa.x, ca.x },
+ }};
+ std::array<MathVector3, 3> rot_y = {{
+ { ca.y, 0.f, -sa.y },
+ { 0.f, 1.f, 0.f },
+ { sa.y, 0.f, ca.y },
+ }};
+ std::array<MathVector3, 3> rot_z = {{
+ { ca.z, sa.z, 0.f },
+ { -sa.z, ca.z, 0.f },
+ { 0.f, 0.f, 1.f },
+ }};
+
+ auto [e_x, e_y, e_z] = rot_x;
+ e_x = e_x.x * rot_y[0] + e_x.y * rot_y[1] + e_x.z * rot_y[2];
+ e_y = e_y.x * rot_y[0] + e_y.y * rot_y[1] + e_y.z * rot_y[2];
+ e_z = e_z.x * rot_y[0] + e_z.y * rot_y[1] + e_z.z * rot_y[2];
+ e_x = e_x.x * rot_z[0] + e_x.y * rot_z[1] + e_x.z * rot_z[2];
+ e_y = e_y.x * rot_z[0] + e_y.y * rot_z[1] + e_y.z * rot_z[2];
+ e_z = e_z.x * rot_z[0] + e_z.y * rot_z[1] + e_z.z * rot_z[2];
+
+ std::array<Object3D, 2> objs{{
+ {
+ {
+ {
+ rad * (-e_x + -e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + -e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ }
+ },
+ {
+ // face 1
+ { 0, 2, 3 },
+ { 0, 3, 1 },
+
+ // face 2
+ { 0, 4, 6 },
+ { 0, 6, 2 },
+
+ // face 3
+ { 0, 1, 5 },
+ { 0, 5, 4 },
+
+ // face 4
+ { 7, 6, 4 },
+ { 7, 4, 5 },
+
+ // face 5
+ { 7, 3, 2 },
+ { 7, 2, 6 },
+
+ // face 6
+ { 7, 5, 1 },
+ { 7, 1, 3 },
+ }
+ },
+ {
+ {
+ {
+ rad * (-e_x + -e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + -e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ }
+ },
+ {
+ // face 1
+ { 0, 2, 3 },
+ { 0, 3, 1 },
+
+ // face 2
+ { 0, 4, 6 },
+ { 0, 6, 2 },
+
+ // face 3
+ { 0, 1, 5 },
+ { 0, 5, 4 },
+
+ // face 4
+ { 7, 6, 4 },
+ { 7, 4, 5 },
+
+ // face 5
+ { 7, 3, 2 },
+ { 7, 2, 6 },
+
+ // face 6
+ { 7, 5, 1 },
+ { 7, 1, 3 },
+ }
+ }
+ }};
+ cfb.clear();
+ float min_z = 2.f, max_z = 50.f;
+ float fac_for_aspect_ratio = 2.f * static_cast<float>(cfb.height()) / static_cast<float>(cfb.width());
+ for (auto obj : objs) {
+ for (auto triangle : obj) {
+ TriangleVertex4 t{triangle};
+
+ // should be multiplied by a matrix, temporary replacement
+ t.vertex1.point.x *= fac_for_aspect_ratio;
+ t.vertex1.point.y = -t.vertex1.point.y;
+ t.vertex1.point.w = -t.vertex1.point.z;
+ t.vertex1.point.z = 2.f * (-t.vertex1.point.z - min_z) / (max_z - min_z) - 1.f;
+ t.vertex2.point.x *= fac_for_aspect_ratio;
+ t.vertex2.point.y = -t.vertex2.point.y;
+ t.vertex2.point.w = -t.vertex2.point.z;
+ t.vertex2.point.z = 2.f * (-t.vertex2.point.z - min_z) / (max_z - min_z) - 1.f;
+ t.vertex3.point.x *= fac_for_aspect_ratio;
+ t.vertex3.point.y = -t.vertex3.point.y;
+ t.vertex3.point.w = -t.vertex3.point.z;
+ t.vertex3.point.z = 2.f * (-t.vertex3.point.z - min_z) / (max_z - min_z) - 1.f;
+
+ cfb.draw_triangle(t);
+ }
+ }
+ mvaddnstr(0, 0, cfb.chars(), cfb.width() * cfb.height());
+ }
+
+ // terminate
+ endwin();
+}
+#endif
+
+#define SCREEN_WIDTH 640
+#define SCREEN_HEIGHT 480
+
+void main_SDL() {
+ SDL_Window* window = NULL;
+ SDL_Renderer* renderer = NULL;
+ SDL_Texture* texture = NULL;
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ fprintf(stderr, "Error: SDL_Init error: %s\n", SDL_GetError());
+ return;
+ }
+ window = SDL_CreateWindow("Engine", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
+ if (window == NULL) {
+ fprintf(stderr, "Error: SDL_CreateWindow error: %s\n", SDL_GetError());
+ return;
+ }
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
+ texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
+ PixelFrameBuffer pfb{SCREEN_WIDTH, SCREEN_HEIGHT};
+
+ MathVector3 a{0.f, 0.f, 0.f};
+ float dist = 4.f;
+ SDL_Event e;
+ bool quit = false;
+ while (!quit) {
+ a.x += .0050f;
+ a.y += .0065f;
+ a.z += .0080f;
+
+ float rad = 5.f;
+ MathVector3 ca{std::cos(a.x), std::cos(a.y), std::cos(a.z)};
+ MathVector3 sa{std::sin(a.x), std::sin(a.y), std::sin(a.z)};
+
+ std::array<MathVector3, 3> rot_x = {{
+ { 1.f, 0.f, 0.f },
+ { 0.f, ca.x, sa.x },
+ { 0.f, -sa.x, ca.x },
+ }};
+ std::array<MathVector3, 3> rot_y = {{
+ { ca.y, 0.f, -sa.y },
+ { 0.f, 1.f, 0.f },
+ { sa.y, 0.f, ca.y },
+ }};
+ std::array<MathVector3, 3> rot_z = {{
+ { ca.z, sa.z, 0.f },
+ { -sa.z, ca.z, 0.f },
+ { 0.f, 0.f, 1.f },
+ }};
+
+ auto [e_x, e_y, e_z] = rot_x;
+ e_x = e_x.x * rot_y[0] + e_x.y * rot_y[1] + e_x.z * rot_y[2];
+ e_y = e_y.x * rot_y[0] + e_y.y * rot_y[1] + e_y.z * rot_y[2];
+ e_z = e_z.x * rot_y[0] + e_z.y * rot_y[1] + e_z.z * rot_y[2];
+ e_x = e_x.x * rot_z[0] + e_x.y * rot_z[1] + e_x.z * rot_z[2];
+ e_y = e_y.x * rot_z[0] + e_y.y * rot_z[1] + e_y.z * rot_z[2];
+ e_z = e_z.x * rot_z[0] + e_z.y * rot_z[1] + e_z.z * rot_z[2];
+
+ std::array<Object3D, 2> objs{{
+ {
+ {
+ {
+ rad * (-e_x + -e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + -e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + -e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + +e_z - .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ }
+ },
+ {
+ // face 1
+ { 0, 2, 3 },
+ { 0, 3, 1 },
+
+ // face 2
+ { 0, 4, 6 },
+ { 0, 6, 2 },
+
+ // face 3
+ { 0, 1, 5 },
+ { 0, 5, 4 },
+
+ // face 4
+ { 7, 6, 4 },
+ { 7, 4, 5 },
+
+ // face 5
+ { 7, 3, 2 },
+ { 7, 2, 6 },
+
+ // face 6
+ { 7, 5, 1 },
+ { 7, 1, 3 },
+ }
+ },
+ {
+ {
+ {
+ rad * (-e_x + -e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + -e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + -e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + -e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (-e_x + +e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ },
+ {
+ rad * (+e_x + +e_y + +e_z + .5f * (e_x + e_y + e_z)) - dist * rad * MathVector3{0.f, 0.f, 1.f},
+ {}
+ }
+ },
+ {
+ // face 1
+ { 0, 2, 3 },
+ { 0, 3, 1 },
+
+ // face 2
+ { 0, 4, 6 },
+ { 0, 6, 2 },
+
+ // face 3
+ { 0, 1, 5 },
+ { 0, 5, 4 },
+
+ // face 4
+ { 7, 6, 4 },
+ { 7, 4, 5 },
+
+ // face 5
+ { 7, 3, 2 },
+ { 7, 2, 6 },
+
+ // face 6
+ { 7, 5, 1 },
+ { 7, 1, 3 },
+ }
+ }
+ }};
+ pfb.clear();
+ float min_z = 2.f, max_z = 50.f;
+ float fac_for_aspect_ratio = 2.f * static_cast<float>(pfb.height()) / static_cast<float>(pfb.width());
+ for (auto obj : objs) {
+ for (auto triangle : obj) {
+ TriangleVertex4 t{triangle};
+
+ // should be multiplied by a matrix, temporary replacement
+ t.vertex1.point.x *= fac_for_aspect_ratio;
+ t.vertex1.point.y = -t.vertex1.point.y;
+ t.vertex1.point.w = -t.vertex1.point.z;
+ t.vertex1.point.z = 2.f * (-t.vertex1.point.z - min_z) / (max_z - min_z) - 1.f;
+ t.vertex2.point.x *= fac_for_aspect_ratio;
+ t.vertex2.point.y = -t.vertex2.point.y;
+ t.vertex2.point.w = -t.vertex2.point.z;
+ t.vertex2.point.z = 2.f * (-t.vertex2.point.z - min_z) / (max_z - min_z) - 1.f;
+ t.vertex3.point.x *= fac_for_aspect_ratio;
+ t.vertex3.point.y = -t.vertex3.point.y;
+ t.vertex3.point.w = -t.vertex3.point.z;
+ t.vertex3.point.z = 2.f * (-t.vertex3.point.z - min_z) / (max_z - min_z) - 1.f;
+
+ pfb.draw_triangle(t);
+ }
+ }
+ SDL_UpdateTexture(texture, NULL, pfb.pixels(), SCREEN_WIDTH * 4);
+ SDL_RenderClear(renderer);
+ SDL_RenderCopy(renderer, texture, NULL, NULL);
+ SDL_RenderPresent(renderer);
+ SDL_UpdateWindowSurface(window);
+ while (SDL_WaitEventTimeout(&e, 10)) {
+ if (e.type == SDL_QUIT) {
+ quit = true;
+ }
+ }
+ }
+ SDL_DestroyTexture(texture);
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+}
+
+#ifdef __WINDOWS__
+int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
+ (void) hInstance;
+ (void) hPrevInstance;
+ (void) pCmdLine;
+ (void) nCmdShow;
+#else
+int main(int argc, char *argv[]) {
+ (void) argc;
+ (void) argv;
+#endif
+ // main_term();
+ main_SDL();
+ return EXIT_SUCCESS;
+}