diff --git a/src/Components/PointLight.h b/src/Components/PointLight.h index 248fec6..9037b89 100755 --- a/src/Components/PointLight.h +++ b/src/Components/PointLight.h @@ -9,13 +9,22 @@ namespace Components struct PointLight : Component { - float Intensity; - float MaxRange; + PointLight() + : Specular(1.0f, 1.0f, 1.0f) + , Diffuse(1.0f, 1.0f, 1.0f) + , specularExponent(50.0f) + , ConstantAttenuation(1.0f) + , LinearAttenuation(0.f) + , QuadraticAttenuation(3.f) + { } + + float ConstantAttenuation, LinearAttenuation, QuadraticAttenuation; + Color color; + glm::vec3 Specular; glm::vec3 Diffuse; - float constantAttenuation, linearAttenuation, quadraticAttenuation; - float spotExponent; - Color color; + float specularExponent; + float Scale; virtual PointLight* Clone() const override { return new PointLight(*this); } }; diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 9e48cf7..151ad43 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -324,13 +324,13 @@ void GameWorld::Initialize() { auto lightentity = CreateEntity(tank); auto transform = AddComponent(lightentity, "Transform"); - transform->Position = glm::vec3(0, 15, 0); + transform->Position = glm::vec3(0, 0, 0); auto light = AddComponent(lightentity, "PointLight"); - light->Diffuse = glm::vec3(128.f/255.f, 172.f/255.f, 242.f/255.f); - light->Specular = glm::vec3(1.f); - light->constantAttenuation = 0.3f; - light->linearAttenuation = 0.003f; - light->quadraticAttenuation = 0.002f; + //light->Diffuse = glm::vec3(128.f/255.f, 172.f/255.f, 242.f/255.f); + //light->Specular = glm::vec3(1.f); + /*light->ConstantAttenuation = 0.3f; + light->LinearAttenuation = 0.003f; + light->QuadraticAttenuation = 0.002f;*/ } // auto wheelpair = CreateEntity(tank); @@ -524,7 +524,7 @@ void GameWorld::Initialize() } CommitEntity(wheel); - /*auto entity = CreateEntity(tank); + auto entity = CreateEntity(tank); auto transformComponent = AddComponent(entity, "Transform"); transformComponent->Position = glm::vec3(2,-1.7,2.0); transformComponent->Scale = glm::vec3(3,3,3); @@ -546,7 +546,7 @@ void GameWorld::Initialize() spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; emitterComponent->ParticleTemplate = particleEntity; - CommitEntity(particleEntity);*/ + CommitEntity(particleEntity); } { @@ -608,37 +608,37 @@ void GameWorld::Initialize() } CommitEntity(wheel); - //auto entity = CreateEntity(tank); - //auto transformComponent = AddComponent(entity, "Transform"); - //transformComponent->Position = glm::vec3(-2,-1.7,2.0); - //transformComponent->Scale = glm::vec3(3,3,3); - //transformComponent->Orientation = glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)); - //auto emitterComponent = AddComponent(entity, "ParticleEmitter"); - //emitterComponent->SpawnCount = 2; - //emitterComponent->SpawnFrequency = 0.005; - //emitterComponent->SpreadAngle = glm::pi(); - //emitterComponent->UseGoalVelocity = false; - //emitterComponent->LifeTime = 0.5; - ////emitterComponent->AngularVelocitySpectrum.push_back(glm::pi() / 100); - //emitterComponent->ScaleSpectrum.push_back(glm::vec3(0.05)); - //CommitEntity(entity); + auto entity = CreateEntity(tank); + auto transformComponent = AddComponent(entity, "Transform"); + transformComponent->Position = glm::vec3(-2,-1.7,2.0); + transformComponent->Scale = glm::vec3(3,3,3); + transformComponent->Orientation = glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)); + auto emitterComponent = AddComponent(entity, "ParticleEmitter"); + emitterComponent->SpawnCount = 2; + emitterComponent->SpawnFrequency = 0.005; + emitterComponent->SpreadAngle = glm::pi(); + emitterComponent->UseGoalVelocity = false; + emitterComponent->LifeTime = 0.5; + //emitterComponent->AngularVelocitySpectrum.push_back(glm::pi() / 100); + emitterComponent->ScaleSpectrum.push_back(glm::vec3(0.05)); + CommitEntity(entity); - //auto particleEntity = CreateEntity(entity); - //auto TEMP = AddComponent(particleEntity, "Transform"); - //TEMP->Scale = glm::vec3(0); - //auto spriteComponent = AddComponent(particleEntity, "Sprite"); - //spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; - //emitterComponent->ParticleTemplate = particleEntity; + auto particleEntity = CreateEntity(entity); + auto TEMP = AddComponent(particleEntity, "Transform"); + TEMP->Scale = glm::vec3(0); + auto spriteComponent = AddComponent(particleEntity, "Sprite"); + spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; + emitterComponent->ParticleTemplate = particleEntity; - //CommitEntity(particleEntity); + CommitEntity(particleEntity); } CommitEntity(tank); { auto camera = CreateEntity(tank); auto transform = AddComponent(camera, "Transform"); - transform->Position.z = 20.f; - transform->Position.y = 7.f; + transform->Position.z = 30.f; + transform->Position.y = 5.f; //transform->Orientation = glm::quat(glm::vec3(-glm::pi() / 8.f, 0.f, 0.f)); transform->Orientation = glm::angleAxis(glm::pi() / 100, glm::vec3(1,0,0)); auto cameraComp = AddComponent(camera, "Camera"); diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 2905891..3498e93 100755 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -13,12 +13,15 @@ Renderer::Renderer() m_DrawWireframe = false; m_DrawBounds = false; #endif - - m_ShadowMapRes = 2048; + Gamma = 2.2f; + CAtt = 1.0f; + LAtt = 0.0f; + QAtt = 3.0f; + m_ShadowMapRes = 2048*8; m_SunPosition = glm::vec3(0, 3.5f, 10); m_SunTarget = glm::vec3(0, 0, 0); - m_SunProjection = glm::ortho(-100, 100, -100, 100, -100, 100); - Lights = 0; + m_SunProjection = glm::ortho(-200.f, 200.f, -200.f, 200.f, -100, 200); +/* Lights = 0;*/ } void Renderer::Initialize() @@ -76,7 +79,7 @@ void Renderer::Initialize() void Renderer::LoadContent() { - auto standardVS = std::shared_ptr(new VertexShader("Shaders/Vertex.glsl")); + /*auto standardVS = std::shared_ptr(new VertexShader("Shaders/Vertex.glsl")); auto standardFS = std::shared_ptr(new FragmentShader("Shaders/Fragment.glsl")); m_ShaderProgram.AddShader(standardVS); @@ -89,12 +92,7 @@ void Renderer::LoadContent() m_ShaderProgramNormals.AddShader(std::shared_ptr(new FragmentShader("Shaders/Normals.frag.glsl"))); m_ShaderProgramNormals.Compile(); m_ShaderProgramNormals.Link(); - - m_ShaderProgramShadows.AddShader(std::shared_ptr(new VertexShader("Shaders/ShadowMap.vert.glsl"))); - m_ShaderProgramShadows.AddShader(std::shared_ptr(new FragmentShader("Shaders/ShadowMap.frag.glsl"))); - m_ShaderProgramShadows.Compile(); - m_ShaderProgramShadows.Link(); - + m_ShaderProgramShadowsDrawDepth.AddShader(std::shared_ptr(new VertexShader("Shaders/VisualizeDepth.vert.glsl"))); m_ShaderProgramShadowsDrawDepth.AddShader(std::shared_ptr(new FragmentShader("Shaders/VisualizeDepth.frag.glsl"))); m_ShaderProgramShadowsDrawDepth.Compile(); @@ -108,13 +106,124 @@ void Renderer::LoadContent() m_ShaderProgramSkybox.AddShader(std::shared_ptr(new VertexShader("Shaders/Skybox.vert.glsl"))); m_ShaderProgramSkybox.AddShader(std::shared_ptr(new FragmentShader("Shaders/Skybox.frag.glsl"))); m_ShaderProgramSkybox.Compile(); - m_ShaderProgramSkybox.Link(); + m_ShaderProgramSkybox.Link();*/ - m_Skybox = std::make_shared("Textures/Skybox/Sunset", "jpg"); + m_ShaderProgramShadows.AddShader(std::shared_ptr(new VertexShader("Shaders/ShadowMap.vert.glsl"))); + m_ShaderProgramShadows.AddShader(std::shared_ptr(new FragmentShader("Shaders/ShadowMap.frag.glsl"))); + m_ShaderProgramShadows.Compile(); + m_ShaderProgramShadows.Link(); - m_DebugAABB = CreateAABB(); + m_FirstPassProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/Vertex.glsl"))); + m_FirstPassProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/Fragment.glsl"))); + m_FirstPassProgram.Compile(); + + glBindFragDataLocation(m_FirstPassProgram.GetHandle(), 0, "frag_Diffuse"); + glBindFragDataLocation(m_FirstPassProgram.GetHandle(), 1, "frag_Position"); + glBindFragDataLocation(m_FirstPassProgram.GetHandle(), 2, "frag_Normal"); + m_FirstPassProgram.Link(); + + m_SecondPassProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/Vertex2.glsl"))); + m_SecondPassProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/Fragment2.glsl"))); + m_SecondPassProgram.Compile(); + m_SecondPassProgram.Link(); + + m_SecondPassProgram_Debug.AddShader(std::shared_ptr(new VertexShader("Shaders/Vertex2.glsl"))); + m_SecondPassProgram_Debug.AddShader(std::shared_ptr(new FragmentShader("Shaders/Fragment2-Debug.glsl"))); + m_SecondPassProgram_Debug.Compile(); + m_SecondPassProgram_Debug.Link(); + + m_FinalPassProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/FinalPass.vert.glsl"))); + m_FinalPassProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/FinalPass.frag.glsl"))); + m_FinalPassProgram.Compile(); + m_FinalPassProgram.Link(); m_ScreenQuad = CreateQuad(); CreateShadowMap(m_ShadowMapRes); + FrameBufferTextures(); +} + +void Renderer::Draw(double dt) +{ + if(glfwGetKey(m_Window, GLFW_KEY_F1)) + { + m_QuadView = false; + } + if(glfwGetKey(m_Window, GLFW_KEY_F2)) + { + m_QuadView = true; + } + + if(glfwGetKey(m_Window, GLFW_KEY_KP_1)) + { + Gamma -= 0.3f * dt; + LOG_INFO("Gamma_UP: %f", Gamma); + } + if(glfwGetKey(m_Window, GLFW_KEY_KP_4)) + { + Gamma += 0.3f * dt; + LOG_INFO("Gamma_DOWN: %f", Gamma); + } + + if(glfwGetKey(m_Window, GLFW_KEY_1)) + { + if(glfwGetKey(m_Window, GLFW_KEY_KP_ADD)) + { + CAtt += 0.5f * dt; + LOG_INFO("Const: %f", CAtt); + } + if(glfwGetKey(m_Window, GLFW_KEY_KP_SUBTRACT)) + { + CAtt -= 0.5f * dt; + LOG_INFO("Const: %f", CAtt); + } + } + if(glfwGetKey(m_Window, GLFW_KEY_2)) + { + if(glfwGetKey(m_Window, GLFW_KEY_KP_ADD)) + { + LAtt += 0.5f * dt; + LOG_INFO("Linear: %f", LAtt); + } + if(glfwGetKey(m_Window, GLFW_KEY_KP_SUBTRACT)) + { + LAtt -= 0.5f * dt; + LOG_INFO("Linear: %f", LAtt); + } + } + if(glfwGetKey(m_Window, GLFW_KEY_3)) + { + if(glfwGetKey(m_Window, GLFW_KEY_KP_ADD)) + { + QAtt += 0.5f * dt; + LOG_INFO("Quadratic: %f", QAtt); + } + if(glfwGetKey(m_Window, GLFW_KEY_KP_SUBTRACT)) + { + QAtt -= 0.5f * dt; + LOG_INFO("Quadratic: %f", QAtt); + } + } + + glDisable(GL_BLEND); + + DrawFBO(); + + ClearStuff(); + glfwSwapBuffers(m_Window); +} + +#pragma region TempRegion + +void Renderer::DrawSkybox() +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, m_Width, m_Height); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_ShaderProgramSkybox.Bind(); + glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * glm::toMat4(glm::inverse(m_Camera->Orientation())); + glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramSkybox.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(cameraMatrix)); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + m_Skybox->Draw(); } void Renderer::CreateShadowMap(int resolution) @@ -137,194 +246,35 @@ void Renderer::CreateShadowMap(int resolution) glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_ShadowDepthTexture, 0); glDrawBuffer(GL_NONE); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - { + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { LOG_ERROR("Framebuffer incomplete!"); return; + } } -void Renderer::Draw(double dt) -{ - glDisable(GL_BLEND); - - DrawSkybox(); - DrawShadowMap(); - DrawScene(); - -#ifdef DEBUG - // Draw bounding boxes - if (m_DrawBounds) - { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); - m_ShaderProgramDebugAABB.Bind(); - for (auto tuple : AABBsToRender) - { - glm::mat4 modelMatrix; - bool colliding; - std::tie(modelMatrix, colliding) = tuple; - // Model matrix - glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix(); - glm::mat4 MVP = cameraMatrix * modelMatrix; - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramDebugAABB.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); - // Color - glm::vec4 color(1.f, 1.f, 1.f, 0.f); - if (colliding) - color = glm::vec4(1.f, 0.f, 0.f, 0.f); - glUniform4fv(glGetUniformLocation(m_ShaderProgramDebugAABB.GetHandle(), "Color"), 1, glm::value_ptr(color)); - glBindVertexArray(m_DebugAABB); - glDrawArrays(GL_LINES, 0, 24); - } - } - - DrawDebugShadowMap(); -#endif - - ClearStuff(); - glfwSwapBuffers(m_Window); -} - -void Renderer::DrawSkybox() -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, m_Width, m_Height); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - m_ShaderProgramSkybox.Bind(); - glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * glm::toMat4(glm::inverse(m_Camera->Orientation())); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramSkybox.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(cameraMatrix)); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - m_Skybox->Draw(); -} - -void Renderer::DrawScene() -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, m_Width, m_Height); - - glClear(GL_DEPTH_BUFFER_BIT); - //glClearColor(1.0f, 1.0f, 0.0f, 1.0f); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); -#ifdef DEBUG - glDisable(GL_CULL_FACE); - glPolygonMode(GL_BACK, GL_LINE); -#endif - - // Draw models - glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)) * glm::translate(-m_Camera->Position() * glm::vec3(1, 0, 0)); - glm::mat4 depthCamera = m_SunProjection * depthViewMatrix; - glm::mat4 biasMatrix( - 0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 0.5, 0.0, - 0.5, 0.5, 0.5, 1.0 - ); - - m_ShaderProgram.Bind(); - glUniform1i(glGetUniformLocation(m_ShaderProgram.GetHandle(), "numberOfLights"), Lights); - glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "position"), Lights, Light_position.data()); - glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "specular"), Lights, Light_specular.data()); - glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "diffuse"), Lights, Light_diffuse.data()); - glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "constantAttenuation"), Lights, Light_constantAttenuation.data()); - glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "linearAttenuation"), Lights, Light_linearAttenuation.data()); - glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "quadraticAttenuation"), Lights, Light_quadraticAttenuation.data()); - glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "spotExponent"), Lights, Light_spotExponent.data()); - if (m_DrawWireframe) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, m_ShadowDepthTexture); - //DrawModels(m_ShaderProgram); - glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix(); - glm::mat4 depthCameraMatrix = biasMatrix * depthCamera; - glm::mat4 MVP; - glm::mat4 depthMVP; - for (auto tuple : ModelsToRender) - { - Model* model; - glm::mat4 modelMatrix; - bool visible; - std::tie(model, modelMatrix, visible, std::ignore) = tuple; - if (!visible) - continue; - - MVP = cameraMatrix * modelMatrix; - depthMVP = depthCameraMatrix * modelMatrix; - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVP)); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "model"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "view"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); - glBindVertexArray(model->VAO); - for (auto texGroup : model->TextureGroups) - { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, *texGroup.Texture); - glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, texGroup.EndIndex - texGroup.StartIndex + 1); - } - } - - for (auto tuple : TexturesToRender) - { - Texture* texture; - glm::mat4 modelMatrix; - glm::mat4 billboardMatrix; - std::tie(texture, modelMatrix, billboardMatrix) = tuple; - - //MVP = cameraMatrix * glm::inverse(glm::toMat4(m_Camera->Orientation()) * modelMatrix ); - MVP = cameraMatrix * modelMatrix * billboardMatrix; - - depthMVP = depthCameraMatrix * modelMatrix; - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVP)); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "model"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "view"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, *texture); - glBindVertexArray(m_ScreenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - - - - -#ifdef DEBUG - // Debug draw model normals - if (m_DrawNormals) - { - m_ShaderProgramNormals.Bind(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - DrawModels(m_ShaderProgramNormals); - } -#endif -} void Renderer::DrawShadowMap() { - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); + glEnable(GL_DEPTH_TEST);//Tests where objects are and display them correctly + glEnable(GL_CULL_FACE); //removes triangles on the wrong side of the object + glCullFace(GL_BACK); //Make it so that only the back faces are rendered + //Binds the FBO and sets the veiwport, witch in effect is how large the shadowmap is and what resolution it has. glBindFramebuffer(GL_FRAMEBUFFER, m_ShadowFrameBuffer); glViewport(0, 0, m_ShadowMapRes, m_ShadowMapRes); glClear(GL_DEPTH_BUFFER_BIT); //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)) * glm::translate(-m_Camera->Position() * glm::vec3(1, 0, 0)); -// glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)); + //Creates the "camera" for the shadowmap from the direction of the sun. + glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)); glm::mat4 depthCamera = m_SunProjection * depthViewMatrix; - - //glm::mat4 cameraMatrix = depthProjectionMatrix * m_Camera->ViewMatrix(); - glm::mat4 MVP; m_ShaderProgramShadows.Bind(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //Draws filled polygons + + //For each model, render them to the shadowmap for (auto tuple : ModelsToRender) { Model* model; @@ -425,26 +375,22 @@ void Renderer::AddPointLightToDraw( glm::vec3 _position, glm::vec3 _specular, glm::vec3 _diffuse, - float _constantAttenuation, - float _linearAttenuation, - float _quadraticAttenuation, - float _spotExponent + float _specularExponent, + float _ConstantAttenuation, + float _LinearAttenuation, + float _QuadraticAttenuation ) { - Light_position.push_back(_position.x); - Light_position.push_back(_position.y); - Light_position.push_back(_position.z); - Light_specular.push_back(_specular.x); - Light_specular.push_back(_specular.y); - Light_specular.push_back(_specular.z); - Light_diffuse.push_back(_diffuse.x); - Light_diffuse.push_back(_diffuse.y); - Light_diffuse.push_back(_diffuse.z); - Light_constantAttenuation.push_back(_constantAttenuation); - Light_linearAttenuation.push_back(_linearAttenuation); - Light_quadraticAttenuation.push_back(_quadraticAttenuation); - Light_spotExponent.push_back(_spotExponent); - Lights = Light_constantAttenuation.size(); + Light light; + light.Position = _position; + light.Diffuse = _diffuse; + light.Specular = _specular; + light.SpecularExponent = _specularExponent; + light.ConstantAttenuation = _ConstantAttenuation; + light.LinearAttenuation = _LinearAttenuation; + light.QuadraticAttenuation = _QuadraticAttenuation; + light.SphereModelMatrix = CreateLightMatrix(light); + Lights.push_back(light); } void Renderer::AddAABBToDraw(glm::vec3 origin, glm::vec3 volumeVector, bool colliding) @@ -577,17 +523,306 @@ GLuint Renderer::CreateSkybox() return vao; } + void Renderer::ClearStuff() { AABBsToRender.clear(); ModelsToRender.clear(); TexturesToRender.clear(); - Light_position.clear(); - Light_specular.clear(); - Light_diffuse.clear(); - Light_constantAttenuation.clear(); - Light_linearAttenuation.clear(); - Light_quadraticAttenuation.clear(); - Light_spotExponent.clear(); - Lights = 0; -} \ No newline at end of file + Lights.clear(); +} + +#pragma endregion + +void Renderer::FrameBufferTextures() +{ + m_fbBasePass = 0; + m_fDepthBuffer = 0; + + glGenFramebuffers(1, &m_fbBasePass); + glGenRenderbuffers(1, &m_fDepthBuffer); + + glBindRenderbuffer(GL_RENDERBUFFER, m_fDepthBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Width, m_Height); + + //Generate and bind diffuse texture + glGenTextures(1, &m_fDiffuseTexture); + glBindTexture(GL_TEXTURE_2D, m_fDiffuseTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Generate and bind position texture + glGenTextures(1, &m_fPositionTexture); + glBindTexture(GL_TEXTURE_2D, m_fPositionTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Generate and bind normal texture + glGenTextures(1, &m_fNormalsTexture); + glBindTexture(GL_TEXTURE_2D, m_fNormalsTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + /*glGenTextures(1, &m_fShadowTexture); + glBindTexture(GL_TEXTURE_2D, m_fShadowTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);*/ + + //Bind fb + glBindFramebuffer(GL_FRAMEBUFFER, m_fbBasePass); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_fDepthBuffer); + + //Attach textures to the FB + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fDiffuseTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_fPositionTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, m_fNormalsTexture, 0); + //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, m_fShadowTexture, 0); + + GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(fbStatus != GL_FRAMEBUFFER_COMPLETE) + { + LOG_ERROR("DeferredLighting:Init: m_fbBasePass incomplete: 0x%x\n", fbStatus); + //exit(1); + } + + m_fbLightingPass = 0; + glGenFramebuffers(1, &m_fbLightingPass); + + glGenTextures(1, &m_fLightingTexture); + glBindTexture(GL_TEXTURE_2D, m_fLightingTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glBindFramebuffer(GL_FRAMEBUFFER, m_fbLightingPass); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fLightingTexture, 0); + + fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(fbStatus != GL_FRAMEBUFFER_COMPLETE) + { + LOG_ERROR("DeferredLighting:Init: m_fbLightingPass incomplete: 0x%x\n", fbStatus); + //exit(1); + } + + + +} + +void Renderer::DrawFBO() +{ + DrawShadowMap(); + + /* + Base pass + */ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbBasePass); + + // Clear G-buffer + GLenum windowBuffClear[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; + glDrawBuffers(3, windowBuffClear); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Execute the first render stage which will fill out the internal buffers with data(??) + m_FirstPassProgram.Bind(); + GLenum windowBuffOpaque[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; + glDrawBuffers(3, windowBuffOpaque); + + glCullFace(GL_BACK); + + glViewport(0, 0, m_Width, m_Height); + DrawFBOScene(); + + /* + Lighting pass + */ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbLightingPass); + GLenum lightingPassAttachments[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, lightingPassAttachments); + + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + + m_SecondPassProgram.Bind(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_fPositionTexture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_fNormalsTexture); + + glCullFace(GL_FRONT); + DrawLightScene(); + + /* + Final pass + */ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + m_FinalPassProgram.Bind(); + + // Ambient light + glUniform3fv(glGetUniformLocation(m_FinalPassProgram.GetHandle(), "La"), 1, glm::value_ptr(glm::vec3(0.1f, 0.1f, 0.1f))); + glUniform1f(glGetUniformLocation(m_FinalPassProgram.GetHandle(), "Gamma"), Gamma); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_fDiffuseTexture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_fLightingTexture); + + glCullFace(GL_BACK); + glBindVertexArray(m_ScreenQuad); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLES, 0, 6); +} + +void Renderer::DrawFBOScene() +{ +// glEnable(GL_DEPTH_TEST);//Tests where objects are and display them correctly +// glEnable(GL_CULL_FACE); //removes triangles on the wrong side of the object +// glCullFace(GL_BACK); //Make it so that only the back faces are rendered + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //Draws filled polygons + + glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix(); + glm::mat4 MVP; + glm::mat4 biasMatrix( + 0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 0.5, 0.0, + 0.5, 0.5, 0.5, 1.0 + ); + + glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)); + glm::mat4 depthCamera = m_SunProjection * depthViewMatrix; + glm::mat4 depthCameraMatrix = biasMatrix * depthCamera; + glm::mat4 depthMVP; + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_ShadowDepthTexture); + + for (auto tuple : ModelsToRender) + { + Model* model; + glm::mat4 modelMatrix; + bool visible; + std::tie(model, modelMatrix, visible, std::ignore) = tuple; + if (!visible) + continue; + + MVP = cameraMatrix * modelMatrix; + depthMVP = depthCameraMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVP)); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); + glBindVertexArray(model->VAO); + for (auto texGroup : model->TextureGroups) + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, *texGroup.Texture); + glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, texGroup.EndIndex - texGroup.StartIndex + 1); + } + } + + for (auto tuple : TexturesToRender) + { + Texture* texture; + glm::mat4 modelMatrix; + glm::mat4 billboardMatrix; + std::tie(texture, modelMatrix, billboardMatrix) = tuple; + + //MVP = cameraMatrix * glm::inverse(glm::toMat4(m_Camera->Orientation()) * modelMatrix ); + MVP = cameraMatrix * modelMatrix * billboardMatrix; + + depthMVP = depthCameraMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVP)); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, *texture); + glBindVertexArray(m_ScreenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + } +} + + + +void Renderer::DrawLightScene() +{ + glEnable(GL_BLEND); + glBlendEquation (GL_FUNC_ADD); + glBlendFunc(GL_ONE,GL_ONE); + + glDisable (GL_DEPTH_TEST); + glDepthMask (GL_FALSE); + glBindVertexArray(m_sphereModel->VAO); + + glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix(); + glm::mat4 MVP; + + for (auto &light : Lights) + { + MVP = cameraMatrix * light.SphereModelMatrix; + + glUniform2fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "ViewportSize"), 1,glm::value_ptr(glm::vec2(m_Width, m_Height))); + glUniformMatrix4fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); + glUniformMatrix4fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); + glUniformMatrix4fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(light.SphereModelMatrix)); + glUniform3fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "ls"), 1, glm::value_ptr(light.Specular)); + glUniform3fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "ld"), 1, glm::value_ptr(light.Diffuse)); + glUniform3fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "lp"), 1, glm::value_ptr(light.Position)); + glUniform3f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "CameraPosition"), m_Camera->Position().x, m_Camera->Position().y, m_Camera->Position().z); + glUniform1f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "specularExponent"), light.SpecularExponent); +// glUniform1f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "ConstantAttenuation"), light.ConstantAttenuation); +// glUniform1f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "LinearAttenuation"), light.LinearAttenuation); +// glUniform1f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "QuadraticAttenuation"), light.QuadraticAttenuation); + glUniform1f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "ConstantAttenuation"), CAtt); + glUniform1f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "LinearAttenuation"), LAtt); + glUniform1f(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "QuadraticAttenuation"), QAtt); + + glDrawArrays(GL_TRIANGLES, 0, m_sphereModel->Vertices.size()); + }; + glEnable (GL_DEPTH_TEST); + glDepthMask (GL_TRUE); + glDisable (GL_BLEND); +} + +void Renderer::SetSphereModel( Model* _model ) +{ + m_sphereModel = _model; +} + +glm::mat4 Renderer::CreateLightMatrix(Light &_light) +{ +// float c = _light.ConstantAttenuation; +// float l = _light.LinearAttenuation; +// float q = _light.QuadraticAttenuation; + float c = CAtt; + float l = LAtt; + float q = QAtt; + float cutOffRadius = abs(sqrt((-4*c*q) + pow(l, 2) + (1024*q) - l) / (2*q)); + + glm::mat4 model; + model *= glm::translate(_light.Position); + model *= glm::scale(glm::vec3(cutOffRadius)); + return model; +} + diff --git a/src/Renderer.h b/src/Renderer.h index 26891d6..f462a09 100755 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -12,6 +12,7 @@ #include "Model.h" #include "Components/PointLight.h" #include "Skybox.h" +#include "ResourceManager.h" class Renderer { @@ -26,14 +27,6 @@ public: std::list> ModelsToRender; std::list> TexturesToRender; - int Lights; - std::vector Light_position; - std::vector Light_specular; - std::vector Light_diffuse; - std::vector Light_constantAttenuation; - std::vector Light_linearAttenuation; - std::vector Light_quadraticAttenuation; - std::vector Light_spotExponent; std::list> AABBsToRender; Renderer(); @@ -49,10 +42,10 @@ public: glm::vec3 _position, glm::vec3 _specular, glm::vec3 _diffuse, - float _constantAttenuation, - float _linearAttenuation, - float _quadraticAttenuation, - float _spotExponent + float _specularExponent, + float _ConstantAttenuation, + float _LinearAttenuation, + float _QuadraticAttenuation ); void AddAABBToDraw(glm::vec3 origin, glm::vec3 volumeVector, bool colliding); @@ -69,8 +62,25 @@ public: void DrawBounds(bool val) { m_DrawBounds = val; } void DrawSkybox(); + void SetSphereModel(Model* _model); + private: int m_Width, m_Height; + + struct Light + { + glm::vec3 Position; + glm::vec3 Specular; + glm::vec3 Diffuse; + float SpecularExponent; + glm::mat4 SphereModelMatrix; + float ConstantAttenuation, LinearAttenuation, QuadraticAttenuation; + }; + + float Gamma; + + std::list Lights; + GLFWwindow* m_Window; GLint m_glVersion[2]; GLchar* m_glVendor; @@ -78,6 +88,7 @@ private: bool m_DrawNormals; bool m_DrawWireframe; bool m_DrawBounds; + float CAtt, LAtt, QAtt; std::shared_ptr m_Skybox; @@ -87,24 +98,53 @@ private: glm::mat4 m_SunProjection; GLuint m_DebugAABB; - GLuint m_ScreenQuad; GLuint m_ShadowFrameBuffer; GLuint m_ShadowDepthTexture; + GLuint m_fbBasePass; + GLuint m_fDiffuseTexture; + GLuint m_fPositionTexture; + GLuint m_fNormalsTexture; + GLuint m_fBlendTexture; + GLuint m_fbLightingPass; + GLuint m_fLightingTexture; + GLuint m_fShadowTexture; + + GLuint m_fDepthBuffer; + GLenum draw_bufs[2]; + GLuint m_ScreenQuad; + Model* m_sphereModel; + + bool m_QuadView; + std::shared_ptr m_Camera; ShaderProgram m_ShaderProgram; + ShaderProgram m_FirstPassProgram; + ShaderProgram m_SecondPassProgram; + ShaderProgram m_SecondPassProgram_Debug; + ShaderProgram m_FinalPassProgram; + ShaderProgram m_ShaderProgramNormals; ShaderProgram m_ShaderProgramShadows; ShaderProgram m_ShaderProgramShadowsDrawDepth; ShaderProgram m_ShaderProgramDebugAABB; ShaderProgram m_ShaderProgramSkybox; + + void ClearStuff(); void DrawScene(); void DrawModels(ShaderProgram &shader); void DrawShadowMap(); void CreateShadowMap(int resolution); + void FrameBufferTextures(); + void DrawFBO(); + void DrawFBOScene(); + void DrawLightScene(); + void BindFragDataLocation(); + glm::mat4 CreateLightMatrix(Light &_light); + GLuint CreateQuad(); void DrawDebugShadowMap(); GLuint CreateAABB(); diff --git a/src/ShaderProgram.cpp b/src/ShaderProgram.cpp index e9bd864..bd67e90 100755 --- a/src/ShaderProgram.cpp +++ b/src/ShaderProgram.cpp @@ -103,6 +103,11 @@ void ShaderProgram::AddShader(std::shared_ptr shader) void ShaderProgram::Compile() { + if (m_ShaderProgramHandle == 0) + { + m_ShaderProgramHandle = glCreateProgram(); + } + for (auto &shader : m_Shaders) { if (!shader->IsCompiled()) @@ -121,7 +126,7 @@ GLuint ShaderProgram::Link() } LOG_INFO("Linking shader program"); - m_ShaderProgramHandle = glCreateProgram(); + for (auto &shader : m_Shaders) { glAttachShader(m_ShaderProgramHandle, shader->GetHandle()); diff --git a/src/ShaderProgram.h b/src/ShaderProgram.h index 07dbf9b..a27300c 100755 --- a/src/ShaderProgram.h +++ b/src/ShaderProgram.h @@ -61,7 +61,7 @@ class ShaderProgram { public: ShaderProgram() - : m_ShaderProgramHandle(0) { } + : m_ShaderProgramHandle(0) { } ~ShaderProgram(); void AddShader(std::shared_ptr shader); diff --git a/src/Shaders/FinalPass.frag.glsl b/src/Shaders/FinalPass.frag.glsl new file mode 100644 index 0000000..2a6cf4c --- /dev/null +++ b/src/Shaders/FinalPass.frag.glsl @@ -0,0 +1,29 @@ +#version 430 + +uniform vec3 La; +uniform float Gamma; + +layout (binding=0) uniform sampler2D DiffuseTexture; +layout (binding=1) uniform sampler2D LightingTexture; +layout (binding=2) uniform sampler2D ShadowTexture; + +in VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Input; + +out vec4 FragmentColor; + +void main() +{ + vec4 DiffuseTexel = texture(DiffuseTexture, Input.TextureCoord); + vec4 LightingTexel = texture(LightingTexture, Input.TextureCoord); + vec4 ShadowTexel = texture(ShadowTexture, Input.TextureCoord); + + + vec4 _FragmentColor = DiffuseTexel * vec4(La, 1.0) + LightingTexel; + FragmentColor = vec4(pow(_FragmentColor.rgb, vec3(1.0 / Gamma)), _FragmentColor.a); + //FragmentColor = ShadowTexel; + +} \ No newline at end of file diff --git a/src/Shaders/FinalPass.vert.glsl b/src/Shaders/FinalPass.vert.glsl new file mode 100644 index 0000000..05deece --- /dev/null +++ b/src/Shaders/FinalPass.vert.glsl @@ -0,0 +1,16 @@ +#version 430 + +layout(location = 0) in vec3 Position; + +out VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Output; + +void main() +{ + gl_Position = vec4(Position, 1.0); + Output.Position = Position; + Output.TextureCoord = (vec2(Position) + 1) / 2; +} \ No newline at end of file diff --git a/src/Shaders/Fragment.glsl b/src/Shaders/Fragment.glsl index 1909e84..cc5370f 100755 --- a/src/Shaders/Fragment.glsl +++ b/src/Shaders/Fragment.glsl @@ -1,113 +1,43 @@ #version 430 -uniform mat4 model; -uniform mat4 view; - -layout(binding=0) uniform sampler2D texture0; -layout(binding=1) uniform sampler2D shadowMap; - -const int maxNumberOfLights = 82; -uniform int numberOfLights; -uniform vec3 position[maxNumberOfLights]; -uniform vec3 specular[maxNumberOfLights]; -uniform vec3 diffuse[maxNumberOfLights]; -uniform float constantAttenuation[maxNumberOfLights]; -uniform float linearAttenuation[maxNumberOfLights]; -uniform float quadraticAttenuation[maxNumberOfLights]; -uniform float spotExponent[maxNumberOfLights]; +layout (binding=0) uniform sampler2D DiffuseTexture; +layout (binding=1) uniform sampler2D ShadowTexture; in VertexData { vec3 Position; vec3 Normal; vec2 TextureCoord; - vec3 ShadowCoord; + vec4 ShadowCoord; } Input; -vec3 scene_ambient = vec3(0.5, 0.5, 0.5); +out vec4 frag_Diffuse; +out vec4 frag_Position; +out vec4 frag_Normal; -out vec4 fragmentColor; +float Shadow(vec4 ShadowCoord) +{ + //float cosTheta = clamp(dot(Input.Normal, 1.0), 0.0, 1.0); + float bias = 0.0005; // cosTheta is dot( n,l ), clamped between 0 and 1 + bias = clamp(bias, 0.0, 0.01); + if( texture(ShadowTexture, Input.ShadowCoord.xy).z < ShadowCoord.z - bias) + { + return 0.3; + } + else + { + return 1.0; + } +} void main() { + // Diffuse Texture + frag_Diffuse = texture(DiffuseTexture, Input.TextureCoord) * Shadow(Input.ShadowCoord); - // Texture - vec4 texel = texture2D(texture0, Input.TextureCoord); - //vec4 texel = (blend.x * texel0) + (blend.y * texel1) + (blend.z * texel2); + // G-buffer Position + frag_Position = vec4(Input.Position.xyz, 1.0); - // - // Phong shading - // - - // Ambient light - vec3 La = scene_ambient; // Ambient light - vec3 Ks = vec3(0.3, 0.3, 0.3); // Specular reflectance - vec3 Kd = vec3(1.0, 1.0, 1.0); // Diffuse reflectance - vec3 Ka = vec3(1.0, 1.0, 1.0); // Ambient reflectance - vec3 Is; - vec3 Id; - - // Shadows - //float cosTheta = clamp(dot(Input.Normal, vec3(0, 1, 0)), 0.0, 1.0); - //float bias = 0.001 * tan(acos(cosTheta)); // cosTheta is dot( n,l ), clamped between 0 and 1 - //bias = clamp(bias, 0.0, 0.01); - float visibility = 1.0; - /*if (Input.ShadowCoord.x >= 0.0 && Input.ShadowCoord.x <= 1.0 && Input.ShadowCoord.y >= 0.0 && Input.ShadowCoord.y <= 1.0) - { - float bias = 0.00005; - vec4 shadowMapValue = texture(shadowMap, Input.ShadowCoord.xy); - if (shadowMapValue.z < clamp(Input.ShadowCoord.z - bias, 0, 1)) - { - visibility = 0.3; - } - }*/ - - vec3 totalLighting = La * Ka * visibility; - - float attenuation; - - for(int i = 0; i < numberOfLights && i < maxNumberOfLights; i++) - { - // Light - //vec3 lightPosition = vec3(0, 0, 2); - vec3 Ls = specular[i]; // Specular light - vec3 Ld = diffuse[i]; // Diffuse light - - vec3 lightPosView = vec3(view * vec4(position[i], 1.0)); - vec3 surfacePosition = vec3(model * vec4(Input.Position, 1.0)); - vec3 surfacePosView = vec3(view * vec4(surfacePosition, 1.0)); - vec3 surfaceToLight = normalize(lightPosView - surfacePosView); - mat3 normalMatrix = transpose(inverse(mat3(view * model))); - vec3 surfaceNormal = normalize(normalMatrix * Input.Normal); - - float dist = length(position[i] - surfacePosition); - - attenuation = 1.0 / (constantAttenuation[i] - + linearAttenuation[i] * dist - + quadraticAttenuation[i] * pow(dist, 2.0)); - //attenuation = attenuation * pow(clampedCosine, spotExponent[i]); - - // Diffuse light - float dotProd = dot(surfaceToLight, surfaceNormal); - dotProd = max(dotProd, 0.0); - - Id = Ld * Kd * abs(dotProd) * attenuation; - - // Specular light - vec3 reflection = reflect(-surfaceToLight, surfaceNormal); - float dotSpecular = dot(reflection, normalize(-surfacePosView)); - dotSpecular = max(dotSpecular, 0.0); - float specularFactor = pow(dotSpecular, 30.0); // Specular factor - - Is = attenuation * Ls * Ks * specularFactor; - - totalLighting = totalLighting + Id + Is; - } - - fragmentColor = vec4(totalLighting, 1.0) * texel; - - - //fragmentColor = vec4(Id, 1.0) * texel; - - //fragmentColor = texel; + // G-buffer Normal + frag_Normal = vec4(Input.Normal, 0.0); } \ No newline at end of file diff --git a/src/Shaders/Fragment2-Debug.glsl b/src/Shaders/Fragment2-Debug.glsl new file mode 100644 index 0000000..db35d6e --- /dev/null +++ b/src/Shaders/Fragment2-Debug.glsl @@ -0,0 +1,38 @@ +#version 430 + +layout (binding=0) uniform sampler2D DiffuseTexture; +layout (binding=1) uniform sampler2D PositionTexture; +layout (binding=2) uniform sampler2D NormalTexture; + +in VertexData +{ + vec3 Position; + vec3 Normal; + vec2 TextureCoord; +} Input; + +out vec4 FragColor; + +void DrawQuadrant(vec4 texel, vec2 quadrant) +{ + if (-quadrant.x * Input.Position.x < 0 && -quadrant.y * Input.Position.y < 0) + { + FragColor = texel; + } +} + +void main() +{ + vec4 DiffuseTexel = texture2D(DiffuseTexture, Input.TextureCoord); + vec4 PositionTexel = texture2D(PositionTexture, Input.TextureCoord); + vec4 NormalTexel = texture2D(NormalTexture, Input.TextureCoord); + + //FragColor = texture2D(DiffuseTexture, Input.TextureCoord * 2 + vec2(0, -1)); + DrawQuadrant(texture2D(DiffuseTexture, Input.TextureCoord * 2), vec2(-1, 1)); + DrawQuadrant(texture2D(PositionTexture, Input.TextureCoord * 2), vec2(1, 1)); + DrawQuadrant(texture2D(NormalTexture, Input.TextureCoord * 2), vec2(-1, -1)); + + vec4 AllTexel = texture2D(DiffuseTexture, Input.TextureCoord*2)*texture2D(PositionTexture, Input.TextureCoord*2)*texture2D(NormalTexture, Input.TextureCoord*2); + DrawQuadrant(AllTexel, vec2(1, -1)); +} + diff --git a/src/Shaders/Fragment2.glsl b/src/Shaders/Fragment2.glsl new file mode 100644 index 0000000..f531f76 --- /dev/null +++ b/src/Shaders/Fragment2.glsl @@ -0,0 +1,84 @@ +#version 430 + +layout (binding=0) uniform sampler2D PositionTexture; +layout (binding=1) uniform sampler2D NormalsTexture; + +uniform vec2 ViewportSize; +uniform mat4 MVP; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform vec3 la; +uniform vec3 ls; +uniform vec3 ld; +uniform vec3 lp; +uniform float specularExponent; +uniform vec3 CameraPosition; +uniform float ConstantAttenuation; +uniform float LinearAttenuation; +uniform float QuadraticAttenuation; + +const vec3 ks = vec3(1.0, 1.0, 1.0); +const vec3 kd = vec3(1.0, 1.0, 1.0); +const vec3 ka = vec3(1.0, 1.0, 1.0); +const float kshine = 1.0; + +in VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Input; + +out vec4 FragColor; + +vec4 phong(vec3 position, vec3 normal) +{ + // Diffuse + vec3 lightPos = vec3(V * vec4(lp, 1.0)); + vec3 distanceToLight = lightPos - position; + vec3 directionToLight = normalize(distanceToLight); + float dotProd = dot(directionToLight, normal); + dotProd = max(dotProd, 0.0); + vec3 Id = kd * ld * dotProd; + + // Specular + //vec3 reflection = reflect(-directionToLight, normal); + vec3 surfaceToViewer = normalize(-position); + vec3 halfWay = normalize(surfaceToViewer + directionToLight); + float dotSpecular = max(dot(halfWay, normal), 0.0); + float specularFactor = pow(dotSpecular, specularExponent * 2.0); + vec3 Is = ks * ls * specularFactor; + + //Attenuation + float dist = distance(lightPos, position); + //float attenuation = -log(min(1.0, dist / LightRadius)); + + float attenuation = 1.0 / (ConstantAttenuation + (LinearAttenuation * dist) + (QuadraticAttenuation * dist * dist)); + + //float attenuation = 1.0 / (1.0 - 0.0001 * pow(dist, 2)); + + //float attenuation = clamp(0.0, 1.0, 1.0 / (0.001 + (0.001 * dist) + (0.001 * dist * dist))); + + //float attenuation = 1.0 / dot(directionToLight, directionToLight); + + //float att_s = 5; + //float attenuation = pow(dist, 2) / pow(5.0, 2); + //attenuation = 1.0 / (1.0 + attenuation * att_s); + //att_s = 1.0 / (1.0 + att_s); + //attenuation = attenuation / (1.0 - att_s); + + //float radius = 5.0; + //float alpha = dist / radius; + //float dampingFactor = 1.0 - pow(alpha, 3); + + return vec4((Id + Is) * attenuation, 1.0); +} + +void main() +{ + vec2 TextureCoord = gl_FragCoord.xy / ViewportSize; + vec4 PositionTexel = texture(PositionTexture, TextureCoord); + vec4 NormalTexel = texture(NormalsTexture, TextureCoord); + + FragColor = phong(vec3(PositionTexel), vec3(NormalTexel)); +} \ No newline at end of file diff --git a/src/Shaders/Vertex.glsl b/src/Shaders/Vertex.glsl index 295d523..2f799ef 100755 --- a/src/Shaders/Vertex.glsl +++ b/src/Shaders/Vertex.glsl @@ -1,26 +1,29 @@ #version 430 uniform mat4 MVP; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; uniform mat4 DepthMVP; -layout(location = 0) in vec3 Position; -layout(location = 1) in vec3 Normal; -layout(location = 2) in vec2 TextureCoord; +layout (location = 0) in vec3 Position; +layout (location = 1) in vec3 Normal; +layout (location = 2) in vec2 TextureCoord; out VertexData { vec3 Position; vec3 Normal; vec2 TextureCoord; - vec3 ShadowCoord; + vec4 ShadowCoord; } Output; void main() { gl_Position = MVP * vec4(Position, 1.0); - Output.Position = Position; - Output.Normal = Normal; + Output.Position = vec3(V * M * vec4(Position, 1.0)); + Output.Normal = normalize(vec3(inverse(transpose(V * M)) * vec4(Normal, 0.0))); Output.TextureCoord = TextureCoord; - Output.ShadowCoord = vec3(DepthMVP * vec4(Position, 1.0)); + Output.ShadowCoord = DepthMVP * vec4(Position, 1.0); } \ No newline at end of file diff --git a/src/Shaders/Vertex2.glsl b/src/Shaders/Vertex2.glsl new file mode 100644 index 0000000..e617846 --- /dev/null +++ b/src/Shaders/Vertex2.glsl @@ -0,0 +1,22 @@ +#version 430 + +uniform mat4 MVP; + +layout (location = 0) in vec3 Position; +layout (location = 2) in vec2 TextureCoord; + +uniform mat4 depthBiasMVP; + +out VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Output; + +void main() +{ + gl_Position = MVP * vec4(Position, 1.0); + Output.Position = Position; + Output.TextureCoord = (vec2(Position) + 1.0) / 2.0; + +} \ No newline at end of file diff --git a/src/Shaders/geometry_pass.frag.glsl b/src/Shaders/geometry_pass.frag.glsl deleted file mode 100644 index 4fe34ba..0000000 --- a/src/Shaders/geometry_pass.frag.glsl +++ /dev/null @@ -1,20 +0,0 @@ -#version 430 - -in vec2 TexCoord0; -in vec3 Normal0; -in vec3 WorldPos0; - -layout (location = 0) out vec3 WorldPosOut; -layout (location = 1) out vec3 DiffuseOut; -layout (location = 2) out vec3 NormalOut; -layout (location = 3) out vec3 TexCoordOut; - -uniform sampler2D gColorMap; - -void main() -{ - WorldPosOut = WorldPos0; - DiffuseOut = texture(gColorMap, TexCoord0).xyz; - NormalOut = normalize(Normal0); - TexCoordOut = vec3(TexCoord0, 0.0); -} \ No newline at end of file diff --git a/src/Shaders/geometry_pass.vert.glsl b/src/Shaders/geometry_pass.vert.glsl deleted file mode 100644 index c431ba9..0000000 --- a/src/Shaders/geometry_pass.vert.glsl +++ /dev/null @@ -1,20 +0,0 @@ -#version 430 - -layout (location = 0) in vec3 Position; -layout (location = 1) in vec2 TexCoord; -layout (location = 2) in vec3 Normal; - -uniform mat4 gWVP; -uniform mat4 gWorld; - -out vec2 TexCoord0; -out vec3 Normal0; -out vec3 WorldPos0; - -void main() -{ - gl_Position = gWVP * vec4(Position, 1.0); - TexCoord0 = TexCoord; - Normal0 = (gWorld * vec4(Normal, 0.0)).xyz; - WorldPos0 = (gWorld * vec4(Position, 1.0)).xyz; -} \ No newline at end of file diff --git a/src/Systems/RenderSystem.cpp b/src/Systems/RenderSystem.cpp index 35a57d8..4f0e727 100755 --- a/src/Systems/RenderSystem.cpp +++ b/src/Systems/RenderSystem.cpp @@ -39,10 +39,11 @@ void Systems::RenderSystem::UpdateEntity(double dt, EntityID entity, EntityID pa position, pointLightComponent->Specular, pointLightComponent->Diffuse, - pointLightComponent->constantAttenuation, - pointLightComponent->linearAttenuation, - pointLightComponent->quadraticAttenuation, - pointLightComponent->spotExponent); + pointLightComponent->specularExponent, + pointLightComponent->ConstantAttenuation, + pointLightComponent->LinearAttenuation, + pointLightComponent->QuadraticAttenuation + ); } auto cameraComponent = m_World->GetComponent(entity, "Camera"); @@ -71,6 +72,8 @@ void Systems::RenderSystem::UpdateEntity(double dt, EntityID entity, EntityID pa void Systems::RenderSystem::Initialize() { m_TransformSystem = m_World->GetSystem("TransformSystem"); + + m_Renderer->SetSphereModel(m_World->GetResourceManager()->Load("Model", "Models/Placeholders/PhysicsTest/Sphere.obj")); } void Systems::RenderSystem::RegisterComponents(ComponentFactory* cf) diff --git a/src/Util/defferedUtil.h b/src/Util/defferedUtil.h new file mode 100644 index 0000000..d362fac --- /dev/null +++ b/src/Util/defferedUtil.h @@ -0,0 +1,28 @@ +#ifndef UTIL_H +#define UTIL_H + +#include +#include +#include + +#define ZERO_MEM(a) memset(a, 0, sizeof(a)) + +#define ARRAY_SIZE_IN_ELEMENTS(a) (sizeof(a)/sizeof(a[0])) + +#define INVALID_OGL_VALUE 0xFFFFFFFF + +#define SAFE_DELETE(p) if (p) { delete p; p = NULL; } + +#define GLExitIfError() \ +{ \ + GLenum Error = glGetError(); \ + \ + if (Error != GL_NO_ERROR) { \ + printf("OpenGL error in %s:%d: 0x%x\n", __FILE__, __LINE__, Error); \ + exit(0); \ + } \ +} + +#define GLCheckError() (glGetError() == GL_NO_ERROR) + +#endif /* UTIL_H */ diff --git a/src/gBuffer.cpp b/src/gBuffer.cpp deleted file mode 100644 index 5acf690..0000000 --- a/src/gBuffer.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "PrecompiledHeader.h" -#include "gBuffer.h" - -bool GBuffer::Init(unsigned int WindowWidth, unsigned int WindowHeight) -{ - // Create the FBO - glGenFramebuffers(1, &m_fbo); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo); - - // Create the gbuffer textures - glGenTextures(ARRAY_SIZE_IN_ELEMENTS(m_textures), m_textures); - glGenTextures(1, &m_depthTexture); - - for (unsigned int i = 0 ; i < ARRAY_SIZE_IN_ELEMENTS(m_textures) ; i++) { - glBindTexture(GL_TEXTURE_2D, m_textures[i]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0); - } - - // depth - glBindTexture(GL_TEXTURE_2D, m_depthTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, - NULL); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0); - - GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; - glDrawBuffers(ARRAY_SIZE_IN_ELEMENTS(DrawBuffers), DrawBuffers); - - GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - if (Status != GL_FRAMEBUFFER_COMPLETE) { - printf("FB error, status: 0x%x\n", Status); - return false; - } - - // restore default FBO - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - - return true; -} \ No newline at end of file diff --git a/src/gBuffer.h b/src/gBuffer.h deleted file mode 100644 index 721eb15..0000000 --- a/src/gBuffer.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef gBuffer_h__ -#define gBuffer_h__ - -#include - -class GBuffer -{ -public: - - enum GBUFFER_TEXTURE_TYPE { - GBUFFER_TEXTURE_TYPE_POSITION, - GBUFFER_TEXTURE_TYPE_DIFFUSE, - GBUFFER_TEXTURE_TYPE_NORMAL, - GBUFFER_TEXTURE_TYPE_TEXCOORD, - GBUFFER_NUM_TEXTURES - }; - - GBuffer(); - - ~GBuffer(); - - bool Init(unsigned int WindowWidth, unsigned int WindowHeight); - - void BindForWriting(); - - void BindForReading(); - -private: - - GLuint m_fbo; - GLuint m_textures[GBUFFER_NUM_TEXTURES]; - GLuint m_depthTexture; -}; - -#endif //gBuffer_h__ \ No newline at end of file diff --git a/vs11/Returngeance.psess b/vs11/Returngeance.psess new file mode 100644 index 0000000..1912c4c --- /dev/null +++ b/vs11/Returngeance.psess @@ -0,0 +1,83 @@ + + + + Returngeance.sln + Sampling + None + true + true + Timestamp + Cycles + 10000000 + 10 + 10 + + false + + + + false + 500 + + \Memory\Pages/sec + \PhysicalDisk(_Total)\Avg. Disk Queue Length + \Processor(_Total)\% Processor Time + + + + true + false + false + + false + + + false + + + + bin\Debug\Returngeance.exe + 01/01/0001 00:00:00 + true + true + false + false + false + false + false + true + false + Executable + bin\Debug\Returngeance.exe + ..\bin\Debug + + + IIS + InternetExplorer + true + false + + false + + + false + + {E8B4A2A2-882B-402A-98A7-8B4F7233C8B3}|Returngeance\Returngeance.vcxproj + Returngeance\Returngeance.vcxproj + Returngeance + + + + + Returngeance140427.vsp + + + Returngeance140427(1).vsp + + + + + :PB:{E8B4A2A2-882B-402A-98A7-8B4F7233C8B3}|Returngeance\Returngeance.vcxproj + + + \ No newline at end of file diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index 6ccecc9..5226852 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -195,6 +195,7 @@ + @@ -203,7 +204,11 @@ + + + + @@ -211,6 +216,7 @@ + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 641fa8f..f0252d5 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -352,12 +352,10 @@ Input\Events + - - Shaders - - + Shaders @@ -381,11 +379,29 @@ Shaders + + Shaders + Shaders Shaders + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + \ No newline at end of file