X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fapp.cpp;h=c418660ec48d209be4fef8ba2074c3aa1bb192ee;hb=2d8c7c015478a4528c0909f11d43998b1393948d;hp=d54e8df56d1d0e875da4e599cca3ae67ea4b67cb;hpb=b314df303ffedbd6d2e81872908d12fc9712801a;p=blank.git diff --git a/src/app.cpp b/src/app.cpp index d54e8df..c418660 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,49 +1,103 @@ #include "app.hpp" +#include "geometry.hpp" + #include #include -namespace { - -constexpr GLfloat vtx_coords[] = { - -1.0f, -1.0f, -1.0f, - 1.0f, -1.0f, -1.0f, - 0.0f, 1.0f, -1.0f, -}; - -} - namespace blank { Application::Application() : init_sdl() +, init_img() , init_gl() , window() , ctx(window.CreateContext()) , init_glew() , program() -, vtx_buf(0) -, mvp() +, move_velocity(0.003f) +, pitch_sensitivity(-0.0025f) +, yaw_sensitivity(-0.001f) +, blockType() +, cam() +, chunk() +, 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) +, m_handle(0) +, v_handle(0) +, mv_handle(0) , mvp_handle(0) -, running(false) { +, light_position_handle(0) +, light_color_handle(0) +, light_power_handle(0) +, running(false) +, front(false) +, back(false) +, left(false) +, right(false) +, up(false) +, down(false) { GLContext::EnableVSync(); + GLContext::EnableDepthTest(); + GLContext::EnableBackfaceCulling(); program.LoadShader( GL_VERTEX_SHADER, "#version 330 core\n" - "layout(location = 0) in vec3 vertexPosition_modelspace;\n" + "layout(location = 0) in vec3 vtx_position;\n" + "layout(location = 1) in vec3 vtx_color;\n" + "layout(location = 2) in vec3 vtx_normal;\n" + "uniform mat4 M;\n" + "uniform mat4 V;\n" "uniform mat4 MVP;\n" + "uniform vec3 light_position;\n" + "out vec3 frag_color;\n" + "out vec3 vtx_world;\n" + "out vec3 normal;\n" + "out vec3 eye;\n" + "out vec3 light_direction;\n" "void main() {\n" - "vec4 v = vec4(vertexPosition_modelspace, 1);\n" + "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" + "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" + "frag_color = vtx_color;\n" "}\n" ); program.LoadShader( GL_FRAGMENT_SHADER, "#version 330 core\n" + "in vec3 frag_color;\n" + "in vec3 vtx_world;\n" + "in vec3 normal;\n" + "in vec3 eye;\n" + "in vec3 light_direction;\n" + "uniform mat4 MV;\n" + "uniform vec3 light_position;\n" + "uniform vec3 light_color;\n" + "uniform float light_power;\n" "out vec3 color;\n" "void main() {\n" - "color = vec3(1, 1, 1);\n" + "vec3 ambient = vec3(0.1, 0.1, 0.1) * frag_color;\n" + "vec3 specular = vec3(0.3, 0.3, 0.3);\n" + "float distance = length(light_position - vtx_world);\n" + "vec3 n = normalize(normal);\n" + "vec3 l = normalize(light_direction);\n" + "float cos_theta = clamp(dot(n, l), 0, 1);\n" + "vec3 E = normalize(eye);\n" + "vec3 R = reflect(-l, n);\n" + "float cos_alpha = clamp(dot(E, R), 0, 1);\n" + "color = ambient" + " + frag_color * light_color * light_power * cos_theta / (distance * distance)" + " + specular * light_color * light_power * pow(cos_alpha, 5) / (distance * distance);\n" "}\n" ); program.Link(); @@ -56,25 +110,55 @@ Application::Application() 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); + cam.Position(glm::vec3(0, 4, 4)); - glm::mat4 projection = glm::perspective( - 45.0f, // FOV in degrees - 1.0f, // aspect ratio - 0.1f, // near clip - 100.0f // far clip - ); - glm::mat4 view = glm::lookAt( - glm::vec3(0, 0, 0), // observer - glm::vec3(0, 0, -1), // target - glm::vec3(0, 1, 0) // up - ); - glm::mat4 model(1.0f); // identity: no transformation - mvp = projection * view * model; + 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))); + + 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"); + mv_handle = program.UniformLocation("MV"); mvp_handle = program.UniformLocation("MVP"); + light_position_handle = program.UniformLocation("light_position"); + light_color_handle = program.UniformLocation("light_color"); + light_power_handle = program.UniformLocation("light_power"); glClearColor(0.0, 0.0, 0.0, 1.0); } @@ -87,6 +171,7 @@ Application::~Application() { void Application::Run() { running = true; Uint32 last = SDL_GetTicks(); + window.GrabMouse(); while (running) { Uint32 now = SDL_GetTicks(); int delta = now - last; @@ -97,6 +182,7 @@ void Application::Run() { void Application::Loop(int dt) { HandleEvents(); + Update(dt); Render(); } @@ -105,38 +191,109 @@ void Application::HandleEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { + case SDL_KEYDOWN: + 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: + up = event.key.state == SDL_PRESSED; + break; + case SDLK_e: + down = event.key.state == SDL_PRESSED; + break; + } + break; + case SDL_MOUSEMOTION: + cam.RotateYaw(event.motion.xrel * yaw_sensitivity); + cam.RotatePitch(event.motion.yrel * pitch_sensitivity); + break; case SDL_QUIT: running = false; break; + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_RESIZED: + cam.Viewport(event.window.data1, event.window.data2); + break; + default: + break; + } + break; default: break; } } } +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(); + int blkid; + float dist; + if (chunk.Intersection(aim, glm::mat4(1.0f), &blkid, &dist)) { + glm::vec3 pos = Chunk::ToCoords(blkid); + outline_visible = true; + outline_transform = glm::translate(glm::mat4(1.0f), pos); + } else { + outline_visible = false; + } +} + void Application::Render() { - glClear(GL_COLOR_BUFFER_BIT); + GLContext::Clear(); 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); - 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); + chunk.Draw(); + if (outline_visible) { + mv = cam.View() * outline_transform; + 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(); }