PDA

View Full Version : Blending in Qt



ToddAtWSU
11-06-2006, 01:50 PM
I am trying to draw a box on top of a QGLWidget i have inside a Qt application. This code works on a Solaris machine with OpenGL 1.3 but does not work on a Linux machine running RedHat 4 with OpenGL 2.0. I am allowing the user to use the mouse to draw a box on top of my QGLWidget. I have 3 sets of variables that are arrays containing 2 floats, an X and Y value. My ortho and viewport is all set up and working properly. I draw what I call an old box followed by the new box. I use blending with XOR so I can draw the box from the start point to the mouse. Then when the user moves the mouse, I want to redraw over the old box and draw the new box based on the mouse's current position. The code to draw my box on top of all my other drawings looks like the following.


if( drawBox == true )
{
setAutoBufferSwap( false );
qglColor( mBoxColor );
glDrawBuffer( GL_FRONT );
glEnable( GL_LOGIC_OP );
glEnable( GL_BLEND );
glBlendEquationEXT( GL_LOGIC_OP );
glLogicOp( GL_XOR );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glLineWidth( 2.0 );
// Erase the old box
glBegin( GL_LINE_LOOP );
glVertex3d( mBeginBox[0], mBeginBox[1], 0.0 );
glVertex3d( mBeginBox[0], mOldEndBox[1], 0.0 );
glVertex3d( mOldEndBox[0], mOldEndBox[1], 0.0 );
glVertex3d( mOldEndBox[0], mBeginBox[1], 0.0 );
glEnd( );
// Draw the new box based on the current mouse position
glBegin( GL_LINE_LOOP );
glVertex3d( mBeginBox[0], mBeginBox[1], 0.0 );
glVertex3d( mBeginBox[0], mEndBox[1], 0.0 );
glVertex3d( mEndBox[0], mEndBox[1], 0.0 );
glVertex3d( mEndBox[0], mBeginBox[1], 0.0 );
glEnd( );
glDisable( GL_LOGIC_OP );
glDisable( GL_BLEND );
glDrawBuffer( GL_BACK );
setAutoBufferSwap( true );
} Can anybody see what is wrong in this code? My guess is it has something to do with the glBlendEquationEXT call. What I get is if my mBoxColor == Qt::black, I see every single black box that was drawn from stop to finish. It draws both boxes, but never XORs the boxes and erases the older of the boxes. Why does this work on Solaris 8 running OpenGL 1.3 but not RedHat 4 with OpenGL 2.0? I have also tried using glColor3f( 0.0, 1.0, 0.0 ); and this did not change anything except the color of the boxes. Thanks for all your help!

Relic
11-06-2006, 03:13 PM
The calls glBlendEquationEXT(GL_LOGIC_OP) requires the extension GL_EXT_blend_logic_op (from 1995!). Does the Implementation offer this?
Add glGetError to catch if you used an invalid enum.

Anyway you probably don't need that. Just do this:

glLogicOp( GL_XOR ); // Try to always set state first, then enable it. That avoids at least one OpenGL pitfall (#14).
glEnable( GL_COLOR_LOGIC_OP ); // GL_LOGIC_OP is for color index mode, use GL_COLOR_LOGIC_OP if you're in RGBA mode.
...
glDisable( GL_COLOR_LOGIC_OP );

Here's a nice idea if pure XOR looks too lame: For fancy color effects you can render in white and limit the rendering to different combinations of the RGB channels with the glColorMask RGB booleans.

ToddAtWSU
11-07-2006, 06:13 AM
Thanks Relic. That would explain why GL_LOGIC_OP worked for me on the Solaris. I was doing the project in 8-bit color indexed mode. But on the Linux machine I am in 24-bit RGB color. I looked and my glext.h includes that GL_EXT_blend_logic_op. My big problem now is my compiler tells me GL_COLOR_LOGIC_OP is not a valid choice. I looked inside my gl.h file and found where GL_COLOR_LOGIC_OP is #define right after GL_LOGIC_OP. Inside my make file for the include paths, the first path I include is /usr/include and then my file #include <GL/gl.h> so I know that /usr/include/GL/gl.h should be the first implementation of gl.h on my system. This version had GL_COLOR_LOGIC_OP defined, yet it can't find it. Do you have any ideas why this is? I think this is exactly what I need but since I can't compile in it, I don't know how to test it out. Thanks!

Relic
11-07-2006, 06:26 AM
That your glext.h contains GL_EXT_blend_logic_op means nothing. The question is if glGetString(GL_EXTENSIONS) issued on the OpenGL implementation reports it.

Sorry, I'm not a Linux user and can't really help with build problems.
If you think your includes are not working, you could rename or add a syntax error to the gl.h you think it is and see what happens. If your normal projects still build you obviously use a different header. Search for all of them and track the one down.

To check if the GL_COLOR_LOGIC_OP works at all before you fixed your build problems, you could just define it in the source where you use it.

Add glGetError calls during debugging!