Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Copy frame data to texture

  1. #1
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    7

    Copy frame data to texture

    I would like to copy the image currently drawn onscreen into a texture. It seems like glCopyTexSubImage2D is the best way to accomplish this, but it doesn't seem to be working.

    I'm trying to get this to work first in a simple case. At the first frame I simply draw a red circle in the corner of the screen and store the current frame in a texture. In subsequent frames I draw the stored texture, then draw another red circle at an offset which increases with time, and then copy the current frame back to the texture.

    If this were working correctly then I would expect to see all of the red circles which had been drawn in all earlier frames, which would show up as a line which gets longer as the animation proceeds. Instead I simply see a red circle marching across the screen, which seems to indicate that I am not correctly storing the frame data into my texture.

    I would very much appreciate any help that anyone could offer.

    I'm writing in Java using JOGL, and the relevant code is as follows:

    Code :
    	public void init(GLAutoDrawable drawable) {
    		GL2 gl = drawable.getGL().getGL2();
     
    		gl.glDisable(GL2.GL_DEPTH_TEST);
     
    		gl.glMatrixMode(GL2.GL_PROJECTION);
    		gl.glLoadIdentity();
    		gl.glOrtho(0.0, width, 0.0, height, 0.0, 1.0);
    		gl.glViewport(0, 0, width, height);
     
    		gl.glGenTextures(1, frameTexture, 0);
    	}
     
    	public void display(GLAutoDrawable drawable) {
    		GL2 gl = drawable.getGL().getGL2();
    		GLU glu = new GLU();
    		GLUquadric quad = glu.gluNewQuadric();
     
    		gl.glClear(GL2.GL_COLOR_BUFFER_BIT);
     
    		if(frameNumber > 0) {
    			// draw the texture stored in frameTexture
    			gl.glEnable(GL2.GL_TEXTURE_2D);
    			gl.glBindTexture(GL.GL_TEXTURE_2D, frameTexture[0]);
    			gl.glBegin(GL2.GL_QUADS);
    			gl.glBegin(GL2.GL_QUADS);
    			gl.glTexCoord2f(0, 0);
    			gl.glVertex2d(0, 0);
    			gl.glTexCoord2f(width, 0);
    			gl.glVertex2d(width, 0);
    			gl.glTexCoord2f(width, height);
    			gl.glVertex2d(width, height);
    			gl.glTexCoord2f(0, height);
    			gl.glVertex2d(0, height);
    			gl.glEnd();
    		}
     
    		// draw a red circle
    		double[] oldColor = new double[4];
    		gl.glGetDoublev(GL2.GL_CURRENT_COLOR, oldColor, 0);
    		gl.glColor3dv(new double[] {1.0, 0.0, 0.0}, 0);
    		gl.glPushMatrix();
    		gl.glTranslated(frameNumber, frameNumber, 0);
    		glu.gluDisk(quad, 0, 15, 20, 2);
    		gl.glPopMatrix();
    		gl.glColor3dv(oldColor, 0);
     
    		// update frameTexture with the current frame buffer
    		gl.glEnable(GL2.GL_TEXTURE_2D);
    		gl.glBindTexture(GL2.GL_TEXTURE_2D, frameTexture[0]);
    		gl.glCopyTexSubImage2D(GL2.GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
     
    		frameNumber++;
    	}

  2. #2
    Junior Member Regular Contributor
    Join Date
    Nov 2010
    Location
    Brazil, Rio de Janeiro
    Posts
    147

    Re: Copy frame data to texture

    always when you wanna use a rendered image as texture, consider the use of Frame Buffer Objects. This kind off objects allows the use of techniques such as render-to-texture, which can very useful for what you trying to accomplish.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,792

    Re: Copy frame data to texture

    gl.glGenTextures(1, frameTexture, 0);
    This is not sufficient to create a texture. It creates the name for a texture, but that doesn't actually allocate the storage for any of the image data.

    Therefore, you need to call glTexImage2D with the proper width and height, as well as the desired internal format.

    Also, you seem to call glBegin twice. Is that a typo, or is that actually in your code?

  4. #4
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    7

    Re: Copy frame data to texture

    Thanks for the quick replies. I removed the extra call to glBegin() and changed my initialization to the following:

    Code :
    	public void init(GLAutoDrawable drawable) {
    		GL2 gl = drawable.getGL().getGL2();
     
    		gl.glDisable(GL2.GL_DEPTH_TEST);
     
    		gl.glMatrixMode(GL2.GL_PROJECTION);
    		gl.glLoadIdentity();
    		gl.glOrtho(0.0, width, 0.0, height, 0.0, 1.0);
    		gl.glViewport(0, 0, width, height);
     
    		gl.glEnable(GL2.GL_TEXTURE_2D);
    		gl.glGenTextures(1, frameTexture, 0);
    		gl.glBindTexture(GL2.GL_TEXTURE_2D, frameTexture[0]);
    		Buffer texData = FloatBuffer.allocate(4 * width * height);
    		gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGBA, width, height, 0, GL2.GL_RGBA, GL2.GL_FLOAT, texData);
    	}

    but this gives the same behavior as before.

    If I can't get this working then I'll check out frame buffer objects, but for this application it seems that glCopyTexSubImage2D would be simpler although possibly slower.

    Is there anything else that I'm doing blatantly wrong?

  5. #5
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,792

    Re: Copy frame data to texture

    What happens if you just draw a white quad instead of trying to draw a textured quad?

  6. #6
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    7

    Re: Copy frame data to texture

    Commenting out all of the texturing calls doesn't change the observed behavior at all; I still see a red circle marching diagonally across the screen. As a sanity check I also tried adding a call

    Code :
    gl.glColor3d(0.8, 0.8, 0.8);

    before starting the quad. This gives a gray background with a red circle marching diagonally across the screen, as expected; it looks basically the same as it did before.

  7. #7
    Junior Member Regular Contributor
    Join Date
    Dec 2009
    Posts
    178

    Re: Copy frame data to texture

    I guess your texture coordinates are wrong:

    Code :
    gl.glTexCoord2f(width, height);

    should be

    Code :
    gl.glTexCoord2f(1.0f, 1.0f);

    The texture is in the range 0.0 to 1.0, you're just filling the screen with the texture's border color (except one corner pixel).

  8. #8
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    7

    Re: Copy frame data to texture

    I guess your texture coordinates are wrong
    I thought that might be the problem at first too, but changing width and height to 1.0f does not have the desired effect.

    Moreover, I have another texture (from a file, not from the color buffer) of the same size as the texture I'm trying to create, and this other texture doesn't render correctly unless I use width and height for texture coordinates; using 1.0f just fills the screen with a single pixel.

  9. #9
    Member Regular Contributor
    Join Date
    Oct 2010
    Location
    France
    Posts
    466

    Re: Copy frame data to texture

    Try with using non rectangular textures (so with width=height), use unsigned byte instead of float (no need to try float here), and stuck your texture coordinates between 0 and 1.

  10. #10
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    393

    Re: Copy frame data to texture

    It could also be a mip-mapping issue, try disabling them, or calling glGenerateMipmap(GL_TEXTURE_2D) after glCopyTexSubImage2D if you do actually want mipmaps.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •