diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj b/Escape-the-Dawn/Escape-the-Dawn.vcxproj
index f34b012..8a6c3db 100644
--- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj
+++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj
@@ -169,6 +169,10 @@
+
+
+
+
diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters
index 2ce6bb5..da3ea10 100644
--- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters
+++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters
@@ -164,6 +164,18 @@
Shaders
+
+ Shaders
+
+
+ Shaders
+
+
+ Shaders
+
+
+ Shaders
+
diff --git a/Escape-the-Dawn/GameWorld.cpp b/Escape-the-Dawn/GameWorld.cpp
index 3844113..c19fe46 100644
--- a/Escape-the-Dawn/GameWorld.cpp
+++ b/Escape-the-Dawn/GameWorld.cpp
@@ -19,6 +19,18 @@ void GameWorld::Initialize()
std::shared_ptr camera;
EntityID ent;
+ // Camera
+ ent = CreateEntity();
+ SetProperty(ent, "Name", std::string("Camera"));
+ transform = AddComponent(ent, "Transform");
+ AddComponent(ent, "Input");
+ transform->Position = glm::vec3(0.f, 2.f, 10.f);
+ camera = AddComponent(ent, "Camera");
+ camera->FOV = 45.f;
+ camera->FarClip = 1000.f;
+ camera->NearClip = 0.01f;
+ transform->Orientation = glm::angleAxis(glm::radians(25.0f),glm::vec3(1,0,0));
+
// Fucking lights
ent = CreateEntity();
transform = AddComponent(ent, "Transform");
@@ -83,6 +95,8 @@ void GameWorld::Initialize()
transform->Position = glm::vec3(10.f, 0.f, 0.f);
model = AddComponent(ent, "Model");
model->ModelFile = "ship.obj";
+
+ // Camera
}
void GameWorld::Update(double dt)
diff --git a/Escape-the-Dawn/Model.cpp b/Escape-the-Dawn/Model.cpp
index 4ae2126..b6eacf6 100644
--- a/Escape-the-Dawn/Model.cpp
+++ b/Escape-the-Dawn/Model.cpp
@@ -13,6 +13,10 @@ Model::Model(OBJ &obj)
TextureGroup* currentTexGroup = nullptr;
int index = 0;
for (auto face : obj.Faces) {
+ if (face.Material == nullptr) {
+ LOG_ERROR("Missing material for .obj file \"%s\"", obj.Path().string().c_str());
+ return;
+ }
// New material
if (face.Material != currentMaterial) {
currentMaterial = face.Material;
@@ -49,7 +53,9 @@ Model::Model(OBJ &obj)
}
}
- CreateBuffers(Vertices, Normals, TextureCoords);
+ if (Vertices.size() > 0) {
+ CreateBuffers(Vertices, Normals, TextureCoords);
+ }
}
bool Model::Loadobj(const char* path, std::vector & out_vertices, std::vector &out_normals, std::vector & out_TextureCoords)
@@ -186,27 +192,39 @@ bool Model::Loadobj(const char* path, std::vector & out_vertices, st
}
-void Model::CreateBuffers( std::vector _Vertices, std::vector _Normals, std::vector_TextureCoords)
+void Model::CreateBuffers( std::vector vertices, std::vector normals, std::vectortextureCoords)
{
LOG_INFO("Generating VertexBuffer");
glGenBuffers(1, &VertexBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, _Vertices.size() * sizeof(glm::vec3), &_Vertices[0], GL_STATIC_DRAW);
- GLERROR("GLEW: BufferFail, VertexBuffer");
+ if (vertices.size() > 0) {
+ glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
+ GLERROR("GLEW: BufferFail, VertexBuffer");
+ } else {
+ LOG_WARNING("Created empty vertex buffer!");
+ }
LOG_INFO("Generating NormalBuffer");
glGenBuffers(1, &NormalBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, NormalBuffer);
- glBufferData(GL_ARRAY_BUFFER, _Normals.size() * sizeof(glm::vec3), &_Normals[0], GL_STATIC_DRAW);
- GLERROR("GLEW: BufferFail, NormalBuffer");
+ if (normals.size() > 0) {
+ glBindBuffer(GL_ARRAY_BUFFER, NormalBuffer);
+ glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
+ GLERROR("GLEW: BufferFail, NormalBuffer");
+ } else {
+ LOG_WARNING("Created empty normal buffer!");
+ }
LOG_INFO("Generating textureCoordBuffer");
glGenBuffers(1, &TextureCoordBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, TextureCoordBuffer);
- glBufferData(GL_ARRAY_BUFFER, _TextureCoords.size() * sizeof(glm::vec2), &_TextureCoords[0], GL_STATIC_DRAW);
- GLERROR("GLEW: BufferFail, TextureCoordBuffer");
+ if (textureCoords.size() > 0) {
+ glBindBuffer(GL_ARRAY_BUFFER, TextureCoordBuffer);
+ glBufferData(GL_ARRAY_BUFFER, textureCoords.size() * sizeof(glm::vec2), &textureCoords[0], GL_STATIC_DRAW);
+ GLERROR("GLEW: BufferFail, TextureCoordBuffer");
+ } else {
+ LOG_WARNING("Created empty texture coordinate buffer!");
+ }
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
diff --git a/Escape-the-Dawn/OBJ.cpp b/Escape-the-Dawn/OBJ.cpp
index 4615466..df3ece7 100644
--- a/Escape-the-Dawn/OBJ.cpp
+++ b/Escape-the-Dawn/OBJ.cpp
@@ -1,10 +1,5 @@
#include "OBJ.h"
-OBJ::OBJ()
-{
- m_CurrentMaterial = nullptr;
-}
-
bool OBJ::LoadFromFile(std::string filename)
{
m_Path = boost::filesystem::path(filename);
diff --git a/Escape-the-Dawn/OBJ.h b/Escape-the-Dawn/OBJ.h
index aa157fa..9aeed54 100644
--- a/Escape-the-Dawn/OBJ.h
+++ b/Escape-the-Dawn/OBJ.h
@@ -38,12 +38,13 @@ public:
struct Face
{
+ Face() : Material(nullptr) { }
std::vector Definitions;
MaterialInfo* Material;
};
- OBJ();
- OBJ(std::string filename) { LoadFromFile(filename); }
+ OBJ() : m_CurrentMaterial(nullptr) { }
+ OBJ(std::string filename) : m_CurrentMaterial(nullptr) { LoadFromFile(filename); }
std::vector> Vertices;
std::vector> Normals;
@@ -52,6 +53,7 @@ public:
std::map Materials;
bool LoadFromFile(std::string filename);
+ boost::filesystem::path Path() const { return m_Path; }
private:
boost::filesystem::path m_Path;
diff --git a/Escape-the-Dawn/Renderer.cpp b/Escape-the-Dawn/Renderer.cpp
index 84f1273..bffbaae 100644
--- a/Escape-the-Dawn/Renderer.cpp
+++ b/Escape-the-Dawn/Renderer.cpp
@@ -5,6 +5,10 @@ Renderer::Renderer()
m_VSync = false;
m_DrawNormals = false;
m_DrawWireframe = false;
+
+ m_SunPosition = glm::vec3(0, 10, 10);
+ m_SunTarget = glm::vec3(0);
+ m_SunProjection = glm::ortho(-20, 20, -20, 20, -10, 20);
}
void Renderer::Initialize()
@@ -55,49 +59,178 @@ void Renderer::Initialize()
LoadContent();
}
+void Renderer::LoadContent()
+{
+ auto standardVS = std::shared_ptr(new VertexShader("Shaders/Vertex.glsl"));
+ auto standardFS = std::shared_ptr(new FragmentShader("Shaders/Fragment.glsl"));
+
+ m_ShaderProgram.AddShader(standardVS);
+ m_ShaderProgram.AddShader(standardFS);
+ m_ShaderProgram.Compile();
+ m_ShaderProgram.Link();
+
+ m_ShaderProgramNormals.AddShader(std::shared_ptr(new GeometryShader("Shaders/Normals.geo.glsl")));
+ m_ShaderProgramNormals.AddShader(standardVS);
+ 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();
+ m_ShaderProgramShadowsDrawDepth.Link();
+
+ m_ScreenQuad = CreateQuad();
+ CreateShadowMap(2048*2);
+}
+
+void Renderer::CreateShadowMap(int resolution)
+{
+ glGenFramebuffers(1, &m_ShadowFrameBuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_ShadowFrameBuffer);
+
+ // Depth texture
+ glGenTextures(1, &m_ShadowDepthTexture);
+ glBindTexture(GL_TEXTURE_2D, m_ShadowDepthTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, resolution, resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+
+ //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
+ //glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY );
+
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_ShadowDepthTexture, 0);
+ glDrawBuffer(GL_NONE);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ LOG_ERROR("Framebuffer incomplete!");
+ return;
+ }
+}
void Renderer::Draw(double dt)
{
+ DrawShadowMap();
+ DrawScene();
+
+ DrawDebugShadowMap();
+
+ ModelsToRender.clear();
+ glfwSwapBuffers(m_Window);
+}
+
+void Renderer::DrawScene()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, WIDTH, HEIGHT);
+
glClear(GL_COLOR_BUFFER_BIT | 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::mat4 depthCamera = m_SunProjection * depthViewMatrix;
+ glm::mat4 depthMVP = depthCamera;
+ 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 depthBiasMVP = biasMatrix * depthMVP;
+
m_ShaderProgram.Bind();
- glPolygonMode(GL_FRONT_AND_BACK, m_DrawWireframe ? GL_LINE : GL_FILL);
- DrawModels();
-
+ glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthBiasMVP));
+ glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "position"), 3, Light_position.data());
+ glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "specular"), 3, Light_specular.data());
+ glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "diffuse"), 3, Light_diffuse.data());
+ glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "constantAttenuation"), 3, Light_constantAttenuation.data());
+ glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "linearAttenuation"), 3, Light_linearAttenuation.data());
+ glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "quadraticAttenuation"), 3, Light_quadraticAttenuation.data());
+ glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "spotExponent"), 3, 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);
+
#ifdef DEBUG
- // Debug draw normals
+ // Debug draw model normals
if (m_DrawNormals) {
m_ShaderProgramNormals.Bind();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- DrawModels();
+ DrawModels(m_ShaderProgramNormals);
}
#endif
-
- ModelsToRender.clear();
-
-#ifdef DEBUG
- // Debug draw normals
- if (m_DrawNormals) {
- m_ShaderProgramNormals.Bind();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- DrawModels();
- }
-#endif
-
- ModelsToRender.clear();
-
- glfwSwapBuffers(m_Window);
}
-void Renderer::DrawModels()
+void Renderer::DrawShadowMap()
+{
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_ShadowFrameBuffer);
+ glViewport(0, 0, 2048*2, 2048*2);
+
+ 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::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);
+ for (int i = 0; i < ModelsToRender.size(); i++)
+ {
+ ModelData* modelData = ModelsToRender.at(i);
+ auto model = modelData->model;
+
+ MVP = depthCamera * modelData->ModelMatrix;
+ glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramShadows.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
+
+ glBindVertexArray(model->VAO);
+ for (auto texGroup : model->TextureGroups) {
+ glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, texGroup.EndIndex - texGroup.StartIndex + 1);
+ }
+ }
+}
+
+void Renderer::DrawDebugShadowMap()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, 200*(16.f/9.f), 200);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+ //glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ m_ShaderProgramShadowsDrawDepth.Bind();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_ShadowDepthTexture);
+ glBindVertexArray(m_ScreenQuad);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+void Renderer::DrawModels(ShaderProgram &shader)
{
glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix();
@@ -108,23 +241,14 @@ void Renderer::DrawModels()
auto model = modelData->model;
MVP = cameraMatrix * modelData->ModelMatrix;
- glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
- glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "model"), 1, GL_FALSE, glm::value_ptr(modelData->ModelMatrix));
- glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "view"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix()));
- glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "position"), 3, Light_position.data());
- glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "specular"), 3, Light_specular.data());
- glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "diffuse"), 3, Light_diffuse.data());
- glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "constantAttenuation"), 3, Light_constantAttenuation.data());
- glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "linearAttenuation"), 3, Light_linearAttenuation.data());
- glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "quadraticAttenuation"), 3, Light_quadraticAttenuation.data());
- glUniform1fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "spotExponent"), 3, Light_spotExponent.data());
-
-
+ glUniformMatrix4fv(glGetUniformLocation(shader.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
+ glUniformMatrix4fv(glGetUniformLocation(shader.GetHandle(), "model"), 1, GL_FALSE, glm::value_ptr(modelData->ModelMatrix));
+ glUniformMatrix4fv(glGetUniformLocation(shader.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->texture);
- glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, (texGroup.EndIndex - texGroup.StartIndex + 1) * abs(sin(glfwGetTime())));
+ glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, texGroup.EndIndex - texGroup.StartIndex + 1);
}
}
}
@@ -173,23 +297,43 @@ void Renderer::AddPointLightToDraw(
}
-
-void Renderer::LoadContent()
+GLuint Renderer::CreateQuad()
{
- auto standardVS = std::shared_ptr(new VertexShader("Shaders/Vertex.glsl"));
- auto standardFS = std::shared_ptr(new FragmentShader("Shaders/Fragment.glsl"));
+ float quadVertices[] = {
+ -1.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f,
- auto normalsGS = std::shared_ptr(new GeometryShader("Shaders/Normals.geo.glsl"));
- auto normalsFS = std::shared_ptr(new FragmentShader("Shaders/Normals.frag.glsl"));
+ -1.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ };
+ float quadTexCoords[] = {
+ 0.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
- m_ShaderProgram.AddShader(standardVS);
- m_ShaderProgram.AddShader(standardFS);
- m_ShaderProgram.Compile();
- m_ShaderProgram.Link();
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+ };
+ GLuint vbo[2], vao;
+ glGenBuffers(2, vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+ glBufferData(GL_ARRAY_BUFFER, 3 * 6 * sizeof(float), quadVertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
+ glBufferData(GL_ARRAY_BUFFER, 2 * 6 * sizeof(float), quadTexCoords, GL_STATIC_DRAW);
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(2);
- m_ShaderProgramNormals.AddShader(normalsGS);
- m_ShaderProgramNormals.AddShader(standardVS);
- m_ShaderProgramNormals.AddShader(normalsFS);
- m_ShaderProgramNormals.Compile();
- m_ShaderProgramNormals.Link();
-}
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ return vao;
+}
\ No newline at end of file
diff --git a/Escape-the-Dawn/Renderer.h b/Escape-the-Dawn/Renderer.h
index b75f6bd..7fcca0d 100644
--- a/Escape-the-Dawn/Renderer.h
+++ b/Escape-the-Dawn/Renderer.h
@@ -83,12 +83,27 @@ private:
bool m_DrawNormals;
bool m_DrawWireframe;
+ glm::vec3 m_SunPosition;
+ glm::vec3 m_SunTarget;
+ glm::mat4 m_SunProjection;
+
+ GLuint m_ScreenQuad;
+ GLuint m_ShadowFrameBuffer;
+ GLuint m_ShadowDepthTexture;
+
std::shared_ptr m_Camera;
ShaderProgram m_ShaderProgram;
ShaderProgram m_ShaderProgramNormals;
+ ShaderProgram m_ShaderProgramShadows;
+ ShaderProgram m_ShaderProgramShadowsDrawDepth;
- void DrawModels();
+ void DrawScene();
+ void DrawModels(ShaderProgram &shader);
+ void DrawShadowMap();
+ void CreateShadowMap(int resolution);
+ GLuint CreateQuad();
+ void DrawDebugShadowMap();
};
diff --git a/Escape-the-Dawn/Shaders/Fragment.glsl b/Escape-the-Dawn/Shaders/Fragment.glsl
index d4e1733..a852e1b 100644
--- a/Escape-the-Dawn/Shaders/Fragment.glsl
+++ b/Escape-the-Dawn/Shaders/Fragment.glsl
@@ -3,7 +3,8 @@
uniform mat4 model;
uniform mat4 view;
-layout(binding=0) uniform sampler2D texture;
+layout(binding=0) uniform sampler2D texture0;
+layout(binding=1) uniform sampler2D shadowMap;
const int numberOfLights = 3;
@@ -15,20 +16,21 @@ uniform float linearAttenuation[numberOfLights];
uniform float quadraticAttenuation[numberOfLights];
uniform float spotExponent[numberOfLights];
- in VertexData {
+in VertexData {
vec3 Position;
vec3 Normal;
vec2 TextureCoord;
+ vec3 ShadowCoord;
} Input;
-vec3 scene_ambient = vec3(0.5, 0.5, 0.5);
+vec3 scene_ambient = vec3(0.2);
out vec4 fragmentColor;
void main() {
// Texture
- vec4 texel = texture2D(texture, Input.TextureCoord);
+ vec4 texel = texture2D(texture0, Input.TextureCoord);
//vec4 texel = (blend.x * texel0) + (blend.y * texel1) + (blend.z * texel2);
//
@@ -43,48 +45,59 @@ void main() {
vec3 Is;
vec3 Id;
- vec3 totalLighting = La * Ka;
+ // 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 bias = 0.003;
+ float visibility = 1.0;
+ vec4 shadowMapValue = texture(shadowMap, Input.ShadowCoord.xy);
+ if (shadowMapValue.z < Input.ShadowCoord.z - bias) {
+ visibility = 0.5;
+ }
+
+ vec3 totalLighting = La * Ka * visibility;
float attenuation;
for(int i = 0; i < numberOfLights; i++)
{
- // Light
- //vec3 lightPosition = vec3(0, 0, 2);
- vec3 Ls = specular[i]; // Specular light
- vec3 Ld = diffuse[i]; // Diffuse light
+ // 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);
- 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);
+ 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]);
+ 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);
+ // Diffuse light
+ float dotProd = dot(surfaceToLight, surfaceNormal);
+ dotProd = max(dotProd, 0.0);
- Id = Ld * Kd * abs(dotProd) * attenuation;
+ 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
+ // 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;
+ Is = attenuation * Ls * Ks * specularFactor;
- totalLighting = totalLighting + Id + Is;
+ totalLighting = totalLighting + Id + Is;
}
+
fragmentColor = vec4(totalLighting, 1.0) * texel;
diff --git a/Escape-the-Dawn/Shaders/ShadowMap.frag.glsl b/Escape-the-Dawn/Shaders/ShadowMap.frag.glsl
new file mode 100644
index 0000000..adae8d5
--- /dev/null
+++ b/Escape-the-Dawn/Shaders/ShadowMap.frag.glsl
@@ -0,0 +1,9 @@
+#version 430
+
+uniform mat4 MVP;
+
+layout(location = 0) out float FragmentDepth;
+
+void main() {
+ FragmentDepth = gl_FragCoord.z;
+}
\ No newline at end of file
diff --git a/Escape-the-Dawn/Shaders/ShadowMap.vert.glsl b/Escape-the-Dawn/Shaders/ShadowMap.vert.glsl
new file mode 100644
index 0000000..042411c
--- /dev/null
+++ b/Escape-the-Dawn/Shaders/ShadowMap.vert.glsl
@@ -0,0 +1,22 @@
+#version 430
+
+uniform mat4 MVP;
+
+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;
+} Output;
+
+void main()
+{
+ gl_Position = MVP * vec4(Position, 1.0);
+
+ Output.Position = Position;
+ Output.Normal = Normal;
+ Output.TextureCoord = TextureCoord;
+}
\ No newline at end of file
diff --git a/Escape-the-Dawn/Shaders/Vertex.glsl b/Escape-the-Dawn/Shaders/Vertex.glsl
index 042411c..2b5b0e5 100644
--- a/Escape-the-Dawn/Shaders/Vertex.glsl
+++ b/Escape-the-Dawn/Shaders/Vertex.glsl
@@ -1,6 +1,7 @@
#version 430
uniform mat4 MVP;
+uniform mat4 DepthMVP;
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
@@ -10,6 +11,7 @@ out VertexData {
vec3 Position;
vec3 Normal;
vec2 TextureCoord;
+ vec3 ShadowCoord;
} Output;
void main()
@@ -19,4 +21,5 @@ void main()
Output.Position = Position;
Output.Normal = Normal;
Output.TextureCoord = TextureCoord;
+ Output.ShadowCoord = vec3(DepthMVP * vec4(Position, 1.0));
}
\ No newline at end of file
diff --git a/Escape-the-Dawn/Shaders/VisualizeDepth.frag.glsl b/Escape-the-Dawn/Shaders/VisualizeDepth.frag.glsl
new file mode 100644
index 0000000..eef8e6e
--- /dev/null
+++ b/Escape-the-Dawn/Shaders/VisualizeDepth.frag.glsl
@@ -0,0 +1,24 @@
+#version 430
+
+layout(binding = 0) uniform sampler2D DepthTexture;
+
+in VertexData {
+ vec3 Position;
+ vec2 TextureCoord;
+} Input;
+
+out vec4 FragmentColor;
+
+float LinearizeDepth(float z)
+{
+ float n = 0.1; // camera z near
+ float f = 10.0; // camera z far
+ return (2.0 * n) / (f + n - z * (f - n));
+}
+
+void main() {
+ float z = texture(DepthTexture, Input.TextureCoord).x;
+ vec4 color = vec4(z, z, z, 0);
+
+ FragmentColor = color;
+}
\ No newline at end of file
diff --git a/Escape-the-Dawn/Shaders/VisualizeDepth.vert.glsl b/Escape-the-Dawn/Shaders/VisualizeDepth.vert.glsl
new file mode 100644
index 0000000..32e6205
--- /dev/null
+++ b/Escape-the-Dawn/Shaders/VisualizeDepth.vert.glsl
@@ -0,0 +1,17 @@
+#version 430
+
+layout(location = 0) in vec3 Position;
+layout(location = 2) in vec2 TextureCoord;
+
+out VertexData {
+ vec3 Position;
+ vec2 TextureCoord;
+} Output;
+
+void main()
+{
+ gl_Position = vec4(Position, 1.0);
+
+ Output.Position = Position;
+ Output.TextureCoord = TextureCoord;
+}
\ No newline at end of file
diff --git a/Escape-the-Dawn/plane.mtl b/Escape-the-Dawn/plane.mtl
index 750fa40..2961836 100644
--- a/Escape-the-Dawn/plane.mtl
+++ b/Escape-the-Dawn/plane.mtl
@@ -1,7 +1,7 @@
-# Blender MTL File: 'obstaclesandstuff.blend'
+# Blender MTL File: 'None'
# Material Count: 1
-newmtl Material.004
+newmtl Material.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000