X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fapp.cpp;h=56b12dda8c58bf5b29a5decefd301f69c0c71c5a;hb=5700ea3c08ea5e4a5c743f0413b65dc8eebfd220;hp=b398e9c20e4e032e7c6b9d59df18a39746e7239a;hpb=ac8765b510707d77cac9620778f40ddf3a4ad2a2;p=blank.git diff --git a/src/app.cpp b/src/app.cpp index b398e9c..56b12dd 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,5 +1,7 @@ #include "app.hpp" +#include "geometry.hpp" + #include #include @@ -17,9 +19,11 @@ Application::Application() , move_velocity(0.003f) , pitch_sensitivity(-0.0025f) , yaw_sensitivity(-0.001f) -, blockType() , cam() -, chunk() +, world() +, outline() +, outline_visible(false) +, outline_transform(1.0f) , light_position(17.0f, 17.0f, 17.0f) , light_color(1.0f, 1.0f, 1.0f) , light_power(250.0f) @@ -36,7 +40,12 @@ Application::Application() , left(false) , right(false) , up(false) -, down(false) { +, down(false) +, place(false) +, remove(false) +, pick(false) +, remove_id(0) +, place_id(1) { GLContext::EnableVSync(); GLContext::EnableDepthTest(); GLContext::EnableBackfaceCulling(); @@ -48,6 +57,7 @@ Application::Application() "layout(location = 2) in vec3 vtx_normal;\n" "uniform mat4 M;\n" "uniform mat4 V;\n" + "uniform mat4 MV;\n" "uniform mat4 MVP;\n" "uniform vec3 light_position;\n" "out vec3 frag_color;\n" @@ -59,11 +69,11 @@ Application::Application() "vec4 v = vec4(vtx_position, 1);\n" "gl_Position = MVP * v;\n" "vtx_world = (M * v).xyz;\n" - "vec3 vtx_camera = (V * M * v).xyz;\n" + "vec3 vtx_camera = (MV * v).xyz;\n" "eye = vec3(0, 0, 0) - vtx_camera;\n" "vec3 light_camera = (V * v).xyz;\n" "light_direction = light_position + eye;\n" - "normal = (V * M * vec4(vtx_normal, 0)).xyz;\n" + "normal = (MV * vec4(vtx_normal, 0)).xyz;\n" "frag_color = vtx_color;\n" "}\n" ); @@ -107,28 +117,24 @@ Application::Application() cam.Position(glm::vec3(0, 4, 4)); - blockType.Add(BlockType(true, glm::vec3(1, 1, 1))); - blockType.Add(BlockType(true, glm::vec3(1, 0, 0))); - blockType.Add(BlockType(true, glm::vec3(0, 1, 0))); - blockType.Add(BlockType(true, glm::vec3(0, 0, 1))); + world.Generate(); - chunk.BlockAt(glm::vec3(0, 0, 0)) = Block(blockType[4]); - chunk.BlockAt(glm::vec3(0, 0, 1)) = Block(blockType[1]); - chunk.BlockAt(glm::vec3(1, 0, 0)) = Block(blockType[2]); - chunk.BlockAt(glm::vec3(1, 0, 1)) = Block(blockType[3]); - chunk.BlockAt(glm::vec3(2, 0, 0)) = Block(blockType[4]); - chunk.BlockAt(glm::vec3(2, 0, 1)) = Block(blockType[1]); - chunk.BlockAt(glm::vec3(3, 0, 0)) = Block(blockType[2]); - chunk.BlockAt(glm::vec3(3, 0, 1)) = Block(blockType[3]); - chunk.BlockAt(glm::vec3(2, 0, 2)) = Block(blockType[4]); - chunk.BlockAt(glm::vec3(2, 0, 3)) = Block(blockType[1]); - chunk.BlockAt(glm::vec3(3, 0, 2)) = Block(blockType[2]); - chunk.BlockAt(glm::vec3(3, 0, 3)) = Block(blockType[3]); - chunk.BlockAt(glm::vec3(1, 1, 0)) = Block(blockType[1]); - chunk.BlockAt(glm::vec3(1, 1, 1)) = Block(blockType[4]); - chunk.BlockAt(glm::vec3(2, 1, 1)) = Block(blockType[3]); - chunk.BlockAt(glm::vec3(2, 2, 1)) = Block(blockType[2]); - chunk.Invalidate(); + outline.vertices = std::vector({ + { 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, + { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, + { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, + { 0.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, + }); + outline.colors.resize(24, { -1, -1, -1 }); + outline.Invalidate(); m_handle = program.UniformLocation("M"); v_handle = program.UniformLocation("V"); @@ -141,10 +147,6 @@ Application::Application() glClearColor(0.0, 0.0, 0.0, 1.0); } -Application::~Application() { - -} - void Application::Run() { running = true; @@ -192,6 +194,18 @@ void Application::HandleEvents() { break; } 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); @@ -234,6 +248,46 @@ void Application::Update(int dt) { 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_transform = glm::translate(chunk->Transform(), pos); + } else { + outline_visible = false; + } + + if (pick) { + if (chunk) { + place_id = chunk->BlockAt(blkid).type->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() { @@ -241,18 +295,30 @@ void Application::Render() { program.Use(); - glm::mat4 m(1.0f); - glm::mat4 mv(cam.View() * m); - glm::mat4 mvp(cam.MakeMVP(m)); - glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]); glUniformMatrix4fv(v_handle, 1, GL_FALSE, &cam.View()[0][0]); - glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]); - glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); glUniform3f(light_position_handle, light_position.x, light_position.y, light_position.z); glUniform3f(light_color_handle, light_color.x, light_color.y, light_color.z); glUniform1f(light_power_handle, light_power); - chunk.Draw(); + for (Chunk &chunk : world.LoadedChunks()) { + glm::mat4 m(chunk.Transform()); + glm::mat4 mv(cam.View() * m); + glm::mat4 mvp(cam.MakeMVP(m)); + glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]); + glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]); + glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); + chunk.Draw(); + } + + if (outline_visible) { + glm::mat4 m(outline_transform); + glm::mat4 mv(cam.View() * outline_transform); + glm::mat4 mvp(cam.MakeMVP(outline_transform)); + glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]); + glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]); + glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); + outline.Draw(); + } window.Flip(); }