PDA

View Full Version : Get the pixel / color format of the draw buffer?



taifunbrowser
07-03-2009, 11:03 PM
I recently tracked down a relatively nasty ping-ponging bug in Vista:

When using the Aero theme, the back buffer is RGBA, so you have to make an RGBA texture to copy the pixels into, or you get weird distortion.

When using the basic theme, the back buffer is RGB, and so you have to make an RGB texture.

Basically, it comes down to that I need to be able to query what format the back buffer is in, so I can make the right texture. I have working programs for both cases, I just need the code to pick when to run which.

-Taif

awhig
07-04-2009, 12:29 AM
Not clear by "Aero" theme and "basic" theme.

ZbuffeR
07-04-2009, 01:47 AM
1) if you need an alpha channel, you should explicitly require it at window creation. Aero or not should not make a difference, unless you rely on default behavior. Do you use glut or win32 api ? Please show this part of your code.

2) glCopyTex[Sub]Image2D show work from/to any mix of RGB/RGBA back buffer and texture, unless an implementation bug. Can you also show your code for this part ?

3) what is your GPU hardware and its driver version ?

taifunbrowser
07-05-2009, 09:52 AM
OK_ Actually, I was wrong. It doesn't matter whether I use glCopyTexImage2D with RGB or RGBA. It comes down to that either way, the code works if Aero is enabled, and fails if it is not.

The workaround is to call glCopyTexImage2D every frame, but that's slow. Plus, why does glCopyTexSubImage2D only work when Aero is enabled?

1) Sorry, I'm using some bindings that get the canvas for me.

2) glCopyTexImage2D works fine, but it's slower than glCopyTexSubImage2D if you're calling it every frame. glCopyTexImage2D works in both cases, glCopyTexSubImage2D is only working when Aero is enabled.



if (GlTargetDrawBuffer==-1){

int[] res = new int[1]; //Read from the draw buffer
gl.glGetIntegerv(GL_DRAW_BUFFER,res,0);
GlTargetDrawBuffer = res[0];
int[] txtnumber = new int[1]; //Make the blurBuffer
gl.glGenTextures(1, txtnumber, 0);
blurTexture = txtnumber[0];
}
gl.glReadBuffer(GlTargetDrawBuffer);
if (BlurBufferState==0){ //First frame, we use copyTex.
BlurBufferState = 1;
gl.glBindTexture(GL.GL_TEXTURE_2D, blurTexture);
gl.glCopyTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, 0,0,width,height,0);
} else { //Every frame after that, use copySubTex
//NOTE: this only seems to work when Aero is enabled. :(
gl.glBindTexture(GL.GL_TEXTURE_2D, blurTexture);
gl.glCopyTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
}


3) I just upgraded: no difference. I'm using a 64-bit intel integrated card, (laptop), version 7.15.10.1537

taifunbrowser
07-05-2009, 10:08 AM
Whoohoo! fixed

Ok guys, the solution had nothing to do with OPENGL.

Symptoms: When I call GLCopyTexImage2D on the FIRST FRAME, it uses a certain width and height. Then, the copied texture has a LOCKED aspect ratio / size.

Then, successive frames use glCopyTexSubImage2D

BUT - in my application, the first frame was corrupted!

0) GL context created
1) First frame renders
2) <<<< After the first frame, I was changing the properties of the holding window (Specifically, I was enabling that the window could resize: This triggered the "frame" of the image to grow larger, which caused the canvas to be resized!)

The second frame then renders on a canvas that is the wrong size, so the texture distorted! This only happens on vista basic, because the widths of window frame borders are thicker there, depending on whether the window can be resized!

Fix:
1) Setup the window, enable resizing
2) Setup the opengl context, which now knows the right size including the window borders
3) Code runs fine on both themes

-Well, that was fun.