From 0bb5f96d7a215e15db98bdd1fe1becb25ac10a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kapu=C5=9Bci=C5=84ski?= Date: Sun, 28 Feb 2016 23:17:25 +0100 Subject: [PATCH 1/3] Changed depth of shadow map texture to 32 --- src/graphics/engine/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 0fa95753..e08297e8 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -3386,7 +3386,7 @@ void CEngine::RenderShadowMap() FramebufferParams params; params.width = params.height = width; - params.depth = depth = 16; + params.depth = depth = 32; params.depthTexture = true; CFramebuffer *framebuffer = m_device->CreateFramebuffer("shadow", params); From 78e877d9a88f5053d4b9b5ad34fbebbdeda16a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kapu=C5=9Bci=C5=84ski?= Date: Mon, 29 Feb 2016 16:42:01 +0100 Subject: [PATCH 2/3] Changes in framebuffer creation, framebuffer error detection and small other graphical things --- src/graphics/core/framebuffer.cpp | 3 +- src/graphics/core/framebuffer.h | 4 +- src/graphics/engine/engine.cpp | 12 ++-- src/graphics/opengl/gl21device.cpp | 39 ++++++++-- src/graphics/opengl/gl33device.cpp | 15 ++-- src/graphics/opengl/gl33device.h | 2 + src/graphics/opengl/gldevice.cpp | 16 +++-- src/graphics/opengl/gldevice.h | 2 + src/graphics/opengl/glframebuffer.cpp | 71 ++++++++++++++++--- src/graphics/opengl/glframebuffer.h | 4 +- src/graphics/opengl/glutil.cpp | 17 +++++ src/graphics/opengl/glutil.h | 9 +++ .../shaders/fragment_shader_21_perpixel.glsl | 4 ++ .../shaders/fragment_shader_33_perpixel.glsl | 4 +- .../shaders/vertex_shader_21_pervertex.glsl | 65 ++++++++++++----- 15 files changed, 210 insertions(+), 57 deletions(-) diff --git a/src/graphics/core/framebuffer.cpp b/src/graphics/core/framebuffer.cpp index 7298c33c..5a37dff7 100644 --- a/src/graphics/core/framebuffer.cpp +++ b/src/graphics/core/framebuffer.cpp @@ -32,8 +32,9 @@ CDefaultFramebuffer::CDefaultFramebuffer(const FramebufferParams& params) { } -void CDefaultFramebuffer::Create() +bool CDefaultFramebuffer::Create() { + return true; } void CDefaultFramebuffer::Destroy() diff --git a/src/graphics/core/framebuffer.h b/src/graphics/core/framebuffer.h index 2f2b6c85..4598b6d7 100644 --- a/src/graphics/core/framebuffer.h +++ b/src/graphics/core/framebuffer.h @@ -70,7 +70,7 @@ public: virtual ~CFramebuffer() {} //! Creates this framebuffer - virtual void Create() = 0; + virtual bool Create() = 0; //! Destroys this framebuffer virtual void Destroy() = 0; @@ -122,7 +122,7 @@ public: explicit CDefaultFramebuffer(const FramebufferParams ¶ms); //! Creates default framebuffer - void Create() override; + bool Create() override; //! Destroys default framebuffer void Destroy() override; diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index e08297e8..3bed357c 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -3392,7 +3392,7 @@ void CEngine::RenderShadowMap() CFramebuffer *framebuffer = m_device->CreateFramebuffer("shadow", params); if (framebuffer == nullptr) { - GetLogger()->Error("Could not create framebuffer, disabling shadows\n"); + GetLogger()->Error("Could not create shadow mapping framebuffer, disabling dynamic shadows\n"); m_shadowMapping = false; m_offscreenShadowRendering = false; m_qualityShadows = false; @@ -3722,6 +3722,12 @@ void CEngine::UseMSAA(bool enable) params.samples = m_multisample; framebuffer = m_device->CreateFramebuffer("multisample", params); + + if (framebuffer == nullptr) + { + GetLogger()->Error("Could not create MSAA framebuffer, disabling MSAA\n"); + m_multisample = 1; + } } framebuffer->Bind(); @@ -4518,8 +4524,6 @@ void CEngine::DrawPlanet() if (! m_planet->PlanetExist()) return; - m_device->SetRenderMode(RENDER_MODE_INTERFACE); - m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false); m_device->SetRenderState(RENDER_STATE_LIGHTING, false); m_device->SetRenderState(RENDER_STATE_FOG, false); @@ -4529,8 +4533,6 @@ void CEngine::DrawPlanet() m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface); m_planet->Draw(); // draws the planets - - m_device->SetRenderMode(RENDER_MODE_NORMAL); } void CEngine::DrawForegroundImage() diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp index 0601678f..4b668753 100644 --- a/src/graphics/opengl/gl21device.cpp +++ b/src/graphics/opengl/gl21device.cpp @@ -392,9 +392,9 @@ bool CGL21Device::Create() uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor"); uni.lightingEnabled = glGetUniformLocation(m_normalProgram, "uni_LightingEnabled"); - uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_AmbientColor"); - uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_DiffuseColor"); - uni.specularColor = glGetUniformLocation(m_normalProgram, "uni_SpecularColor"); + uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_Material.ambient"); + uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_Material.diffuse"); + uni.specularColor = glGetUniformLocation(m_normalProgram, "uni_Material.specular"); GLchar name[64]; for (int i = 0; i < 8; i++) @@ -402,6 +402,9 @@ bool CGL21Device::Create() sprintf(name, "uni_Light[%d].Enabled", i); uni.lights[i].enabled = glGetUniformLocation(m_normalProgram, name); + sprintf(name, "uni_Light[%d].Type", i); + uni.lights[i].type = glGetUniformLocation(m_normalProgram, name); + sprintf(name, "uni_Light[%d].Position", i); uni.lights[i].position = glGetUniformLocation(m_normalProgram, name); @@ -416,6 +419,15 @@ bool CGL21Device::Create() sprintf(name, "uni_Light[%d].Attenuation", i); uni.lights[i].attenuation = glGetUniformLocation(m_normalProgram, name); + + sprintf(name, "uni_Light[%d].SpotDirection", i); + uni.lights[i].spotDirection = glGetUniformLocation(m_normalProgram, name); + + sprintf(name, "uni_Light[%d].Exponent", i); + uni.lights[i].spotExponent = glGetUniformLocation(m_normalProgram, name); + + sprintf(name, "uni_Light[%d].SpotCutoff", i); + uni.lights[i].spotCutoff = glGetUniformLocation(m_normalProgram, name); } // Set default uniform values @@ -697,14 +709,27 @@ void CGL21Device::SetLight(int index, const Light &light) if (light.type == LIGHT_DIRECTIONAL) { + glUniform1i(loc.type, 1); glUniform4f(loc.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f); } - else + else if (light.type == LIGHT_POINT) { + glUniform1i(loc.type, 2); glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f); - } - // TODO: add spotlight params + glUniform3f(loc.spotDirection, 0.0f, 1.0f, 0.0f); + glUniform1f(loc.spotCutoff, -1.0f); + glUniform1f(loc.spotExponent, 1.0f); + } + else if (light.type == LIGHT_SPOT) + { + glUniform1i(loc.type, 3); + glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f); + + glUniform3f(loc.spotDirection, -light.direction.x, -light.direction.y, -light.direction.z); + glUniform1f(loc.spotCutoff, std::cosf(light.spotAngle)); + glUniform1f(loc.spotExponent, light.spotIntensity); + } } void CGL21Device::SetLightEnabled(int index, bool enabled) @@ -1967,7 +1992,7 @@ CFramebuffer* CGL21Device::CreateFramebuffer(std::string name, const Framebuffer else return nullptr; - framebuffer->Create(); + if (!framebuffer->Create()) return nullptr; CFramebuffer* framebufferPtr = framebuffer.get(); m_framebuffers[name] = std::move(framebuffer); diff --git a/src/graphics/opengl/gl33device.cpp b/src/graphics/opengl/gl33device.cpp index ed4fe08b..e43f1b87 100644 --- a/src/graphics/opengl/gl33device.cpp +++ b/src/graphics/opengl/gl33device.cpp @@ -645,7 +645,7 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix) glUniformMatrix4fv(m_uni->modelMatrix, 1, GL_FALSE, m_worldMat.Array()); m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat); - m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = true; // normal transform Math::Matrix normalMat = matrix; @@ -662,15 +662,14 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix) m_viewMat = Math::MultiplyMatrices(scale, matrix); m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat); - m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = true; glUniformMatrix4fv(m_uni->viewMatrix, 1, GL_FALSE, m_viewMat.Array()); } else if (type == TRANSFORM_PROJECTION) { m_projectionMat = matrix; - - m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = true; glUniformMatrix4fv(m_uni->projectionMatrix, 1, GL_FALSE, m_projectionMat.Array()); } @@ -1992,6 +1991,12 @@ void CGL33Device::DestroyStaticBuffer(unsigned int bufferId) int CGL33Device::ComputeSphereVisibility(const Math::Vector ¢er, float radius) { + if (m_combinedMatrixOutdated) + { + m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = false; + } + Math::Matrix &m = m_combinedMatrix; Math::Vector vec[6]; @@ -2231,7 +2236,7 @@ CFramebuffer* CGL33Device::CreateFramebuffer(std::string name, const Framebuffer } auto framebuffer = MakeUnique(params); - framebuffer->Create(); + if (!framebuffer->Create()) return nullptr; CFramebuffer* framebufferPtr = framebuffer.get(); m_framebuffers[name] = std::move(framebuffer); diff --git a/src/graphics/opengl/gl33device.h b/src/graphics/opengl/gl33device.h index 9bb34e8e..8b27e8d4 100644 --- a/src/graphics/opengl/gl33device.h +++ b/src/graphics/opengl/gl33device.h @@ -205,6 +205,8 @@ private: Math::Matrix m_projectionMat; //! Combined world-view-projection matrix Math::Matrix m_combinedMatrix; + //! true means combined matrix is outdated + bool m_combinedMatrixOutdated = true; //! The current material Material m_material; diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 481f921e..cd617329 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -169,7 +169,7 @@ bool CGLDevice::Create() } // Extract OpenGL version - int glMajor, glMinor; + int glMajor = 1, glMinor = 1; int glVersion = GetOpenGLVersion(glMajor, glMinor); if (glVersion < 13) @@ -402,14 +402,14 @@ void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix) m_worldMat = matrix; UpdateModelviewMatrix(); - m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = true; } else if (type == TRANSFORM_VIEW) { m_viewMat = matrix; UpdateModelviewMatrix(); - m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = true; } else if (type == TRANSFORM_PROJECTION) { @@ -417,7 +417,7 @@ void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix) glMatrixMode(GL_PROJECTION); glLoadMatrixf(m_projectionMat.Array()); - m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = true; } else if (type == TRANSFORM_SHADOW) { @@ -1824,6 +1824,12 @@ void CGLDevice::DestroyStaticBuffer(unsigned int bufferId) int CGLDevice::ComputeSphereVisibility(const Math::Vector ¢er, float radius) { + if (m_combinedMatrixOutdated) + { + m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat); + m_combinedMatrixOutdated = false; + } + Math::Matrix &m = m_combinedMatrix; Math::Vector vec[6]; @@ -2066,7 +2072,7 @@ CFramebuffer* CGLDevice::CreateFramebuffer(std::string name, const FramebufferPa else return nullptr; - framebuffer->Create(); + if (!framebuffer->Create()) return nullptr; CFramebuffer* framebufferPtr = framebuffer.get(); m_framebuffers[name] = std::move(framebuffer); diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index 784a9713..a1e5c02f 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -216,6 +216,8 @@ private: Math::Matrix m_projectionMat; //! Combined world-view-projection matrix Math::Matrix m_combinedMatrix; + //! true means that combined matrix is outdated + bool m_combinedMatrixOutdated = true; //! The current material Material m_material; diff --git a/src/graphics/opengl/glframebuffer.cpp b/src/graphics/opengl/glframebuffer.cpp index b256e1d8..f3523db3 100644 --- a/src/graphics/opengl/glframebuffer.cpp +++ b/src/graphics/opengl/glframebuffer.cpp @@ -42,9 +42,9 @@ CGLFramebuffer::CGLFramebuffer(const FramebufferParams& params) m_samples = 0; } -void CGLFramebuffer::Create() +bool CGLFramebuffer::Create() { - if (m_fbo != 0) return; + if (m_fbo != 0) return false; m_width = m_params.width; m_height = m_params.height; @@ -145,11 +145,37 @@ void CGLFramebuffer::Create() GLuint result = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (result != GL_FRAMEBUFFER_COMPLETE) { - GetLogger()->Error("Framebuffer incomplete\n"); - assert(false); + GetLogger()->Error("Framebuffer incomplete: "); + + switch (result) + { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + GetLogger()->Error("attachment point incomplete"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + GetLogger()->Error("missing attachment"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + GetLogger()->Error("draw buffer has missing color attachments"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + GetLogger()->Error("read buffer has missing color attachments"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + GetLogger()->Error("unsupported attachment format"); + break; + } + + GetLogger()->Error("\n"); + + Destroy(); + + glBindFramebuffer(GL_FRAMEBUFFER, m_currentFBO); + return false; } glBindFramebuffer(GL_FRAMEBUFFER, m_currentFBO); + return true; } void CGLFramebuffer::Destroy() @@ -274,9 +300,9 @@ CGLFramebufferEXT::CGLFramebufferEXT(const FramebufferParams& params) m_samples = 0; } -void CGLFramebufferEXT::Create() +bool CGLFramebufferEXT::Create() { - if (m_fbo != 0) return; + if (m_fbo != 0) return false; m_width = m_params.width; m_height = m_params.height; @@ -362,7 +388,7 @@ void CGLFramebufferEXT::Create() else { glGenRenderbuffersEXT(1, &m_depthRenderbuffer); - glBindRenderbufferEXT(GL_RENDERBUFFER, m_depthRenderbuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthRenderbuffer); if (m_params.samples > 1) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_params.samples, depthFormat, m_params.width, m_params.height); @@ -377,11 +403,38 @@ void CGLFramebufferEXT::Create() GLuint result = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (result != GL_FRAMEBUFFER_COMPLETE_EXT) { - GetLogger()->Error("Framebuffer incomplete: %d\n", result); - assert(false); + GetLogger()->Error("Framebuffer incomplete: "); + + switch (result) + { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + GetLogger()->Error("attachment point incomplete"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + GetLogger()->Error("missing attachment"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + GetLogger()->Error("incompatible attachment dimensions"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + GetLogger()->Error("draw buffer has missing color attachments"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + GetLogger()->Error("read buffer has missing color attachments"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + GetLogger()->Error("unsupported attachment format"); + break; + } + + Destroy(); + + glBindFramebuffer(GL_FRAMEBUFFER, m_currentFBO); + return false; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_currentFBO); + return true; } void CGLFramebufferEXT::Destroy() diff --git a/src/graphics/opengl/glframebuffer.h b/src/graphics/opengl/glframebuffer.h index 0c83fdee..bfe52dfc 100644 --- a/src/graphics/opengl/glframebuffer.h +++ b/src/graphics/opengl/glframebuffer.h @@ -51,7 +51,7 @@ protected: public: CGLFramebuffer(const FramebufferParams& params); - void Create() override; + bool Create() override; void Destroy() override; @@ -101,7 +101,7 @@ protected: public: CGLFramebufferEXT(const FramebufferParams& params); - void Create() override; + bool Create() override; void Destroy() override; diff --git a/src/graphics/opengl/glutil.cpp b/src/graphics/opengl/glutil.cpp index 683c37bf..6c2952c3 100644 --- a/src/graphics/opengl/glutil.cpp +++ b/src/graphics/opengl/glutil.cpp @@ -292,6 +292,23 @@ std::string GetHardwareInfo(bool full) return result.str(); } +bool CheckGLErrors() +{ + GLint error = glGetError(); + bool result = false; + + while (error != GL_NO_ERROR) + { + GetLogger()->Error("OpenGL error: %d\n", error); + + result = true; + + error = glGetError(); + } + + return result; +} + GLenum TranslateGfxPrimitive(PrimitiveType type) { GLenum flag = 0; diff --git a/src/graphics/opengl/glutil.h b/src/graphics/opengl/glutil.h index cef820d5..cc26961b 100644 --- a/src/graphics/opengl/glutil.h +++ b/src/graphics/opengl/glutil.h @@ -68,6 +68,9 @@ bool AreExtensionsSupported(std::string list); //! Returns information about graphics card std::string GetHardwareInfo(bool full = false); +//! Checks for OpenGL errors +bool CheckGLErrors(); + //! Translate Gfx primitive type to OpenGL primitive type GLenum TranslateGfxPrimitive(PrimitiveType type); @@ -125,6 +128,12 @@ struct LightLocations GLint specular = -1; //! Attenuation GLint attenuation = -1; + //! Spot light direction + GLint spotDirection = -1; + //! Spot light exponent + GLint spotExponent = -1; + //! Spot light cutoff + GLint spotCutoff = -1; }; struct UniformLocations diff --git a/src/graphics/opengl/shaders/fragment_shader_21_perpixel.glsl b/src/graphics/opengl/shaders/fragment_shader_21_perpixel.glsl index 723fe055..0a6516d8 100644 --- a/src/graphics/opengl/shaders/fragment_shader_21_perpixel.glsl +++ b/src/graphics/opengl/shaders/fragment_shader_21_perpixel.glsl @@ -37,12 +37,16 @@ uniform float uni_ShadowColor; struct LightParams { bool Enabled; + int Type; vec4 Position; vec4 Ambient; vec4 Diffuse; vec4 Specular; float Shininess; vec3 Attenuation; + vec3 SpotDirection; + float SpotCutoff; + float SpotExponent; }; uniform vec4 uni_AmbientColor; diff --git a/src/graphics/opengl/shaders/fragment_shader_33_perpixel.glsl b/src/graphics/opengl/shaders/fragment_shader_33_perpixel.glsl index 6d8cb685..d184c3a4 100644 --- a/src/graphics/opengl/shaders/fragment_shader_33_perpixel.glsl +++ b/src/graphics/opengl/shaders/fragment_shader_33_perpixel.glsl @@ -80,12 +80,12 @@ void main() vec4 diffuse = vec4(0.0f); vec4 specular = vec4(0.0f); + vec3 normal = (gl_FrontFacing ? data.Normal : -data.Normal); + for(int i=0; i<8; i++) { if(uni_Light[i].Enabled) { - vec3 normal = (gl_FrontFacing ? data.Normal : -data.Normal); - vec3 lightDirection = vec3(0.0f); float atten; diff --git a/src/graphics/opengl/shaders/vertex_shader_21_pervertex.glsl b/src/graphics/opengl/shaders/vertex_shader_21_pervertex.glsl index b0bf8e67..c62d218d 100644 --- a/src/graphics/opengl/shaders/vertex_shader_21_pervertex.glsl +++ b/src/graphics/opengl/shaders/vertex_shader_21_pervertex.glsl @@ -28,17 +28,26 @@ uniform mat4 uni_NormalMatrix; struct LightParams { bool Enabled; + int Type; vec4 Position; vec4 Ambient; vec4 Diffuse; vec4 Specular; float Shininess; vec3 Attenuation; + vec3 SpotDirection; + float SpotCutoff; + float SpotExponent; }; -uniform vec4 uni_AmbientColor; -uniform vec4 uni_DiffuseColor; -uniform vec4 uni_SpecularColor; +struct Material +{ + vec4 ambient; + vec4 diffuse; + vec4 specular; +}; + +uniform Material uni_Material; uniform bool uni_LightingEnabled; uniform LightParams uni_Light[8]; @@ -70,35 +79,53 @@ void main() { if (uni_Light[i].Enabled) { - vec3 lightDirection = uni_Light[i].Position.xyz; + LightParams light = uni_Light[i]; + + vec3 lightDirection = light.Position.xyz; float atten = 1.0f; - // Point light - if (abs(uni_Light[i].Position.w) > 1e-3f) + if (light.Position.w != 0.0f) { - vec3 lightDirection = normalize(uni_Light[i].Position.xyz - position.xyz); - float dist = distance(uni_Light[i].Position.xyz, position.xyz); + float dist = distance(light.Position.xyz, position.xyz); - vec3 lightAtten = uni_Light[i].Attenuation; + float atten = 1.0f / (light.Attenuation.x + + light.Attenuation.y * dist + + light.Attenuation.z * dist * dist); - atten = 1.0f / (lightAtten.x - + lightAtten.y * dist - + lightAtten.z * dist * dist); + lightDirection = normalize(light.Position.xyz - position.xyz); + } + + float spot = 1.0f; + + if (light.SpotCutoff > 0.0f) + { + float cone = dot(light.SpotDirection, lightDirection); + + if (cone > light.SpotCutoff) + { + spot = pow(cone, light.SpotExponent); + } + else + { + spot = 0.0f; + } } vec3 reflectDirection = -reflect(lightDirection, normal); - ambient += uni_Light[i].Ambient; - diffuse += atten * clamp(dot(normal, lightDirection), 0.0f, 1.0f) * uni_Light[i].Diffuse; - specular += atten * clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f) * uni_Light[i].Specular; + float component = atten * spot; + float diffuseComponent = clamp(dot(normal, lightDirection), 0.0f, 1.0f); + float specularComponent = clamp(pow(dot(normal, lightDirection + reflectDirection), light.Shininess), 0.0f, 1.0f); + + ambient += component * light.Ambient * uni_Material.ambient; + diffuse += component * diffuseComponent * light.Diffuse * uni_Material.diffuse; + specular += component * specularComponent * light.Specular * uni_Material.specular; } } - vec4 result = uni_AmbientColor * ambient - + uni_DiffuseColor * diffuse - + uni_SpecularColor * specular; + vec4 result = ambient + diffuse + specular; - color = vec4(min(vec3(1.0f), result.rgb), 1.0f); + color = clamp(vec4(result.rgb, uni_Material.diffuse), 0.0f, 1.0f); } gl_Position = uni_ProjectionMatrix * eyeSpace; From 5fa3ed63b1619203a2128e38b9be0371d0494468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kapu=C5=9Bci=C5=84ski?= Date: Mon, 29 Feb 2016 16:51:18 +0100 Subject: [PATCH 3/3] Compilation fix --- src/graphics/opengl/gl21device.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp index 4b668753..448f65b4 100644 --- a/src/graphics/opengl/gl21device.cpp +++ b/src/graphics/opengl/gl21device.cpp @@ -38,6 +38,7 @@ #include #include +#include #include @@ -727,7 +728,7 @@ void CGL21Device::SetLight(int index, const Light &light) glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f); glUniform3f(loc.spotDirection, -light.direction.x, -light.direction.y, -light.direction.z); - glUniform1f(loc.spotCutoff, std::cosf(light.spotAngle)); + glUniform1f(loc.spotCutoff, std::cos(light.spotAngle)); glUniform1f(loc.spotExponent, light.spotIntensity); } }