diff options
Diffstat (limited to 'src/engine.cpp')
-rw-r--r-- | src/engine.cpp | 115 |
1 files changed, 65 insertions, 50 deletions
diff --git a/src/engine.cpp b/src/engine.cpp index e8cde92..c484b0d 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -13,6 +13,7 @@ #include <memory> #include <utility> #include <SDL.h> +#include <numbers> #ifdef ENABLE_NCURSES #include <ncurses.h> @@ -28,7 +29,22 @@ #include "o3d/camera.h" #include "math/vector.h" #include "math/mat4.h" +#include "math/quat.h" +#include "math/tform.h" #include "renderer.h" +#include "obj_parser.h" + +using + engine::Renderer, + engine::fb::CharacterFrameBuffer, + engine::fb::PixelFrameBuffer, + engine::o3d::Scene, + engine::o3d::Mesh, + engine::o3d::Triangle, + engine::math::Vector3, + engine::math::Vector4, + engine::math::Matrix4, + engine::math::Quaternion; #define FPS 60 @@ -52,49 +68,55 @@ static void usage_error_exit() { std::exit(EXIT_FAILURE); } -static void scene_main(engine::Renderer& renderer, engine::math::Matrix4 final_transform_mat, std::function<bool()> update_frame) { +extern Quaternion camera_quat; +Quaternion camera_quat = Quaternion::one(); + +template<typename FrameBuffer, typename UpdateFrameFn> +static void scene_main(Renderer<FrameBuffer>& renderer, const Matrix4& final_transform_mat, UpdateFrameFn update_frame) { float dist = 1.5f; float rad = 5.f; bool cont = true; - engine::o3d::Scene scene{ - {{0.f, 0.f, rad * dist}, 0.f, 0.f, 0.f}, // camera - { // objects - engine::o3d::Object3D{ - engine::o3d::Mesh::plane(), - -rad * engine::math::Vector3(.5f, .5f, .5f), - rad, 0.f, 0.f, 0.f + Scene scene{ + {{{0.f, 0.f, rad * dist}, {1.f, 0.f, 0.f, 0.f}, {1.f, 1.f, 1.f}}}, + { + // { + // Mesh::plane(), + // { + // Vector3(0.f, 0.f, 0.f), + // {1.f, 0.f, 0.f, 0.f}, + // Vector3(rad, rad, rad), + // } + // }, + { + engine::parse_object("../assets/suzanne.obj"), + { + Vector3(0.f, 0.f, 0.f), + {1.f, 0.f, 0.f, 0.f}, + Vector3(rad, rad, rad), + } }, } }; - auto scale_mat = engine::math::Matrix4::scale(rad); + float mul_angle = 0.f; while (cont) { - scene.camera.rot_x += .0050f; - scene.camera.rot_y += .0065f; - scene.camera.rot_z += .0080f; + camera_quat = Quaternion::euler_zyx(mul_angle * .0050f, mul_angle * .0065f, mul_angle * .0080f); + mul_angle += 1.f; + scene.camera.transform.rot = camera_quat; renderer.clear(); - auto transform_mat = - engine::math::Matrix4::translate(-scene.camera.loc) - * engine::math::Matrix4::rot_x(-scene.camera.rot_x) - * engine::math::Matrix4::rot_y(-scene.camera.rot_y) - * engine::math::Matrix4::rot_z(-scene.camera.rot_z); - std::array<engine::math::Matrix4, 1> mats{{ - transform_mat * scale_mat, - }}; auto pre_final_mat = final_transform_mat - * engine::math::Matrix4::projection(static_cast<float>(renderer.height()) / static_cast<float>(renderer.width()), 2.f, 50.f); - for (int i = 0; i < 1; i++) { - auto final_mat = pre_final_mat * mats[i]; - const auto& mesh = scene.objs[i].mesh; - std::vector<engine::math::Vector4> vertices; + * Matrix4::projection(static_cast<float>(renderer.height()) / static_cast<float>(renderer.width()), 2.f, 50.f) + * scene.camera.transform.opposite().to_mat4(); + for (const auto& obj : scene.objs) { + auto final_mat = pre_final_mat * obj.transform.to_mat4(); + const auto& mesh = obj.mesh; + std::vector<Vector4> vertices; for (const auto& vertex : mesh.vertices) vertices.push_back(final_mat * vertex); - for (auto triangle_indices : mesh.indices) { - renderer.draw_triangle({ - {vertices[triangle_indices[0][0]], mesh.normals[triangle_indices[0][1]], mesh.vertices_data[triangle_indices[0][2]]}, - {vertices[triangle_indices[1][0]], mesh.normals[triangle_indices[1][1]], mesh.vertices_data[triangle_indices[1][2]]}, - {vertices[triangle_indices[2][0]], mesh.normals[triangle_indices[2][1]], mesh.vertices_data[triangle_indices[2][2]]}, - }); + for (const auto& triangle_indices : mesh.indices) { + [&]<std::size_t... j>(std::integer_sequence<std::size_t, j...>) { + renderer.draw_triangle({{vertices[triangle_indices[j][0]], mesh.normals[triangle_indices[j][1]], mesh.vertices_data[triangle_indices[j][2]]}...}); + }(std::make_integer_sequence<std::size_t, 3>()); } } cont = update_frame(); @@ -122,13 +144,10 @@ static int main_term() { int w, h; getmaxyx(stdscr, h, w); - engine::Renderer renderer{ - std::make_unique<engine::fb::CharacterFrameBuffer>(static_cast<unsigned int>(w), static_cast<unsigned int>(h))}; + Renderer<CharacterFrameBuffer> renderer{CharacterFrameBuffer{static_cast<unsigned int>(w), static_cast<unsigned int>(h)}}; - scene_main(renderer, engine::math::Matrix4::scale(engine::math::Vector3(2.f, 1.f, 1.f)), [&]() { - mvaddnstr(0, 0, - static_cast<engine::fb::CharacterFrameBuffer*>(renderer.fb.get())->chars(), - renderer.width() * renderer.height()); + scene_main(renderer, Matrix4::scale(Vector3(2.f, 1.f, 1.f)), [&]() { + mvaddnstr(0, 0, renderer.fb.chars(), renderer.width() * renderer.height()); bool cont = true; //timeout(1000 / FPS); @@ -176,9 +195,9 @@ static int main_term() { #define SCREEN_HEIGHT 480 static int main_graphical() { - SDL_Window* window = NULL; - SDL_Renderer* renderer = NULL; - SDL_Texture* texture = NULL; + SDL_Window* window = nullptr; + SDL_Renderer* renderer = nullptr; + SDL_Texture* texture = nullptr; // init if (SDL_Init(SDL_INIT_VIDEO) < 0) { @@ -186,24 +205,21 @@ static int main_graphical() { return EXIT_FAILURE; } window = SDL_CreateWindow("Engine", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); - if (window == NULL) { + if (window == nullptr) { SDL_Quit(); std::cerr << "Error: SDL_CreateWindow error: " << SDL_GetError() << std::endl; return EXIT_FAILURE; } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); - engine::Renderer engine_renderer{ - std::make_unique<engine::fb::PixelFrameBuffer>(SCREEN_WIDTH, SCREEN_HEIGHT)}; + Renderer<PixelFrameBuffer> engine_renderer{PixelFrameBuffer{SCREEN_WIDTH, SCREEN_HEIGHT}}; SDL_Event e; - scene_main(engine_renderer, engine::math::Matrix4::idty(), [&]() { - SDL_UpdateTexture(texture, NULL, - static_cast<engine::fb::PixelFrameBuffer*>(engine_renderer.fb.get())->pixels(), - SCREEN_WIDTH * 4); + scene_main(engine_renderer, Matrix4::idty(), [&]() { + SDL_UpdateTexture(texture, nullptr, engine_renderer.fb.pixels(), SCREEN_WIDTH * 4); SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderCopy(renderer, texture, nullptr, nullptr); SDL_RenderPresent(renderer); SDL_UpdateWindowSurface(window); bool cont = true; @@ -297,7 +313,6 @@ int main(int argc, char *argv[]) { case MODE_GRAPHICAL: return main_graphical(); default: - ; // unreachable + std::unreachable(); } - return EXIT_SUCCESS; // unreachable } |