diff options
Diffstat (limited to 'src/engine.cpp')
-rw-r--r-- | src/engine.cpp | 217 |
1 files changed, 54 insertions, 163 deletions
diff --git a/src/engine.cpp b/src/engine.cpp index 4740046..69b2f43 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -9,6 +9,7 @@ #include <vector> #include <functional> #include <utility> +#include <iterator> #include <SDL.h> #ifdef ENABLE_NCURSES @@ -49,158 +50,30 @@ template <class FB> void scene_main(FB& fb, std::function<bool()> update_frame) { MathVector3 a{0.f, 0.f, 0.f}; float dist = 4.f; + float rad = 5.f; bool cont = true; + std::array<Object3D, 2> objs{{ Object3D::cube(), Object3D::cube() }}; + auto scale_mat = Mat4::scale(rad); while (cont) { a.x += .0050f; a.y += .0065f; a.z += .0080f; - float rad = 5.f; - auto [e4_x, e4_y, e4_z, e4_w] = (Mat4::rot_x(a.x) * Mat4::rot_y(a.y) * Mat4::rot_z(a.z)).to_vecs(); - auto e_x = e4_x.xyz(); - auto e_y = e4_y.xyz(); - auto e_z = e4_z.xyz(); - - 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 }, - } - } - }}; fb.clear(); - float min_z = 2.f, max_z = 50.f; - float fac_for_aspect_ratio = static_cast<float>(fb.height()) / static_cast<float>(fb.width()); - Mat4 mat{{ - fac_for_aspect_ratio, 0.f, 0.f, 0.f, - 0.f, -1.f, 0.f, 0.f, - 0.f, 0.f, -2.f / (max_z - min_z), -(max_z + min_z) / (max_z - min_z), - 0.f, 0.f, -1.f, 0.f, + auto transform_mat = Mat4::translate(MathVector3{0.f, 0.f, -rad * dist}) * Mat4::rot_z(a.z) * Mat4::rot_y(a.y) * Mat4::rot_x(a.x); + std::array<Mat4, 2> mats{{ + transform_mat * Mat4::translate(MathVector3{-.5f * rad, -.5f * rad, -.5f * rad}) * scale_mat, + transform_mat * Mat4::translate(MathVector3{+.5f * rad, +.5f * rad, +.5f * rad}) * scale_mat, }}; - for (auto obj : objs) { - for (auto triangle : obj) { + auto projection_mat = Mat4::projection(static_cast<float>(fb.height()) / static_cast<float>(fb.width()), 2.f, 50.f); + for (int i = 0; i < 2; i++) { + auto final_mat = projection_mat * mats[i]; + for (auto triangle : objs[i]) { TriangleVertex4 t{triangle}; - t.vertex1.point = mat * t.vertex1.point; - t.vertex2.point = mat * t.vertex2.point; - t.vertex3.point = mat * t.vertex3.point; + t.vertex1.point = final_mat * t.vertex1.point; + t.vertex2.point = final_mat * t.vertex2.point; + t.vertex3.point = final_mat * t.vertex3.point; fb.draw_triangle(t); } @@ -285,13 +158,14 @@ int main_graphical() { SDL_Renderer* renderer = NULL; SDL_Texture* texture = NULL; + // init if (SDL_Init(SDL_INIT_VIDEO) < 0) { - fprintf(stderr, "Error: SDL_Init error: %s\n", SDL_GetError()); + std::cerr << "Error: SDL_Init error: " << SDL_GetError() << std::endl; return EXIT_FAILURE; } 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()); + std::cerr << "Error: SDL_CreateWindow error: " << SDL_GetError() << std::endl; return EXIT_FAILURE; } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); @@ -307,14 +181,17 @@ int main_graphical() { SDL_RenderPresent(renderer); SDL_UpdateWindowSurface(window); bool cont = true; - while (SDL_WaitEventTimeout(&e, 10)) { - if (e.type == SDL_QUIT) { - cont = false; - } + if (SDL_WaitEventTimeout(&e, 10)) { + do { + if (e.type == SDL_QUIT) { + cont = false; + } + } while (SDL_PollEvent(&e)); } return cont; }); + // terminate SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); @@ -323,29 +200,38 @@ int main_graphical() { return EXIT_SUCCESS; } -int main(int argc, char *argv[]) { - int mode = MODE_GRAPHICAL; - for (int i = 1; i < argc; i++) { - if (argv[i][0] == '-') { - if (argv[i][1] == '-') { - if (strcmp(&argv[i][2], "help") == 0) { +std::vector<std::string_view> convert_args(int argc, char *argv[]) { + std::vector<std::string_view> args(argc); + for (int i = 0; i < argc; i++) + args[i] = argv[i]; + return args; +} + +void parse_args(const std::vector<std::string_view>& args, int& mode) { + for (auto args_iter = std::next(args.begin()); args_iter != args.end(); args_iter++) { + const auto& arg = *args_iter; + if (arg.size() >= 1 && arg[0] == '-') { + if (arg.size() >= 2 && arg[1] == '-') { + auto long_opt = arg.substr(2); + if (long_opt == "help") { mode = MODE_HELP; - } else if (strcmp(&argv[i][2], "term") == 0) { + } else if (long_opt == "term") { mode = MODE_TERM; - } else if (strcmp(&argv[i][2], "graphical") == 0) { + } else if (long_opt == "graphical") { mode = MODE_GRAPHICAL; } else { - std::cerr << "Error: Unexpected option `--" << &argv[i][2] << "'." << std::endl; + std::cerr << "Error: Unexpected option `--" << long_opt << "'." << std::endl; usage_error_exit(); } } else { - if (!argv[i][1]) { + std::size_t arg_len = arg.size(); + if (arg_len == 1) { std::cerr << "Error: Unexpected argument `-'." << std::endl; usage_error_exit(); } - std::size_t arg_len = strlen(&argv[i][1]); - for (int j = 0; j < arg_len; j++) { - switch (argv[i][1 + j]) { + for (auto arg_iter = std::next(arg.begin()); arg_iter != arg.end(); arg_iter++) { + const auto& opt = *arg_iter; + switch (opt) { case 'h': mode = MODE_HELP; break; @@ -356,16 +242,21 @@ int main(int argc, char *argv[]) { mode = MODE_GRAPHICAL; break; default: - std::cerr << "Error: Unexpected option `-" << argv[i][1] << "'." << std::endl; + std::cerr << "Error: Unexpected option `-" << opt << "'." << std::endl; usage_error_exit(); } } } } else { - std::cerr << "Error: Unexpected argument `" << argv[i] << "'." << std::endl; + std::cerr << "Error: Unexpected argument `" << arg << "'." << std::endl; usage_error_exit(); } } +} + +int main(int argc, char *argv[]) { + int mode = MODE_GRAPHICAL; + parse_args(convert_args(argc, argv), mode); switch (mode) { case MODE_HELP: print_usage(std::cout); |