Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

FBO texture attachment only being rendered to once?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 d0Sm4o20   Members   -  Reputation: 100

Like
0Likes
Like

Posted 13 February 2011 - 11:38 PM

Hi guys,

I have a texture attached to an FBO that i'm rendering to, and then sending that texture to a shader. It all works fine and well....for 1 frame, the first frame. Then the texture is always black. It seems like the FBO texture can only be drawn to once(!?) in my code, and afterwards, it is erased and only black is drawn to it. It's really driving my nuts. I feel like I'm missing something completely obvious. Here is my main draw function:

void draw() {
	printf("Beginning of draw\n");
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

	// clear the FBO texture and set the draw color
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	// draw a square where the mouse is
	float x, y, w, h;
	w = 100.0f;
	h = 100.0f;
	x = mouse.x;
	y = mouse.y;
	glRectf(x, y, x+w, y+h);

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


	// generate mipmaps for the FBO texture
	glBindTexture(GL_TEXTURE_2D, fbo_tex);
	glGenerateMipmapEXT(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, 0);


	// this should all apply to the actual screen now
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	glColor3f(1.0f, 1.0f, 1.0f);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, fbo_tex);


	// draw a quad which we'll screen align in a vertex shader, and then paint
	// with the FBO texture in the fragment shader
	glUseProgram(blur_program);
	glRecti(0, 0, 1, 1);
	glFlush();
	glUseProgram(0);

	printf("End of draw\n");
	SDL_Delay(1000);
}


This is the vertex shader that aligns that second glRecti call to the screen:

void main(void) {
	gl_Position =  gl_Vertex * 2.0 - 1.0;
  	gl_TexCoord[0]  = gl_Vertex;
}

And the fragment shader:


uniform sampler2D fbo;

void main(void) {
	gl_FragColor = vec4(texture2D(fbo, gl_TexCoord[0].st));
}

Like I said, it seems to work for only *one frame* (I can see the 100x100 white square for 1 second, thanks to the SDL_Delay(1000))....so it is getting drawn to the FBO texture and the shaders are processing everything correctly. It's just that every time draw() is called *after the first time*, the FBO texture is painted with black.

I've changed the clear color on the FBO to red, and indeed the screen is rendered red instead of black, showing that the FBO texture is still being painted, even when the square for some reason is not. I've also tried attaching an arbitrary image as the texture getting fed into my shader, and that works on every frame, showing that the error isn't in my shaders. I'm really at a loss here...why isn't that white 100x100 square being drawn on every draw() call?

Any ideas? Thanks in advance!

Sponsor:

#2 Asem   Members   -  Reputation: 154

Like
0Likes
Like

Posted 13 February 2011 - 11:51 PM

how did you setup the fbo texture? Are you setting to texture to use mipmap filtering like gl_linear_mipmap_linear? It could be the reason that nothing shows up. Check to see what happens if you take away glgeneratemipmaps function.

You could also use gl_FragData[0] = color; where the index is the color attachment.

#3 d0Sm4o20   Members   -  Reputation: 100

Like
0Likes
Like

Posted 14 February 2011 - 12:08 AM

how did you setup the fbo texture? Are you setting to texture to use mipmap filtering like gl_linear_mipmap_linear? It could be the reason that nothing shows up. Check to see what happens if you take away glgeneratemipmaps function.


Hey Asem,

The problem is that it's rendering correctly for one frame, the first frame, and then getting cleared for all subsequent frames. Here's what I mean:

Frame 0: http://i.imgur.com/dkqUs.png
Frame 1: http://i.imgur.com/1VKYl.png

Somehow, when draw() is called a second time, it's refusing to draw the white square.

Here's how the FBO is getting set up:
glGenTextures(1, &fbo_tex);
	glBindTexture(GL_TEXTURE_2D, fbo_tex);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	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_GENERATE_MIPMAP, GL_TRUE);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glBindTexture(GL_TEXTURE_2D, 0);


	GLuint rboId;
	glGenRenderbuffersEXT(1, &rboId);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, WIDTH, HEIGHT);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);


	glGenFramebuffersEXT(1, &fbo);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_tex, 0);
	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId);


	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


	GLuint fbo_l = glGetUniformLocation(blur_program, "fbo");
	glUseProgram(blur_program);
	glUniform1i(fbo_l, 0);
	glUseProgram(0);

	glBindTexture(GL_TEXTURE_2D, 0);


#4 karwosts   Members   -  Reputation: 840

Like
0Likes
Like

Posted 14 February 2011 - 12:42 AM

You've called glGetError?
My Projects:
Portfolio Map for Android - Free Visual Portfolio Tracker
Electron Flux for Android - Free Puzzle/Logic Game

#5 d0Sm4o20   Members   -  Reputation: 100

Like
0Likes
Like

Posted 14 February 2011 - 01:24 AM

You've called glGetError?


I've added assert(glGetError() == GL_NO_ERROR); in the draw() function, and everything seems fine :\

#6 d0Sm4o20   Members   -  Reputation: 100

Like
0Likes
Like

Posted 14 February 2011 - 01:25 AM

It's just really bizarre to me that it would work for the first frame, and not for any of the others. I don't think i'm doing anything permanent to the OpenGL state in that draw() function.

#7 karwosts   Members   -  Reputation: 840

Like
1Likes
Like

Posted 14 February 2011 - 01:30 AM

Have you gone through this with a debugger and verified all the numbers are good in subsequent passes? mouse.x is not NaN or something simple like that.

Also are you certain you're not doing anything opengl related between the end of draw #1 and start of draw #2 that you're not showing?

You may want to try unbinding the draw texture after you're done using it, it may not like that you're trying to draw to a bound texture, but I'm not sure.
My Projects:
Portfolio Map for Android - Free Visual Portfolio Tracker
Electron Flux for Android - Free Puzzle/Logic Game

#8 d0Sm4o20   Members   -  Reputation: 100

Like
0Likes
Like

Posted 14 February 2011 - 01:38 AM

You may want to try unbinding the draw texture after you're done using it, it may not like that you're trying to draw to a bound texture, but I'm not sure.


You beautiful bastard. That's exactly what it was. Posted Image


I should've known better too, I remember reading this from the Blue Book:

You may at this point have already asked yourself, “What happens if I have a texture
attached to the current FBO and also bound to a texture unit that’s currently in use? Isn’t
there a paradox in which I’m currently rendering from the same surface I’m rendering
to?” The answer is, “Yes, there’s a paradox, and you’ll tear apart the very fabric of space
and time, causing the universe to cease existence.” Or your rendering will be undefined.
Either way, don’t do it, I implore you.


Thanks a ton, karwosts!




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS