From cf024f4f72cdc4ea5f2dcf040c4a117feffc64e4 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sun, 11 Mar 2018 11:58:50 +0100 Subject: [PATCH] Diffuse and ambient lighting implemented --- data/shaders/fs_default.glsl | 22 ++++++++++++++++ data/shaders/vs_default.glsl | 19 ++++++++++++++ src/modules/RenderModule.cc | 51 ++++++++++++++++++------------------ src/modules/RenderModule.h | 11 +++++--- src/modules/RenderUtils.cc | 39 ++++++++++++++++----------- src/modules/RenderUtils.h | 21 +++++++++++++++ 6 files changed, 118 insertions(+), 45 deletions(-) create mode 100644 data/shaders/fs_default.glsl create mode 100644 data/shaders/vs_default.glsl diff --git a/data/shaders/fs_default.glsl b/data/shaders/fs_default.glsl new file mode 100644 index 0000000..c512d00 --- /dev/null +++ b/data/shaders/fs_default.glsl @@ -0,0 +1,22 @@ +#version 150 core + +uniform vec4 uColor; +uniform vec3 uLightDirection; + +smooth in vec4 ioFragColor; +in vec3 ioNormal; + +out vec4 outColor; + +void main() { + float ambient_strength = 0.1; + + vec4 ambient = ambient_strength * ioFragColor; + + vec3 norm = normalize(ioNormal); + vec3 light_dir = normalize(uLightDirection); + float diff = max(dot(norm, light_dir), 0.0); + vec4 diffuse = diff * ioFragColor; + + outColor = ambient + diffuse; +} diff --git a/data/shaders/vs_default.glsl b/data/shaders/vs_default.glsl new file mode 100644 index 0000000..179efcc --- /dev/null +++ b/data/shaders/vs_default.glsl @@ -0,0 +1,19 @@ +#version 150 core +#extension GL_ARB_explicit_attrib_location : require + +in vec4 inCoord; +in vec3 inNormal; +in vec2 inUV; +in vec4 inColor; + +uniform mat4 uModelViewProj; +uniform vec3 uLightDirection; + +smooth out vec4 ioFragColor; +out vec3 ioNormal; + +void main() { + gl_Position = uModelViewProj * inCoord; + ioFragColor = inColor; + ioNormal = inNormal; +} diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index d7a6bb2..878f4d7 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -85,6 +85,7 @@ static void module_serialize ( SerializeVec3(*serializer, "protot.RenderModule.Camera.mUp", gRenderer->mCamera.mUp); SerializeFloat(*serializer, "protot.RenderModule.Camera.mNear", gRenderer->mCamera.mNear); SerializeFloat(*serializer, "protot.RenderModule.Camera.mFar", gRenderer->mCamera.mFar); + SerializeVec3(*serializer, "protot.RenderModule.mLight.mDirection", gRenderer->mLight.mDirection); // SerializeBool (*serializer, "protot.RenderModule.draw_floor", gRenderer->drawFloor); // SerializeBool (*serializer, "protot.RenderModule.draw_skybox", gRenderer->drawSkybox); @@ -310,12 +311,15 @@ void Renderer::Initialize(int width, int height) { glBufferData(GL_ARRAY_BUFFER, sizeof(g_coordinate_system_vertex_buffer_data), g_coordinate_system_vertex_buffer_data, GL_STATIC_DRAW); // Simple Shader - mDefaultProgram = RenderProgram("data/shaders/vs_simple.glsl", "data/shaders/fs_simple.glsl"); - bool load_result = mDefaultProgram.Load(); + mSimpleProgram = RenderProgram("data/shaders/vs_simple.glsl", "data/shaders/fs_simple.glsl"); + bool load_result = mSimpleProgram.Load(); + mSimpleProgram.RegisterFileModification(); + assert(load_result); + + mDefaultProgram = RenderProgram("data/shaders/vs_default.glsl", "data/shaders/fs_default.glsl"); + load_result = mDefaultProgram.Load(); mDefaultProgram.RegisterFileModification(); assert(load_result); - muDefaultModelViewProjection = mDefaultProgram.GetUniformLocation("uModelViewProj"); - muDefaultColor = mDefaultProgram.GetUniformLocation("uColor"); // Render Target mRenderTarget = RenderTarget (width, height, @@ -398,9 +402,9 @@ void Renderer::RenderGl() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); - glUseProgram(mDefaultProgram.mProgramId); - glUniformMatrix4fv(muDefaultModelViewProjection, 1, GL_FALSE, model_view_projection.data()); - glUniform4fv(muDefaultColor, 1, Vector4f(1.0f, 0.0f, 0.0f, 1.0f).data()); + glUseProgram(mSimpleProgram.mProgramId); + mSimpleProgram.SetMat44("uModelViewProj", model_view_projection); + mSimpleProgram.SetVec4("uColor", Vector4f (1.0f, 0.0f, 0.0f, 1.0f)); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, mMesh.mVertexBuffer); @@ -413,11 +417,10 @@ void Renderer::RenderGl() { (void*)0 // offset ); -// glDrawArrays(GL_TRIANGLES, 0, 3); // starting from vertex 0; 3 vertices total -// // Coordinate system + // Coordinate system glEnableVertexAttribArray(0); glBindVertexArray(mCoordinateSystem.mVertexArrayId); - glUniform4fv(muDefaultColor, 1, Vector4f(0.0f, 0.0f, 0.0f, 1.0f).data()); + mSimpleProgram.SetVec4("uColor", Vector4f (0.0f, 0.0f, 0.0f, 1.0f)); glBindBuffer(GL_ARRAY_BUFFER, mCoordinateSystem.mVertexBuffer); glVertexAttribPointer( 0, @@ -444,8 +447,8 @@ void Renderer::RenderGl() { TranslateMat44(0.0f, 0.0f, 0.0f) * mCamera.mViewMatrix * mCamera.mProjectionMatrix; - glUniformMatrix4fv(muDefaultModelViewProjection, 1, GL_FALSE, model_view_projection.data()); - glUniform4fv(muDefaultColor, 1, Vector4f(1.0f, 0.0f, 0.0f, 1.0f).data()); + mSimpleProgram.SetMat44("uModelViewProj", model_view_projection); + mSimpleProgram.SetVec4("uColor", Vector4f (0.0f, 0.0f, 0.0f, 1.0f)); gVertexArray.Bind(); gVertexArrayMesh.Draw(GL_LINES); @@ -454,25 +457,21 @@ void Renderer::RenderGl() { TranslateMat44(0.0f, 0.0f, 0.0f) * mCamera.mViewMatrix * mCamera.mProjectionMatrix; - glUniformMatrix4fv(muDefaultModelViewProjection, 1, GL_FALSE, model_view_projection.data()); - glUniform4fv(muDefaultColor, 1, Vector4f(1.0f, 0.0f, 0.0f, 1.0f).data()); - glBindAttribLocation(mDefaultProgram.mProgramId, 0, "inCoord"); - glBindAttribLocation(mDefaultProgram.mProgramId, 1, "inNormal"); - glBindAttribLocation(mDefaultProgram.mProgramId, 2, "inUV"); - glBindAttribLocation(mDefaultProgram.mProgramId, 3, "inColor"); + mSimpleProgram.SetMat44("uModelViewProj", model_view_projection); + mSimpleProgram.SetVec4("uColor", Vector4f (1.0f, 0.0f, 0.0f, 1.0f)); gVertexArray.Bind(); gXZPlaneMesh.Draw(GL_LINES); + // Unit cube + glUseProgram(mDefaultProgram.mProgramId); + model_view_projection = TranslateMat44(3.0f, 0.0f, 1.0f) * mCamera.mViewMatrix * mCamera.mProjectionMatrix; - glUniformMatrix4fv(muDefaultModelViewProjection, 1, GL_FALSE, model_view_projection.data()); - glUniform4fv(muDefaultColor, 1, Vector4f(1.0f, 0.0f, 0.0f, 1.0f).data()); - glBindAttribLocation(mDefaultProgram.mProgramId, 0, "inCoord"); - glBindAttribLocation(mDefaultProgram.mProgramId, 1, "inNormal"); - glBindAttribLocation(mDefaultProgram.mProgramId, 2, "inUV"); - glBindAttribLocation(mDefaultProgram.mProgramId, 3, "inColor"); + mDefaultProgram.SetMat44("uModelViewProj", model_view_projection); + mDefaultProgram.SetVec4("uColor", Vector4f (1.0f, 0.0f, 0.0f, 1.0f)); + mDefaultProgram.SetVec3("uLightDirection", mLight.mDirection); gVertexArray.Bind(); gUnitCubeMesh.Draw(GL_TRIANGLES); @@ -542,8 +541,8 @@ void Renderer::RenderGui() { ImGui::EndDock(); if (ImGui::BeginDock("Render Settings")) { - ImGui::Text("Render Target"); - ImGui::Text("Width %d, Height %d", mRenderTarget.mWidth, mRenderTarget.mHeight); + ImGui::Text("Light"); + ImGui::SliderFloat3("Direction", mLight.mDirection.data(), -10.0f, 10.0f); ImGui::Text("Camera"); mCamera.DrawGui(); diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index 9be65db..dcae0e3 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -57,8 +57,8 @@ struct Camera { }; struct Light { - Vector3f pos; - Vector3f dir; + Vector3f mPosition; + Vector3f mDirection; float mViewMatrix[16]; float mProjectionMatrix[16]; @@ -74,8 +74,8 @@ struct Light { float area; Light() : - pos (Vector3f(0.f, 10.f, 10.f)), - dir (Vector3f(-1.f, -1.f, -1.f)), + mPosition (Vector3f(0.f, 10.f, 10.f)), + mDirection (Vector3f(-1.f, -1.f, -1.f)), mViewMatrix { 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, @@ -115,6 +115,7 @@ struct Renderer { uint32_t mSceneAreaWidth = 1; uint32_t mSceneAreaHeight = 1; + Light mLight; Camera mCamera; Mesh mMesh; Mesh mPlane; @@ -122,6 +123,8 @@ struct Renderer { Texture mDefaultTexture; + RenderProgram mSimpleProgram; + RenderProgram mDefaultProgram; GLuint muDefaultModelViewProjection; GLuint muDefaultColor; diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 5789e31..47b7a57 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -108,6 +108,13 @@ GLuint RenderProgram::LinkProgram(GLuint vertex_shader, GLuint fragment_shader) GLuint ProgramID = glCreateProgram(); glAttachShader(ProgramID, vertex_shader); glAttachShader(ProgramID, fragment_shader); + + // Bind attribute locations + glBindAttribLocation(ProgramID, 0, "inCoord"); + glBindAttribLocation(ProgramID, 1, "inNormal"); + glBindAttribLocation(ProgramID, 2, "inUV"); + glBindAttribLocation(ProgramID, 3, "inColor"); + glLinkProgram(ProgramID); GLint Result = GL_FALSE; @@ -461,36 +468,36 @@ void VertexArray::Bind() { (sizeof(VertexData)), (void*)0 ); - // Attribute 1: color - glEnableVertexAttribArray(1); - glVertexAttribPointer( - 1, - 4, - GL_UNSIGNED_BYTE, - GL_FALSE, - (sizeof(VertexData)), - (void*)(sizeof(float) * 9) - ); - // Attribute 2: normals + // Attribute 1: normals glEnableVertexAttribArray(2); glVertexAttribPointer( - 2, + 1, 3, GL_FLOAT, GL_FALSE, (sizeof(VertexData)), (void*)(sizeof(float) * 4) ); - // Attribute 3: texture coordinates + // Attribute 2: texture coordinates glEnableVertexAttribArray(3); glVertexAttribPointer( - 3, + 2, 2, GL_FLOAT, GL_FALSE, (sizeof(VertexData)), (void*)(sizeof(float) * 7) ); + // Attribute 1: color + glEnableVertexAttribArray(3); + glVertexAttribPointer( + 3, + 4, + GL_UNSIGNED_BYTE, + GL_TRUE, + (sizeof(VertexData)), + (void*)(sizeof(float) * 9) + ); } bool VertexArray::IsBound() { @@ -561,7 +568,9 @@ void VertexArrayMesh::SetData( } if (have_colors) { - memcpy (vertex_data[i].mColor, colors[i].data(), sizeof(float) * 4); + for (int j = 0; j < 4; ++j) { + vertex_data[i].mColor[j] = GLubyte(colors[i][j] * 255.0f); + } } else { memset (vertex_data[i].mColor, 0, sizeof(float) * 4); } diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index 25cfdf4..255db66 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -153,6 +153,27 @@ struct RenderProgram : AFileModificationListener { GLuint CompileFragmentShader(); GLuint LinkProgram(GLuint vertex_shader, GLuint fragment_shader); + void SetVec3(const char* name, const Vector3f& vec) { + GLint location = glGetUniformLocation(mProgramId, name); + glUniform3fv(location, 1, vec.data()); + } + void SetVec4(const char* name, const Vector3f& vec, float w = 1.0f) { + GLint location = glGetUniformLocation(mProgramId, name); + glUniform4f(location, vec[0], vec[1], vec[2], w); + } + void SetVec4(const char* name, const Vector4f& vec) { + GLint location = glGetUniformLocation(mProgramId, name); + glUniform4fv(location, 1, vec.data()); + } + void SetMat44 (const char* name, const Matrix44f& mat) { + GLint location = glGetUniformLocation(mProgramId, name); + glUniformMatrix4fv(location, 1, GL_FALSE, mat.data()); + } + void SetMat33 (const char* name, const Matrix33f& mat) { + GLint location = glGetUniformLocation(mProgramId, name); + glUniformMatrix3fv(location, 1, GL_FALSE, mat.data()); + } + void RegisterFileModification(); virtual bool OnFileChanged(const std::string& filename); };