From: Daniel Karbach Date: Wed, 4 Mar 2015 17:06:21 +0000 (+0100) Subject: extract shader program from application X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=982b69ce8c393ae18beed5239191b8bc2ee1d5d1;p=blank.git extract shader program from application also switch to directional lighting --- diff --git a/src/app.cpp b/src/app.cpp index 56b12dd..8c40c61 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -24,16 +24,6 @@ Application::Application() , 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) -, light_position_handle(0) -, light_color_handle(0) -, light_power_handle(0) , running(false) , front(false) , back(false) @@ -47,69 +37,6 @@ Application::Application() , remove_id(0) , place_id(1) { GLContext::EnableVSync(); - GLContext::EnableDepthTest(); - GLContext::EnableBackfaceCulling(); - program.LoadShader( - GL_VERTEX_SHADER, - "#version 330 core\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 MV;\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(vtx_position, 1);\n" - "gl_Position = MVP * v;\n" - "vtx_world = (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 = (MV * 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" - "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(); - if (!program.Linked()) { - program.Log(std::cerr); - throw std::runtime_error("link program"); - } GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); @@ -136,14 +63,6 @@ Application::Application() 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); } @@ -293,30 +212,17 @@ void Application::Update(int dt) { void Application::Render() { GLContext::Clear(); - program.Use(); + program.Activate(); - glUniformMatrix4fv(v_handle, 1, GL_FALSE, &cam.View()[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); + program.SetVP(cam.View(), cam.Projection()); 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]); + program.SetM(chunk.Transform()); 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]); + program.SetM(outline_transform); outline.Draw(); } diff --git a/src/app.hpp b/src/app.hpp index 1c3c69d..9534da7 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -36,7 +36,7 @@ private: Window window; GLContext ctx; InitGLEW init_glew; - Program program; + DirectionalLighting program; float move_velocity; float pitch_sensitivity; @@ -49,18 +49,6 @@ private: bool outline_visible; glm::mat4 outline_transform; - glm::vec3 light_position; - glm::vec3 light_color; - float light_power; - - GLuint m_handle; - GLuint v_handle; - GLuint mv_handle; - GLuint mvp_handle; - GLuint light_position_handle; - GLuint light_color_handle; - GLuint light_power_handle; - bool running; bool front, back, left, right, up, down; diff --git a/src/shader.cpp b/src/shader.cpp index c42e6fc..99bdb74 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -1,5 +1,7 @@ #include "shader.hpp" +#include "init.hpp" + #include #include #include @@ -134,4 +136,83 @@ GLint Program::UniformLocation(const GLchar *name) const { return glGetUniformLocation(handle, name); } + +DirectionalLighting::DirectionalLighting() +: program() +, light_direction(1.0f, 3.0f, 2.0f) +, light_color(0.9f, 0.9f, 0.9f) +, vp(1.0f) +, m_handle(0) +, mvp_handle(0) +, light_direction_handle(0) +, light_color_handle(0) { + program.LoadShader( + GL_VERTEX_SHADER, + "#version 330 core\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 MVP;\n" + "out vec3 frag_color;\n" + "out vec3 normal;\n" + "void main() {\n" + "gl_Position = MVP * vec4(vtx_position, 1);\n" + "normal = (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 normal;\n" + "uniform vec3 light_direction;\n" + "uniform vec3 light_color;\n" + "out vec3 color;\n" + "void main() {\n" + "vec3 ambient = vec3(0.1, 0.1, 0.1) * frag_color;\n" + "vec3 n = normalize(normal);\n" + "vec3 l = normalize(light_direction);\n" + "float cos_theta = clamp(dot(n, l), 0, 1);\n" + "color = ambient + frag_color * light_color * cos_theta;\n" + "}\n" + ); + program.Link(); + if (!program.Linked()) { + program.Log(std::cerr); + throw std::runtime_error("link program"); + } + + m_handle = program.UniformLocation("M"); + mvp_handle = program.UniformLocation("MVP"); + light_direction_handle = program.UniformLocation("light_direction"); + light_color_handle = program.UniformLocation("light_color"); +} + + +void DirectionalLighting::Activate() { + GLContext::EnableDepthTest(); + GLContext::EnableBackfaceCulling(); + program.Use(); + + glUniform3f(light_direction_handle, light_direction.x, light_direction.y, light_direction.z); + glUniform3f(light_color_handle, light_color.x, light_color.y, light_color.z); +} + +void DirectionalLighting::SetM(const glm::mat4 &m) { + glm::mat4 mvp(vp * m); + glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]); + glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); +} + +void DirectionalLighting::SetVP(const glm::mat4 &v, const glm::mat4 &p) { + vp = p * v; +} + +void DirectionalLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) { + SetVP(v, p); + SetM(m); +} + } diff --git a/src/shader.hpp b/src/shader.hpp index aefcffe..c97e073 100644 --- a/src/shader.hpp +++ b/src/shader.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace blank { @@ -58,6 +59,33 @@ private: }; + +class DirectionalLighting { + +public: + DirectionalLighting(); + + void Activate(); + + void SetM(const glm::mat4 &m); + void SetVP(const glm::mat4 &v, const glm::mat4 &p); + void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p); + +private: + Program program; + + glm::vec3 light_direction; + glm::vec3 light_color; + + glm::mat4 vp; + + GLuint m_handle; + GLuint mvp_handle; + GLuint light_direction_handle; + GLuint light_color_handle; + +}; + } #endif