glCopyTexSubImage distorts colors

Started by napier, November 02, 2004, 19:45:04

Previous topic - Next topic

napier

I'm using glCopyTexSubImage2D to grab the framebuffer into a texture.  Later I restore the screen by drawing that texture on a screen-sized quad.  The problem is that the colors of the restored screen image look slightly different than the original.  If I capture the left half of the screen and draw it on the right side, there is a slight shift in the colors between the two halves:

http://potatoland.com/code/lwjgl/frame2texture/screen_alpha_compare_clearbg_fins.png

Even if I just clear the background to a color, grab the framebuffer and draw it back, I get a color shift:

http://potatoland.com/code/lwjgl/frame2texture/screen_alpha_compare_clearcolor.png

I have no idea what I'm missing here.  Does anybody have a working example of this in LWJGL?

I'm running version .92    Display is 1024 x 768 x 32 @60Hz

Here's the meat of the code:

   public void init()
    {
        // prepare to render in 2D
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glPushMatrix();
        GL11.glLoadIdentity();
        GL11.glOrtho(0,1024,0,768,-1,1);

        // Turn textures on, lighting and depth off
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glDisable(GL11.GL_LIGHTING);
        GL11.glDisable(GL11.GL_DEPTH_TEST);

        // clear the screen
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

        // Create fish texture image
        GLImage fishImgL = loadImage("images/fish_angelblue_L.gif");
        fishTextureHandleL = makeTexturet(fishImgL.pixelBuffer, fishImgL.w, fishImgL.h);

        // Create texture to hold screen image (1024x1024)
        screenTxtrHandle = makeTexturet(allocBytes(1024*1024*4), 1024, 1024);
    }


    public static int makeTexturet(ByteBuffer pixels, int w, int h)
    {
        int textureHandle = allocateTexture();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, w, h, 0, 
			GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels);
        return textureHandle;
    }


    public void render() {
        if (mouseIsDown) {
            // draw the saved screen image on right half of screen
            GL11.glDisable(GL11.GL_BLEND);
            drawQuad(screenTxtrHandle, 512,0, 1024,1024);  // plain vanilla textured quad
        }
        else {
            // draw some blended images on the left side of screen
            GL11.glClearColor(.1f, .1f, .2f, 1f);
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
            GL11.glEnable(GL11.GL_BLEND);
            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
            GL11.glColor4f(1f, 1f, 1f, .5f);
            GLApp.drawImageQuad(fishTextureHandleL, -620, -260, 1200f, 1000f);
            GLApp.drawImageQuad(fishTextureHandleL, -520, -160, 1200f, 1000f);

            // copy the left half screen to a texture
            GL11.glDisable(GL11.GL_BLEND);
            GL11.glColor4f(1,1,1,1);
            GL11.glReadBuffer(GL11.GL_BACK);
            GL11.glBindTexture(GL11.GL_TEXTURE_2D,screenTxtrHandle);
            GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, 0,  0,0,   0,0,512,768);
        }
    }


full code is at:  http://potatoland.com/code/lwjgl/frame2texture/GLApp_FrameSaveTest.java

thanks
penGL/Java/LWJGL demos and code: http://potatoland.org/code/gl

princec

Not a LWJGL thing, it's an OpenGL thing. What's going on there is colour quantization. I expect your drivers are reading a 32 bit framebuffer and stuffing it into a 16bit texture. You can try being more explicit about the texture format in your initial call to glTexImage2 eg GL_RGBA8

Cas :)

napier

Thanks Cas,

I wasn't sure whether it's OpenGL or LWJGL, figured I'd start here first.

I'll check the texture format.  Thanks for the tip.

mark
penGL/Java/LWJGL demos and code: http://potatoland.org/code/gl