PDA

View Full Version : FBO, texture smoothing



kewuwsi
01-24-2008, 10:34 AM
Hi, Guys.

thanks first!
I want to use FBO to do some texture smoothing( ping-pong). The unit test is OK. But when I integrated the part to my app. I got something unexpected. please help! following are my code pieces:

int texW = myMaxTextureSize[0], texH = myMaxTextureSize[1];

// Initialize texture 1, bind to fbo
glGenTextures(1, & my_pp_tex[0]);
glBindTexture(GL_TEXTURE_2D, my_pp_tex[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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texW, texH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);

glBindTexture(GL_TEXTURE_2D, 0);

// Initialize texture 2, bind to fbo

glGenFramebuffersEXT(1, & my_fbo_tex);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo_tex);

// Attach Texture to Framebuffer Color Buffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D, my_pp_tex[0], 0);
// Attach Texture to Framebuffer Color Buffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT , GL_TEXTURE_2D, my_pp_tex[1], 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


// later..........::
// Using FBO
// render to buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo_tex);
glPushAttrib(GL_VIEWPORT_BIT);
glDisable(GL_DEPTH_TEST);


// draw, render myTextureName texture to FBO
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-myMaxTextureSize[0]/2.0, myMaxTextureSize[0]/2.0,- myMaxTextureSize[1]/2.0, myMaxTextureSize[1]/2.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, myMaxTextureSize[0],myMaxTextureSize[1]);


glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE5_ARB);
glBindTexture(GL_TEXTURE_2D, myTextureName);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );


// do some fragment operation

//glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
// I don't think above line is needed, but without this line,I dot nothing. use it, I got something strange( not something like the input image)

glBegin(GL_QUADS );
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-myMaxTextureSize[0]/2.0,-myMaxTextureSize[0]/2.0 );

glTexCoord2f(1.0f, 0.0f);
glVertex2f(myMaxTextureSize[0]/2.0 , 0.0f);

glTexCoord2f(1.0f, 1.0f);
glVertex2f( myMaxTextureSize[0]/2.0, myMaxTextureSize[1]/2.0 );

glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, myMaxTextureSize[1]/2.0);
glEnd();

glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();

glPopAttrib();

glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);

glActiveTextureARB(GL_TEXTURE0_ARB);
//BindTexture(GL_TEXTURE_2D, myTextureName); // use this line will give me correct result,
glBindTexture(GL_TEXTURE_2D, my_pp_tex[1]); // But I want to use this line for FBO, texture smoothing use shaders,

mfort
01-24-2008, 12:04 PM
Hi,

I do not understand the whole picture, but there are some weird spots:

Your code:
1 glEnable(GL_TEXTURE_2D);
2 glActiveTextureARB(GL_TEXTURE5_ARB);

I'd swap the lines 1,2. First select the texture unit, then enable or disable it.

Not sure if texture 5 is what you are after. If yes, then you should use another API to specify tex coord for particular texture unit. But I guess texture 0 is just fine.


--
Marek

-NiCo-
01-24-2008, 12:13 PM
That's not the only weird piece of code, take a look at the vertex coordinates of the quad...

N.

Zengar
01-24-2008, 12:22 PM
I would call this around the box way of thinking :)

kewuwsi
01-24-2008, 12:38 PM
tks.

I noticed the vertex coordinates problem and had made the update to
"
glBegin(GL_QUADS );
glTexCoord2f(0.0f, 0.0f);

glVertex2f(-myMaxTextureSize[0]/2.0,-myMaxTextureSize[1]/2.0 );

glTexCoord2f(1.0f, 0.0f);
glVertex2f(myMaxTextureSize[0]/2.0 , -myMaxTextureSize[1]/2.0);

glTexCoord2f(1.0f, 1.0f);
glVertex2f( myMaxTextureSize[0]/2.0, myMaxTextureSize[1]/2.0 );

glTexCoord2f(0.0f, 1.0f);
glVertex2f(-myMaxTextureSize[0]/2.0 , myMaxTextureSize[1]/2.0);
"
But anyway, I should see some pattern. right now, I see nothing.

-NiCo-
01-24-2008, 12:56 PM
Why do you need two color attachments when performing texture smoothing? I know you're going for a ping-pong implementation but you can't read from a texture and write to that texture (still bound to the FBO) at the same time. Actually you can, but the results will be undefined.

N.

mfort
01-24-2008, 12:59 PM
Always try to make things simple. Usually easier code works better.

Setup the proj. matrix this way:
glOrtho( 0, 1, 0, 1, -1, 1 );
Then your vertices can have nice coordinates (like the texture coords).

I also believe one color attachment would be enough for you.
Edit: -NiCo- already said this while I was writing my post ;-)

kewuwsi
01-24-2008, 01:48 PM
tks

yes, I plan to do some ping-pong for texture smoothing. I do think I need two attachments for swapping( multi level gauss convolution, the attachment will be used to save the previous result).
right now, it is not fully implemented yet. Also for now, my input texture handle is myTextureName, my_pp_tex[] is the attachment.

-NiCo-
01-24-2008, 01:57 PM
You don't need two attachments for that:



//bind FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo_tex);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D, my_pp_tex[0], 0);

//first pass
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, myTextureName);
drawQuadHere();

for (int it=0;it<nrIterations;++it)
{
//ping
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D, my_pp_tex[1], 0);
glBindTexture(GL_TEXTURE_2D, my_pp_tex[0]);
drawQuadHere();

//pong
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D, my_pp_tex[0], 0);
glBindTexture(GL_TEXTURE_2D, my_pp_tex[1]);
drawQuadHere();

}

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_TEXTURE_2D);


N.

kewuwsi
01-24-2008, 02:30 PM
cool, tks. will try it out!

why you think I was "read from a texture and write to that texture (still bound to the FBO) at the same time". I did a test by rendering a line( no textures binded" to the FBO, the output looks reasonable, but looks there are some noise. "results will be undefined.?". really did not get it .

Dark Photon
01-28-2008, 05:48 AM
why you think I was "read from a texture and write to that texture (still bound to the FBO) at the same time". I did a test by rendering a line( no textures binded" to the FBO, the output looks reasonable, but looks there are some noise. "results will be undefined.?". really did not get it .
They're just saying that the results of reading from and rendering into a texture at the same time are explicitly undefined (indeterminent) in the spec. May work with some vendor's driver for some set of driver versions, but you have no guarantee it won't behave badly in the next driver rev. If it does, you have no leg to stand on.

Why the reader thinks you're doing that is pretty obvious. If you're not doing that, great. Don't worry about it. But it does look fishy.

For downsampling, you need a source and a destination. You're allocating two identical textures. You bind them "<u>both</u>" to the FBO. Why? If you weren't violating the above restriction, you shouldn't have both bound at once. You should bind texture A to a texture unit, bind texture B to FBO, and render; then you should bind texture B to texture unit, bind texture A to FBO, and render, etc... ...at least that's one way to downsample.