X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fapp.cpp;h=57651e3b754370602eca2d92706dd000573df1fb;hb=e53a0e2e711a7d8bd9b0ddacd1360aa14370643f;hp=798355d61e9f6eb054ac640c4cb52af4b57767d9;hpb=41e0223ec090142bf03066f4f5fc1f5005095072;p=blank.git diff --git a/src/app.cpp b/src/app.cpp index 798355d..57651e3 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,57 +1,68 @@ #include "app.hpp" -#include "geometry.hpp" - #include #include namespace blank { -Application::Application() +Application::Application(const Config &config) : init_sdl() , init_img() -, init_gl() +, init_gl(config.doublebuf, config.multisampling) , window() , ctx(window.CreateContext()) , init_glew() -, program() -, move_velocity(0.003f) -, pitch_sensitivity(-0.0025f) -, yaw_sensitivity(-0.001f) +, chunk_prog() +, entity_prog() , cam() -, hud() -, world() -, outline() -, outline_visible(false) -, outline_transform(1.0f) -, running(false) -, front(false) -, back(false) -, left(false) -, right(false) -, up(false) -, down(false) -, place(false) -, remove(false) -, pick(false) -, remove_id(0) -, place_id(1) { - GLContext::EnableVSync(); - - GLuint VertexArrayID; - glGenVertexArrays(1, &VertexArrayID); - glBindVertexArray(VertexArrayID); - - world.Generate(); - - cam.Position(glm::vec3(0, 4, 4)); - hud.Viewport(960, 600); - hud.Display(*world.BlockTypes()[place_id]); +, world(config.world) +, interface(config.interface, world) +, test_controller(MakeTestEntity(world)) +, running(false) { + if (config.vsync) { + GLContext::EnableVSync(); + } glClearColor(0.0, 0.0, 0.0, 1.0); } +Entity &Application::MakeTestEntity(World &world) { + Entity &e = world.AddEntity(); + e.Position({ 0.0f, 0.0f, 0.0f }); + e.SetShape(world.BlockTypes()[1].shape, { 1.0f, 1.0f, 0.0f }); + e.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f })); + return e; +} + + +void Application::RunN(size_t n) { + Uint32 last = SDL_GetTicks(); + for (size_t i = 0; i < n; ++i) { + Uint32 now = SDL_GetTicks(); + int delta = now - last; + Loop(delta); + last = now; + } +} + +void Application::RunT(size_t t) { + Uint32 last = SDL_GetTicks(); + Uint32 finish = last + t; + while (last < finish) { + Uint32 now = SDL_GetTicks(); + int delta = now - last; + Loop(delta); + last = now; + } +} + +void Application::RunS(size_t n, size_t t) { + for (size_t i = 0; i < n; ++i) { + Loop(t); + } +} + void Application::Run() { running = true; @@ -77,56 +88,40 @@ void Application::HandleEvents() { while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: + interface.HandlePress(event.key); + break; case SDL_KEYUP: - switch (event.key.keysym.sym) { - case SDLK_w: - front = event.key.state == SDL_PRESSED; - break; - case SDLK_s: - back = event.key.state == SDL_PRESSED; - break; - case SDLK_a: - left = event.key.state == SDL_PRESSED; - break; - case SDLK_d: - right = event.key.state == SDL_PRESSED; - break; - case SDLK_q: - case SDLK_SPACE: - up = event.key.state == SDL_PRESSED; - break; - case SDLK_e: - case SDLK_LSHIFT: - down = event.key.state == SDL_PRESSED; - break; - } + interface.HandleRelease(event.key); break; case SDL_MOUSEBUTTONDOWN: - if (event.button.button == 1) { - // left - remove = true; - } else if (event.button.button == 2) { - // middle - pick = true; - } else if (event.button.button == 3) { - // right - place = true; - } + interface.HandlePress(event.button); + break; + case SDL_MOUSEBUTTONUP: + interface.HandleRelease(event.button); break; case SDL_MOUSEMOTION: - cam.RotateYaw(event.motion.xrel * yaw_sensitivity); - cam.RotatePitch(event.motion.yrel * pitch_sensitivity); + interface.Handle(event.motion); + break; + case SDL_MOUSEWHEEL: + interface.Handle(event.wheel); break; case SDL_QUIT: running = false; break; case SDL_WINDOWEVENT: switch (event.window.event) { + case SDL_WINDOWEVENT_FOCUS_GAINED: + window.GrabMouse(); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + window.ReleaseMouse(); + break; case SDL_WINDOWEVENT_RESIZED: cam.Viewport(event.window.data1, event.window.data2); - hud.Viewport(event.window.data1, event.window.data2); + interface.Handle(event.window); break; default: + interface.Handle(event.window); break; } break; @@ -137,89 +132,20 @@ void Application::HandleEvents() { } void Application::Update(int dt) { - glm::vec3 vel; - if (right && !left) { - vel.x = move_velocity; - } else if (left && !right) { - vel.x = -move_velocity; - } - if (up && !down) { - vel.y = move_velocity; - } else if (down && !up) { - vel.y = -move_velocity; - } - if (back && !front) { - vel.z = move_velocity; - } else if (front && !back) { - vel.z = -move_velocity; - } - cam.OrientationVelocity(vel); - - cam.Update(dt); - - Ray aim = cam.Aim(); - Chunk *chunk; - int blkid; - float dist; - glm::vec3 normal; - if (world.Intersection(aim, glm::mat4(1.0f), &chunk, &blkid, &dist, &normal)) { - glm::vec3 pos = Chunk::ToCoords(blkid); - outline_visible = true; - outline.Clear(); - chunk->BlockAt(blkid).type->FillOutlineModel(outline); - outline_transform = glm::translate(chunk->Transform(), pos); - } else { - outline_visible = false; - } - - if (pick) { - if (chunk) { - place_id = chunk->BlockAt(blkid).type->id; - hud.Display(*world.BlockTypes()[place_id]); - } - pick = false; - } - if (remove) { - if (chunk) { - chunk->BlockAt(blkid).type = world.BlockTypes()[remove_id]; - chunk->Invalidate(); - } - remove = false; - } - if (place) { - if (chunk) { - Chunk *mod_chunk = chunk; - glm::vec3 next_pos = Chunk::ToCoords(blkid) + normal; - if (!Chunk::InBounds(next_pos)) { - mod_chunk = &world.Next(*chunk, normal); - next_pos -= normal * Chunk::Extent(); - } - mod_chunk->BlockAt(next_pos).type = world.BlockTypes()[place_id]; - mod_chunk->Invalidate(); - } - place = false; - } + interface.Update(dt); + test_controller.Update(dt); + world.Update(dt); } void Application::Render() { GLContext::Clear(); - program.Activate(); - - program.SetLightDirection({ -1.0f, -3.0f, -2.0f }); - program.SetVP(cam.View(), cam.Projection()); + chunk_prog.SetProjection(cam.Projection()); + entity_prog.SetProjection(cam.Projection()); - for (Chunk &chunk : world.LoadedChunks()) { - program.SetM(chunk.Transform()); - chunk.Draw(); - } - - if (outline_visible) { - program.SetM(outline_transform); - outline.Draw(); - } + world.Render(chunk_prog, entity_prog); - hud.Render(program); + interface.Render(entity_prog); window.Flip(); }