Sign in to follow this  

Rendering to texture (fixed)

This topic is 3312 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 everyone, Extremely frustrated, I have no idea why my attempt on trying to write the frame into a texture fails each time. Basically, I get a pure white texture even though I have the proper values in the Screen512 array after the glReadPixels() call. Can someone help me out here? Thanks.
//===Frame texture definition
uChar	*Screen512;
GLuint	Screen512Tex;

//===Frame texture initialization
Screen512 = new uChar[512 * 512 * 3];
GLuint texid;
glGenTextures( 1, &texid );
Screen512Tex = texid;
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Screen512 );


//===Render code
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glEnable( GL_BLEND );

//FIRST PASS - NO GLOW
glViewport( 0, 0, 512, 512 );

..
//Render code here
..

glReadPixels( 0, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Screen512 );
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Screen512 );

glViewport( 0, 0, 1024, 768 );
Vec2D c = SystemManager::getInstance().getGraphicsManager()->unprojectScreenCoord( 65.f, Vec2D( 1024, 768 ) );

//The simple quad that I'm trying to render the exact previous frame into.
glPushMatrix();
glTranslatef( 0, 0, 65.f );
glScalef( c.x*0.5, c.y*0.5, 1.f );
glDisable( GL_BLEND );
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 );	glVertex3f( -1,  1, 0 );
glTexCoord2f( 0, 0 );	glVertex3f( -1, -1, 0 );
glTexCoord2f( 1, 0 );	glVertex3f(  1, -1, 0 );
glTexCoord2f( 1, 1 );	glVertex3f(  1,  1, 0 );
glEnd();
glEnable( GL_BLEND );
glPopMatrix();

glutSwapBuffers();
glutPostRedisplay();
[Edited by - Dynx on November 16, 2008 8:49:17 PM]

Share this post


Link to post
Share on other sites
That is because you don't transfer the readed data back to VRAM.
Proper way of using readpixels would be:


1. render your scene here (first pass)

2. read to system memory and create texture from the data

Screen512 = new uChar[512 * 512 * 3];
glReadPixels( 0, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Screen512 );
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Screen512 );

3. second pass


Of course this may be slow, as it involves copying the data back and forth between VRAM and system RAM. Better way to render to texture is use FrameBuffer bjects (FBO), or if they are not available, pixel buffers (pbuffers).

Edit: I forgot to mention that you can bypass using readpixels (and system ram copy) by using glCopyTexImage* or glCopyTexSubImage*. Those functions will read the current frame buffer and copy the content to the currently bound texture. In that case the second step is merely binding the texture and calling glCopyTex(Sub)Image*

Share this post


Link to post
Share on other sites
Quote:
Original post by snoutmate
That is because you don't transfer the readed data back to VRAM.
Proper way of using readpixels would be:


1. render your scene here (first pass)

2. read to system memory and create texture from the data

Screen512 = new uChar[512 * 512 * 3];
glReadPixels( 0, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Screen512 );
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Screen512 );

3. second pass


Edit: I forgot to mention that you can bypass using readpixels (and system ram copy) by using glCopyTexImage* or glCopyTexSubImage*. Those functions will read the current frame buffer and copy the content to the currently bound texture. In that case the second step is merely binding the texture and calling glCopyTex(Sub)Image*


Thanks for the reply but, allocating memory twice( once in using 'new' and once in glTexImage2D) would be an incredible memory hit, and I'm really not seeing how your way is different than mine.
I was eventually going to move to FBOs however; I want to get this to work first. And just to be safe, I tried your method which didn't work.

And I am not rendering the same scene again, just because. I can test it without rendering the actual seen twice.

@V-Man: I checked out the link you've sent, and did the necessary modifications, still no luck though.

Below I'm trying to render copy straight from buffer to texture, still a white texture. I wonder if there is something wrong with the glew.


//--->initializations
GLuint texid;
glGenTextures( 1, &texid );
Screen512Tex = texid;
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, 0, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glGenerateMipmapEXT( GL_TEXTURE_2D );

//------->render
//...render actual scene...
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512, 512 );
glGenerateMipmapEXT( GL_TEXTURE_2D );

glViewport( 0, 0, 1024, 768 );

glDisable( GL_BLEND );
glBindTexture( GL_TEXTURE_2D, Screen512Tex );
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 ); glVertex3f( -1, 1, 0 );
glTexCoord2f( 0, 0 ); glVertex3f( -1, -1, 0 );
glTexCoord2f( 1, 0 ); glVertex3f( 1, -1, 0 );
glTexCoord2f( 1, 1 ); glVertex3f( 1, 1, 0 );
glEnd();
glEnable( GL_BLEND );

glutSwapBuffers();
glutPostRedisplay();





Screenshot: Link

!!!
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, 0, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, Screen512 );

glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0 );

and it works. Thanks for the help.

[Edited by - Dynx on November 16, 2008 1:09:42 PM]

Share this post


Link to post
Share on other sites

This topic is 3312 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this