opengl-escopytexturesgldrawpixels

Copy arbitrarily sized block of pixels into OpenGL ES texture... somehow?


I'm writing a drawing application, and the drawing canvas is an OpenGL texture. When you draw onto the canvas, it determines which region of the canvas texture has been changed, and copies that pixel data out (using glReadPixels) before applying the changes you made.

To undo, I want to simply revert to the previous texture state using that pixel data that was copied out. However, OpenGL ES doesn't provide a glDrawPixels command. What's the best way to do it?

I've considered two options, but I'm not sure either is that great:

  1. Create a temporary texture using the pixels I copied out and draw that in. (However, copied region is not a power of two!)

  2. Unbind the large canvas texture completely, manually alter the bytes of the texture, and then put it back into OpenGL. I'm not using any sort of compression, so this might not be that bad. But it seems like a hack?

Anybody have any ideas? I'd really appreciate it!


Solution

  • In case anyone stumbles across this while trying to do something similar, I've come up with a solution that seems to work well.

    1. Grab an image of the current texture by binding it to the framebuffer and then writing the framebuffer to a CGImageRef.
    2. Create a new CGContext and draw in the existing texture CGImageRef. Then draw old texture data in to the portion that the user changed, effectively "undoing" that change to the image.
    3. Destroy old OpenGL texture and create a texture from the CGContext.

    I think this is a pretty slow way of going about things, but I don't need huge performance - my real concern was limiting the amount of data being kept to represent the "old" texture.

    If you need help with this (there's quite a bit of code) feel free to email me.