Nothing drawn to depth buffer

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. :slight_smile:

Have you used glGetError() to check that nothing is raising an error?

Yes I tried that too, no error.

Is it possible that the vertex shader I use isn’t properly transforming the coordinates? If I render an on screen texture using a different shader with color output it appears on the depth map texture for some reason, but other model objects don’t. On the other hand I can render the scene using the light space matrix and light space shader just fine, it just doesn’t appear on the depth map.

The vertex shader is fine, but we have no way of knowing whether your matrices are correct.

If rendering the scene using the light-space matrix results in the scene being depth sorted correctly, either everything happens to be drawn from back to front, or your depth buffer and depth tests are working.

I note that your glReadPixels() call is using WIDTH and HEIGHT rather than SHADOW_WIDTH and SHADOW_HEIGHT. Reading beyond the framebuffer boundaries won’t generate an error, but the results are undefined (the corresponding portions of the output buffer may be populated with garbage data or left unchanged).

Could that happen randomly like that, that it gets drawn from back to front? I make the call glEnable(GL_DEPTH_TEST), so shouldn’t that make it sort correctly?

Yes I noticed actually that I put WIDTH and HEIGHT instead of SHADOW_WIDTH and SHADOW_HEIGHT in the glReadPixels call, although correcting that didn’t really make a difference as you noted.

Yes, but it would also result in the depth buffer containing the correct values. So that eliminates some possible causes (e.g. the transformation); whatever is going wrong when rendering to the FBO is caused by factors which differ between the two cases rather than by factors they have in common.

Ok I solved the problem, but I have absolutely no idea WHY it solved the problem. instead of multiplying lightProjection and lightView in the program and send a complete lightSpaceMatrix to the shader, I sent lightView And lightProjection seperately, and multiplied them in the shader instead. Why this worked I have to idea, but I’m glad the problem is solved, thanks a lot!