X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fapp.cpp;h=21eb85c309830eca5f332d6f5cdd719d1b8da04a;hb=753be639d7d04f9f7415db9fc2721485c531f0a1;hp=ff5a3bef59f1a3081b2a5c93ceae49953670ee03;hpb=ea1ce7b0fb7709ae56977480821ac96a231a0686;p=blank.git diff --git a/src/app.cpp b/src/app.cpp index ff5a3be..21eb85c 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,19 +1,11 @@ #include "app.hpp" +#include "geometry.hpp" + #include #include -namespace { - -constexpr GLfloat vtx_coords[] = { - -1.0f, -1.0f, 0.0f, - 1.0f, -1.0f, 0.0f, - 0.0f, 1.0f, 0.0f, -}; - -} - namespace blank { Application::Application() @@ -24,58 +16,32 @@ Application::Application() , ctx(window.CreateContext()) , init_glew() , program() -, pitch_sensitivity(-0.0025f) -, yaw_sensitivity(-0.001f) , cam() -, model() -, vtx_buf(0) -, mvp_handle(0) -, running(false) { +, hud() +, world() +, outline() +, outline_visible(false) +, outline_transform(1.0f) +, running(false) +, place(false) +, remove(false) +, pick(false) +, remove_id(0) +, place_id(1) { GLContext::EnableVSync(); - program.LoadShader( - GL_VERTEX_SHADER, - "#version 330 core\n" - "layout(location = 0) in vec3 vertexPosition_modelspace;\n" - "uniform mat4 MVP;\n" - "void main() {\n" - "vec4 v = vec4(vertexPosition_modelspace, 1);\n" - "gl_Position = MVP * v;\n" - "}\n" - ); - program.LoadShader( - GL_FRAGMENT_SHADER, - "#version 330 core\n" - "out vec3 color;\n" - "void main() {\n" - "color = vec3(1, 1, 1);\n" - "}\n" - ); - program.Link(); - if (!program.Linked()) { - program.Log(std::cerr); - throw std::runtime_error("link program"); - } GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); - glGenBuffers(1, &vtx_buf); - glBindBuffer(GL_ARRAY_BUFFER, vtx_buf); - glBufferData(GL_ARRAY_BUFFER, sizeof(vtx_coords), vtx_coords, GL_STATIC_DRAW); - - model.Position(glm::vec3(0, 0, -4)); - cam.Position(glm::vec3(0, 0, 4)); + world.Generate(); - mvp_handle = program.UniformLocation("MVP"); + hud.Viewport(960, 600); + hud.Display(*world.BlockTypes()[place_id]); glClearColor(0.0, 0.0, 0.0, 1.0); } -Application::~Application() { - -} - void Application::Run() { running = true; @@ -91,6 +57,7 @@ void Application::Run() { void Application::Loop(int dt) { HandleEvents(); + Update(dt); Render(); } @@ -99,11 +66,24 @@ void Application::HandleEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + world.Controller().HandleKeyboard(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; + } + break; case SDL_MOUSEMOTION: - cam.RotateYaw(event.motion.xrel * yaw_sensitivity); - cam.RotatePitch(event.motion.yrel * pitch_sensitivity); - std::cout << "x: " << event.motion.xrel << ", y: " << event.motion.yrel - << ", pitch: " << cam.Pitch() << ", yaw: " << cam.Yaw() << std::endl; + world.Controller().HandleMouse(event.motion); break; case SDL_QUIT: running = false; @@ -112,6 +92,7 @@ void Application::HandleEvents() { switch (event.window.event) { case SDL_WINDOWEVENT_RESIZED: cam.Viewport(event.window.data1, event.window.data2); + hud.Viewport(event.window.data1, event.window.data2); break; default: break; @@ -123,30 +104,68 @@ void Application::HandleEvents() { } } +void Application::Update(int dt) { + world.Update(dt); + + Ray aim = world.Controller().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); + outline_transform = glm::scale(outline_transform, glm::vec3(1.0001f)); + } 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; + } +} + void Application::Render() { - glClear(GL_COLOR_BUFFER_BIT); - - program.Use(); - - glm::mat4 mvp(cam.MakeMVP(model.Transform())); - glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); - - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, vtx_buf); - glVertexAttribPointer( - 0, // attribute 0 (for shader) - 3, // size - GL_FLOAT, // type - GL_FALSE, // normalized - 0, // stride - nullptr // offset - ); - glDrawArrays( - GL_TRIANGLES, // how - 0, // start - 3 // len - ); - glDisableVertexAttribArray(0); + GLContext::Clear(); + + program.Activate(); + + program.SetProjection(cam.Projection()); + world.Render(program); + + if (outline_visible) { + program.SetM(outline_transform); + outline.Draw(); + } + + hud.Render(program); window.Flip(); }