aboutsummaryrefslogtreecommitdiff
path: root/src/engine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine.cpp')
-rw-r--r--src/engine.cpp217
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);