Hi there, I’m new here and also fairly new to OpenGL, and I didn’t know whether my question fitted better in the beginner section or the advanced section, but upon looking at related questions here I decided to put it here.
Anyways, I’m building a game using OpenGL for a school project and I’m trying to implement shadow mapping. I create a frame buffer object and bind a texture to it, like so:
GLuint depthMapFBO;
GLuint depthMap;
glm::mat4 lightSpaceMatrix;
glUniform1i(glGetUniformLocation(shaderProgram.program, "shadowMap"), 7);
glGenFramebuffers(1, &depthMapFBO);
//glActiveTexture(GL_TEXTURE2);
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
//shaderProgram.Use();
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
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_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
GLfloat border_color[4] = { 1, 1, 1, 1 };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
GLenum status;
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE:
std::cout << "FrameBuffer generated successfully" << std::endl;
break;
default:
std::cout << "Failed to generate framebuffer" << std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glCheckFramebufferStatus returns GL_FRAMEBUFFER_COMPLETE.
And then I clear the depth buffer, configure a transformation matrix and render the scene using the light space matrix and light space shader like this:
ConfigureShaderAndMatrices(
lightSpaceShader,
lightSpaceMatrix,
glm::vec3(-1.0f, -1.0f, -2.0f),
glm::vec3(game->camera->position.x, game->camera->position.y, 0));
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClearDepth(1.0f);
glClear(GL_DEPTH_BUFFER_BIT);
RenderScene(lightSpaceShader, animationShader, onScreenShader, game->coloredCube);
/*if (*game->state == PLAY)
{
GLfloat* pixels = new GLfloat[WIDTH * HEIGHT];
glReadPixels(
0,
0,
WIDTH,
HEIGHT,
GL_DEPTH_COMPONENT,
GL_FLOAT,
pixels);
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
for (int i = 0; i < HEIGHT; ++i)
{
for (int j = 0; j < WIDTH; ++j)
{
float pixel = pixels[(WIDTH * i) + j];
if (pixel == 1.0f)
count1++;
else if(pixel < 1.0f && pixel > 0.0f)
count2++;
else if (pixel < 0.0f)
count3++;
else if (pixel > 1.0f)
count4++;
}
}
std::cout << count1 << std::endl;
std::cout << count2 << std::endl;
std::cout << count3 << std::endl;
std::cout << count4 << std::endl;
delete pixels;
}*/
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, WIDTH, HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaderProgram.Use();
//lightSpaceShader.Use();
glUniformMatrix4fv(glGetUniformLocation(shaderProgram.program, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, depthMap);
void ConfigureShaderAndMatrices(Shader &shader, glm::mat4 &lightSpaceMatrix, glm::vec3 &lightDir, glm::vec3 &cameraPos)
{
GLfloat near_plane = 10.0f, far_plane = 300.0f;
glm::mat4 lightProjection = glm::ortho(-40.0f, 40.0f, -40.0f, 40.0f, near_plane, far_plane);
glm::normalize(lightDir);
glm::vec3 lightPos = cameraPos + glm::vec3(-lightDir.x * 40.0f, -lightDir.y * 40.0f, -lightDir.z * 40.0f);
glm::mat4 lightView = CalcLookAtMatrix(lightPos, lightDir);
lightSpaceMatrix = lightProjection * lightView;
shader.Use();
glUniformMatrix4fv(glGetUniformLocation(shader.program, "LightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
}
As you can see above I use glReadPixels() to check the data of the depth buffer, and the problem is that about half the values are exactly 1.0, and the rest are less than 0.0 (probably undefined), and I have absolutely no idea why that is. If I try to render the scene using the lightspace matrix and the shader, the scene renders fine, so that isn’t the problem.
Here is the shader I use for the light space render:
// Vertex shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoords;
uniform mat4 lightSpaceMatrix;
uniform mat4 model;
void main()
{
gl_Position = lightSpaceMatrix * model * vec4(position, 1.0f);
}
//Fragment shader
#version 330 core
//out vec4 color;
//out float color;
void main()
{
// Used for testing purposes, otherwise commented out
//gl_FragDepth = gl_FragCoord.z;
//color = vec4(gl_FragCoord.z, gl_FragCoord.z, gl_FragCoord.z, 1.0f);
//color = gl_FragCoord.z;
}
Any ideas what might be the problem? Thankful for replies.