PDA

View Full Version : Problem when mixing openGL and QPainter



sanjayshelke
10th March 2008, 09:13
hi,

I am using openGL selection and picking mechanism in QGLWidget in order to identify the objects under cursor at mouse press.

It works fine if i only used openGL.

But further i mixed openGL and QPainter (like overpainting example of Qt examples) in the samr application,selection and picking mechanism is not working.

I am using Qt 4.4 preview edition.

Can any tell me is it possible or not.
Or else anything i m doing wrong.

regards,
~sanjay

wysota
12th March 2008, 22:10
Could we see some related code?

sanjayshelke
17th March 2008, 13:59
here is the related code.....

In order to mix QPainter and openGL i have reimplemented paintEvent().


void QPyramidTool::paintEvent(QPaintEvent *event)
{

QPainter painter;
painter.begin(this);

resizeGL(width(),height());
// Rotate the Pyramid and update.
glClearColor(2.0, 2.0, 2.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslated(0.0, 0.0,-10.0);
glRotated(m_nXRot / 10.0, 2.0, 0.0, 0.0);
glRotated(m_nYRot / 10.0, 0.0, 2.0, 0.0);
glRotated(m_nZRot / 10.0, 0.0, 0.0, 2.0);

glCallList(m_glObject);

event->accept();
}
and the resizeGL() is
void QPyramidTool::resizeGL(int width, int height)
{
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-3.5, +3.5, +3.5, -3.5, 4.0, 20.0);
glMatrixMode(GL_MODELVIEW);
}

regards,
sanjay

wysota
17th March 2008, 15:14
1. What about the selection code?
2. Why do you initialize the painter if you don't even use it?
3. You should use OpenGL code in QGLWidget::paintGL() and not paintEvent().

sanjayshelke
20th March 2008, 07:13
I have to use QPainter for painting on this QGLWidget,so i have reimpleneted paintEvent().
For reference you can see the overpainting example from Qts examples where they have reimplemented paintEvent() and used QPainter and openGL.

regards,
sanjay

Stukfruit
20th March 2008, 08:33
Yeah, using paintEvent is fully valid.

Anyway, Qt uses OpenGL for painting primitives as well, when you "mix OpenGL and QPainter". Keep that in mind. It doesn't always return to your painting method with the same state as before (altough it tries to).

The use of OpenGL selection/picking modes is not recommended though. For once, they are more or less deprecated (OpenGL3 won't have them, IIRC), and they're becoming very badly supported by some vendors, specifically by ATI.

If you would like to implement picking I would recommend to either use custom color coding or ray picking with intersection tests. You can find code for that about anywhere on the web (look for basic raytracing, it's almost the same), it's even easier than the picking mode when you get the hang of it.

The stencil buffer is used/cleared interally by the Qt painter as well, afaik, so I'm not sure if that's usable when you mix the two.

As for why it doesn't work.. can you post the rest of the code? I'm not seeing any picking/selection-related calls to OpenGL in the code you posted. As far as I can see you're only rendering an object.

sanjayshelke
20th March 2008, 12:42
thanks a lot.
i am not ware of the other techniques for picking.but as u suggest i will go through it.
here is the related code for the selection and picking mechanism.

following code i have used on mousePressEvent().


makeCurrent();
GLuint selectBuf[BUFSIZE];
GLint hits;
GLint viewport[4];


glSelectBuffer (BUFSIZE, selectBuf);
glGetIntegerv(GL_VIEWPORT, viewport);
glRenderMode (GL_SELECT);

glInitNames();
glPushName(0);

glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();

gluPickMatrix((GLdouble) x, (GLdouble)(viewport[3] - y),
2.0, 2.0, viewport);
glOrtho(-3.5, +3.5, +3.5, -3.5, 2.0, 15.0);

glMatrixMode (GL_MODELVIEW);
glLoadName(1);
glBegin(GL_TRIANGLES);
glVertex3d(0.0, 2.0, 0.0);
glVertex3d(-2.0,-2.0, 2.0);
glVertex3d(2.0,-2.0, 2.0);
glEnd();

glLoadName(2);
glBegin(GL_TRIANGLES);
glVertex3d(0.0,2.0,0.0);
glVertex3d(2.0,-2.0,2.0);
glVertex3d(2.0,-2.0,-2.0);
glEnd();

glLoadName(3);
glBegin(GL_TRIANGLES);
glVertex3d(0.0,2.0,0.0);
glVertex3d(2.0,-2.0,-2.0);
glVertex3d(-2.0,-2.0,-2.0);
glEnd();

glLoadName(4);
glBegin(GL_TRIANGLES);
glVertex3d(0.0,2.0,0.0);
glVertex3d(-2.0,-2.0,-2.0);
glVertex3d(-2.0,-2.0, 2.0);
glEnd();


glLoadName(5);
glBegin(GL_QUADS);
glVertex3d(2.0,-2.0,2.0);
glVertex3d(-2.0,-2.0,2.0);
glVertex3d(-2.0,-2.0,-2.0);
glVertex3d(2.0,-2.0,-2.0);
glEnd();

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();

hits = glRenderMode (GL_RENDER); // Returns no.of mouse hits to each face.


regards,
sanjay

sanjayshelke
21st March 2008, 12:55
can any body help me in this.

regards,
~sanjay

wysota
21st March 2008, 13:33
Hmm... why are you drawing in mousePressEvent? The event should handle mouse events, not draw anything. If the state of your widget changes as a result of mouse event handler, you should call updateGL() or update() to redraw it.

sanjayshelke
21st March 2008, 13:49
Actually in mousePressEvent() i am not drawing anything.I am just loading the names for the primitive objects on the stack.It does not draw anything it just enters into the selection mode and loads the name on to the stack.

please can you explain more.

regards,
~sanjay