Advertisement Jump to content
Sign in to follow this  
Solid_Spy

OpenGL OpenGl 3.3 Render To Texture Not Working

This topic is 1872 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have been trying to write my own Graphics Engine that renders a bunch of objects to a texture, then renders the texture on a quad to the screen. I don't know why it is not working. I have followed a lot of tutorials, and looked for help, but have come back empty handed. I will show you as much code as I can, however the engine is pretty huge, and I will show you the parts of the code that I feel are of concern.

 

OpenGl Render Function:

void OpenGl::Render()
{
        //This is the function that renders all the objects and swaps the buffers.
	StartRender();
	for(unsigned int i = 0; i < gameObjectList->size(); i++)
	{
		if(gameObjectList->at(i)->canLoadMeshes)
		{
			((std::vector<std::shared_ptr<RenderableGameObject>>*)gameObjectList)->at(i)->Render(camera->viewMatrix, camera->projectionMatrix);
		}
	}
	PostProcessing();

	EndRender();
}

OpenGl StartRender Function:

void OpenGl::StartRender()
{
        //This prepares OpenGl for rendering.
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glBindFramebuffer(GL_FRAMEBUFFER, motionBlurFrameBuffer);
	glViewport(0, 0, 1024, 768);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

OpenGl PostProcessing Function:

void OpenGl::PostProcessing()
{
        //This is the function that renders the texture to the screen.
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glUseProgram(renderToTexture_Shader.shader);
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glViewport(0, 0, 1024, 768);
	glBindVertexArray(rttVertexArray);
	unsigned int slot;

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, motionBlurTexture);
	glUniform1i(glGetUniformLocation(renderToTexture_Shader.shader, "color_Texture"), 0);

	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glEnableVertexAttribArray(2);
	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

And the function I use to create the FBO object:

bool OpenGl::SetUpOpenglObjects()
{
        //This supposedly huge (not really) function creates the FBO and binds the texture to attribute 4, since the other
        // 3 attributes are used by the vertices.
	glGenVertexArrays(1, &rttVertexArray);
	glBindVertexArray(rttVertexArray);
	unsigned int indices[] = 
	{
		0, 1, 2,
		0, 2, 3,
	};
	normalVertex testTriangle[4];
	testTriangle[0].x = -1.0f;
	testTriangle[0].y = -1.0f;
	testTriangle[0].z = 0.0f;
	testTriangle[0].u = 0.0f;
	testTriangle[0].v = 1.0f;
	testTriangle[0].nx = 0.0f;
	testTriangle[0].ny = 0.0f;
	testTriangle[0].nz = 1.0f;

	testTriangle[1].x = 1.0f;
	testTriangle[1].y = -1.0f;
	testTriangle[1].z = 0.0f;
	testTriangle[1].u = 1.0f;
	testTriangle[1].v = 1.0f;
	testTriangle[1].nx = 0.0f;
	testTriangle[1].ny = 0.0f;
	testTriangle[1].nz = 1.0f;

	testTriangle[2].x = 1.0f;
	testTriangle[2].y = 1.0f;
	testTriangle[2].z = 0.0f;
	testTriangle[2].u = 1.0f;
	testTriangle[2].v = 0.0f;
	testTriangle[2].nx = 0.0f;
	testTriangle[2].ny = 0.0f;
	testTriangle[2].nz = 1.0f;

	testTriangle[3].x = -1.0f;
	testTriangle[3].y = 1.0f;
	testTriangle[3].z = 0.0f;
	testTriangle[3].u = 0.0f;
	testTriangle[3].v = 0.0f;
	testTriangle[3].nx = 0.0f;
	testTriangle[3].ny = 0.0f;
	testTriangle[3].nz = 1.0f;

	glGenBuffers(1, &rttVertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, rttVertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(normalVertex), &testTriangle[0], GL_STATIC_DRAW);

	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glEnableVertexAttribArray(2);

	glBindBuffer(GL_ARRAY_BUFFER, rttVertexBuffer);
	glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(normalVertex), 0);

	glBindBuffer(GL_ARRAY_BUFFER, rttVertexBuffer);
	glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(normalVertex), (unsigned char*)NULL + (3 * sizeof(float)));

	glBindBuffer(GL_ARRAY_BUFFER, rttVertexBuffer);
	glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(normalVertex), (unsigned char*)NULL + (5 * sizeof(float)));

	glGenBuffers(1, &indexBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), &indices, GL_STATIC_DRAW);

	glGenFramebuffers(1, &motionBlurFrameBuffer);
	glBindFramebuffer(GL_FRAMEBUFFER, motionBlurFrameBuffer);
	glActiveTexture(GL_TEXTURE0);
	glGenTextures(1, &motionBlurTexture);
	glBindTexture(GL_TEXTURE_2D, motionBlurTexture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	//glGenerateMipmap(GL_TEXTURE_2D);
	glGenRenderbuffers(1, &depthBuffer);
	glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 128, 128);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
	glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, motionBlurTexture, 0);
	GLenum dBuffers[1] = {GL_COLOR_ATTACHMENT4};
	glDrawBuffers(1, dBuffers);

	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		MessageBox(0, "Ok, Something Is Seriously Wrong Here!", "ErroR", MB_OK);
	}

	glBindFramebuffer(GL_FRAMEBUFFER, motionBlurFrameBuffer);
	glViewport(0, 0, 1024, 768);
        //Not Important:
	/*Model * model2 = new Model();
	model2->name = "Letter_Model";
	model2->modelMaterials = new Material[1];
	model2->modelMaterials->textures = new std::shared_ptr<Texture>[1];
	model2->modelMaterials[0].shader1 = &color_Shader;

	colorShaderMesh * testTriangle2 = new colorShaderMesh();
	testTriangle2->meshName = "Text_Mesh.txt";
	model2->mesh = testTriangle2;

	modelList->push_back(model2);
	meshList->push_back(testTriangle2);*/
	return true;
}

And Here are the fragment shaders, I use some for rendering to the texture, and others for rendering the texture to the screen:

Texture Shader:

#version 400

in vec2 outUV;

layout(location = 4) out vec4 outColor;

uniform sampler2D color_Texture;

void main()
{
	vec4 color;
	color = texture(color_Texture, outUV);

	outColor = color;
	if(outColor.a < 1.0f)
	{
		discard;
	}
}

Screen Shader:

#version 400

in vec2 outUV;

out vec4 outColor;

uniform sampler2D color_Texture

void main()
{
	vec4 color;
	color = texture(color_Texture, outUV);
	color.r = 1.0f

	outColor = color;
}

If anything doesn't quite look right, or if you need me to post more code, just let me know. I know this may look complicated, but idk any other way to explain it. whenever I render normally, without the FBO, it works fine, but when I render with the FBO, I get a black screen. Can anyone help me out here? (I think It might have to do with the uniform texture).

Edited by Solid_Spy

Share this post


Link to post
Share on other sites
Advertisement

Hello, I figured out what I did wrong.

 

Apparently I was supposed to add a semicolon to the Screen Shader, and also, I needed to clear the VertexAttributeArray buffers, by disabling them. All I did was add GlDisableVertexAttribArray(x); before binding the vertexArray for the FBO.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!