Skip to main content
gamedev.net
🔒 Locked

Framebuffer object problem...

Started by iNsAn1tY 4 replies 3.1k views
Original Post
iNsAn1tY
iNsAn1tY
Evening all. Got a bit of a problem with EXT_framebuffer_object. My code's below. I've stepped through it exhaustively, and I can't find anything wrong with it. However, this is the first time I've used FBOs, and I might have missed out something trivial. I have put in error checking code (it's not in at the moment), and I always get back GL_FRAMEBUFFER_COMPLETE_EXT after the FBO setup, indicating that everything should be OK. However, both of the textures appear completely white, as if no write has occurred. They stay white even when the clear colour isn't white. I'm at something of a loss. Any help will be greatly appreciated. If any more of my program is required, I can post it. I'm using GLee for the extension support, btw.

void RenderOrigin(float fScale = 1.0f)
{
	
	glBegin(GL_LINES);
		
		glColor3f(1.0f, 0.0f, 0.0f);
		
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(fScale, 0.0f, 0.0f);
		
		glColor3f(0.0f, 1.0f, 0.0f);
		
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(0.0f, fScale, 0.0f);
		
		glColor3f(0.0f, 0.0f, 1.0f);
		
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(0.0f, 0.0f, fScale);
		
	glEnd();
	
}

void RenderScene(void)
{
	
	// A very, very basic scene...
	
	RenderOrigin(16.0f);
	
	glColor3f(1.0f, 1.0f, 0.0f);
	
	glutSolidSphere(8.0, 20, 20);
	
}

void Render(void)
{
	
	GLuint tempTextures[2];
	
	glGenTextures(2, tempTextures);
	
	GLuint tempFramebuffer;
	GLuint tempRenderbuffer;
	
	glGenFramebuffersEXT(1, &tempFramebuffer);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tempFramebuffer);
	
	glGenRenderbuffersEXT(1, &tempRenderbuffer);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tempRenderbuffer);
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 512, 512);
	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, tempRenderbuffer);
	
	// ----------------------------------------------
	// Reflection texture setup...
	// ----------------------------------------------
	
	glBindTexture(GL_TEXTURE_2D, tempTextures[0]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tempTextures[0], 0);
	
	glDrawBuffer(GL_FALSE);
	glReadBuffer(GL_FALSE);
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tempFramebuffer);
	
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
	
	glViewport(0, 0, 512, 512);
	
	// ----------------------------------------------
	// Reflection texture rendering...
	// ----------------------------------------------
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// <temp>
	gluPerspective(60.0, 1.0, 0.1f, 1000.0f);
	// </temp>
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	// <temp>
	gluLookAt(100.0f, 100.0f, 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
	// </temp>
	
	glScalef(0.0f, -1.0f, 0.0f);
	
	RenderScene();
	
	// ----------------------------------------------
	// Underwater texture setup...
	// ----------------------------------------------
	
	glBindTexture(GL_TEXTURE_2D, tempTextures[1]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tempTextures[1], 0);
	
	glDrawBuffer(GL_FALSE);
	glReadBuffer(GL_FALSE);
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tempFramebuffer);
	
	glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
	
	glViewport(0, 0, 512, 512);
	
	// ----------------------------------------------
	// Underwater texture rendering...
	// ----------------------------------------------
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// <temp>
	gluPerspective(60.0, 1.0, 0.1f, 1000.0f);
	// </temp>
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	// <temp>
	gluLookAt(100.0f, 100.0f, 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
	// </temp>
	
	RenderScene();
	
	// ----------------------------------------------
	// Final scene rendering setup...
	// ----------------------------------------------
	
	// Back to the main surface...
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	
	glDrawBuffer(GL_TRUE);
	glReadBuffer(GL_TRUE);
	
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glViewport(0, 0, g_clientRect.right, g_clientRect.bottom);
	
	// ----------------------------------------------
	// Temporary texture debug rendering...
	// ----------------------------------------------
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// <temp>
	glOrtho(0, (double)g_clientRect.right, 0.0, (double)g_clientRect.bottom, -1.0, 1.0);
	// </temp>
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	glTranslatef(16.0f, 16.0f, 0.0f);
	
	glBindTexture(GL_TEXTURE_2D, tempTextures[0]);
	
	DrawScreenAlignedQuad(256.0f, 256.0f);
	
	glTranslatef(0.0f, 256.0f + 16.0f, 0.0f);
	
	glBindTexture(GL_TEXTURE_2D, tempTextures[1]);
	
	DrawScreenAlignedQuad(256.0f, 256.0f);
	
	// ----------------------------------------------
	// Final scene rendering...
	// ----------------------------------------------
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// <temp>
	gluPerspective(60.0f, (double)g_clientRect.right / (double)g_clientRect.bottom, 0.1f, 1000.0f);
	// </temp>
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	// <temp>
	gluLookAt(100.0f, 100.0f, 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
	// </temp>
	
	RenderScene();
	
	// ----------------------------------------------
	// Cleanup...
	// ----------------------------------------------
	
	glDeleteTextures(2, tempTextures);
	
	glDeleteFramebuffersEXT(1, &tempFramebuffer);
	
}

EDIT: And the one thing I forgot: I'm running this on a GeForce 7800 GTX, so I do have the extensions I'm trying to use [grin] EDIT2: The other one thing I forgot: I have the latest drivers, 84.21.
My opinion is a recombination and regurgitation of the opinions of those around me. I bring nothing new to the table, and as such, can be safely ignored.[ Useful things - Firefox | GLee | Boost | DevIL ]
MARS_999
MARS_999
Honestly the best way to go about this is to use only one FBO and use two color attachements to render to and use the render buffer to do your depthmap. This is the fastest and IMO easiest way to use FBO's...
iNsAn1tY
iNsAn1tY
Thanks for the replies.

@AP - I removed the glDrawBuffer/glReadBuffer commands, and I've gone through my code throughly with glGetError, but there were no errors, and it's made no difference, unfortunately.

@MARS_999 - I am only using one FBO, but I'm re-creating it every frame (performance is not a concern at the moment). I'm basically trying to render to two textures, one after another. I attach the first texture to the FBO's colour attachment 0 and render to it, then attach the second to the same FBO's colour attachment 0 and render to it. Is this the right way to do it? I did try attaching the two textures to colour attachments 0 and 1 respectively, but this made no difference. I've also tried only rendering to only one texture, and completely removing the code for the second texture. This hasn't made any difference either.

It seems like the extension isn't functioning at all, which is strange. I'll see if I can find some code or a demo which uses FBOs, to test if it's working.
My opinion is a recombination and regurgitation of the opinions of those around me. I bring nothing new to the table, and as such, can be safely ignored.[ Useful things - Firefox | GLee | Boost | DevIL ]
iNsAn1tY
iNsAn1tY
AAAARRRRGGGGHHHH!

glEnable(GL_TEXTURE_2D);

If you're drawing quads with textures on them, you need to ACTUALLY TURN ON TEXTURING AT SOME POINT. I knew it would be something stupidly simple. I am now kicking myself. All the FBO rendering is absolutely fine, I just couldn't see the finished product.

Ah well, that's that little mystery cleared up [grin]
My opinion is a recombination and regurgitation of the opinions of those around me. I bring nothing new to the table, and as such, can be safely ignored.[ Useful things - Firefox | GLee | Boost | DevIL ]
MARS_999
MARS_999
Quote:
Original post by iNsAn1tY
AAAARRRRGGGGHHHH!

glEnable(GL_TEXTURE_2D);

If you're drawing quads with textures on them, you need to ACTUALLY TURN ON TEXTURING AT SOME POINT. I knew it would be something stupidly simple. I am now kicking myself. All the FBO rendering is absolutely fine, I just couldn't see the finished product.

Ah well, that's that little mystery cleared up [grin]


Hmm, you must be using FFP then. :) I was assuming you were using shaders of some sorts. But I guess if you are just rendering the results to see them then FFP would be fine and then yes you need that function call. :)


Back to the performance a single FBO with multiple texture attachments and attach the textures to 0-n color attachements is the best way to go. Then you would use the glDrawBuffer() to switch between the attachements. HTH but if you got it working cheers!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.