#include "game/terrain.h" #include "gfx/window.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const int DISPLAY_WIDTH = 800; static const int DISPLAY_HEIGHT = 600; class Monkey : public WorldObject, public Physical { public: Monkey() : Physical {{0.0, 0.5, 1.0}, "res/monkey3.obj", "res/bricks.jpg"} { } void tick(TickDuration elapsed) override { counter += 0.000625F * elapsed.count(); location.GetRot().y = std::numbers::pi_v + sin(counter); location.GetRot().z = 0.3 * cos(counter * 10); } private: float counter {}; }; class SDL_Application { public: SDL_Application() { SDL_Init(SDL_INIT_EVERYTHING); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); } ~SDL_Application() { SDL_Quit(); } NO_COPY(SDL_Application); NO_MOVE(SDL_Application); void run() { Collection windows; windows.create(DISPLAY_WIDTH, DISPLAY_HEIGHT, "OpenGL"); Worker w; World world; world.create(); world.create(); Shader shader; Camera camera({-1250.0F, 35.0F, -1250.0F}, 70.0F, (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT, 0.1F, 10000.0F); camera.Pitch(0.24); camera.RotateY(0.7854); shader.Bind(); shader.setView(camera.GetViewProjection()); SDL_Event e; bool isRunning = true; auto t_start = std::chrono::high_resolution_clock::now(); const auto framelen = std::chrono::milliseconds {1000} / 120; bool mrb {false}, ctrl {false}; while (isRunning) { while (SDL_PollEvent(&e)) { switch (e.type) { case SDL_QUIT: isRunning = false; break; case SDL_KEYDOWN: switch (e.key.keysym.sym) { case SDLK_KP_8: camera.MoveForward(1); break; case SDLK_KP_2: camera.MoveForward(-1); break; case SDLK_KP_4: camera.MoveRight(1); break; case SDLK_KP_6: camera.MoveRight(-1); break; case SDLK_KP_7: camera.RotateY(0.04); break; case SDLK_KP_9: camera.RotateY(-0.04); break; case SDLK_LCTRL: case SDLK_RCTRL: ctrl = true; break; } shader.setView(camera.GetViewProjection()); break; case SDL_KEYUP: switch (e.key.keysym.sym) { case SDLK_LCTRL: case SDLK_RCTRL: ctrl = false; break; } break; case SDL_MOUSEBUTTONDOWN: switch (e.button.button) { case SDL_BUTTON_RIGHT: SDL_SetRelativeMouseMode(SDL_TRUE); mrb = true; break; } break; case SDL_MOUSEBUTTONUP: switch (e.button.button) { case SDL_BUTTON_RIGHT: SDL_SetRelativeMouseMode(SDL_FALSE); mrb = false; break; } break; case SDL_MOUSEMOTION: if (mrb) { if (ctrl) { camera.RotateY(-0.01F * e.motion.xrel); camera.Pitch(-0.01F * e.motion.yrel); } else { camera.MoveRight(e.motion.xrel); camera.SlideForward(e.motion.yrel); } shader.setView(camera.GetViewProjection()); } break; } } const auto t_end = std::chrono::high_resolution_clock::now(); const auto t_passed = std::chrono::duration_cast(t_end - t_start); world.apply(&WorldObject::tick, t_passed); windows.apply(&Window::Clear, 0.0F, 0.0F, 0.0F, 1.0F); world.apply(&Renderable::render, shader); windows.apply(&Window::SwapBuffers); if (const auto snz = framelen - t_passed; snz.count() > 0) { SDL_Delay(snz.count()); } t_start = t_end; } } }; int main(int, char **) { SDL_Application().run(); return 0; }