Results 1 to 2 of 2

Thread: QGraphicsScene Widgets in OpenGL Projection with only a tiny problem

  1. #1
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Cool QGraphicsScene Widgets in OpenGL Projection with only a tiny problem

    Hi there!

    This post is mainly to share my efforts of about a weeks time.. to get real 3-dimensional positioning of widgets working. I didn't find anything similar and maybe somebody is trying to achieve the same thing. (The WolfenQT example uses its own transformation and not the opengl setup.)

    There is, however, one small problem left. I can't get text mouse selection to work. Everything is fully functional, but when I try to range-select text (mouse down, move, up) it won't do. I think it has something to do with my coordinate transformation.. somehow its still not exactly right, when it comes to orientation.

    The crucial function is CGL3dProjectedItem:UpdateTransformation(CGLCamera* cam):

    Qt Code:
    1. void CGL3dProjectedItem::UpdateTransformation(CGLCamera* cam)
    2. {
    3. //GLfloat projection[16];
    4. GLfloat camera[16];
    5. // Save Modelmatrix
    6. glMatrixMode(GL_MODELVIEW);
    7. glPushMatrix();
    8. // use gl to perform the matrix multiplications. using modelview matrix as temp.. Start fresh
    9. glLoadIdentity();
    10. // Multiply camera Matrices
    11. cam->GetTransformation(camera);
    12. glMultMatrixf(camera);
    13. // Item placement..
    14. glTranslated(Position().x(),Position().y(),Position().z());
    15. glTranslated(CenterPos().x(),CenterPos().y(),CenterPos().z());
    16. // Item rotation..
    17. if (Angle().x() != 0) glRotatef(Angle().x(),1,0,0);
    18. if (Angle().y() != 0) glRotatef(Angle().y(),0,1,0);
    19. if (Angle().z() != 0) glRotatef(Angle().z(),0,0,1);
    20. // Get final gl Matrix..
    21. glGetFloatv(GL_MODELVIEW_MATRIX , _trans);
    22.  
    23. // At this point.. the coordinates are not yet normalized. m33 >> 1.
    24. // Normalization will be performed in the QTransform (w' = m13*x + m23*y + m33 | x' /= w' | y' /= w')
    25. QTransform trans = GetQTrans(_trans);
    26.  
    27. setTransform(trans);
    28.  
    29. // Restore previous gl matrix
    30. glPopMatrix();
    31.  
    32. prepareGeometryChange();
    33. _bounds = shape().boundingRect();
    34.  
    35. CGL3d dist = cam->Position() - Position();
    36. setZValue(-dist.Length());
    37. }
    To copy to clipboard, switch view to plain text mode 

    with cam->GetTransformation(camera):

    Qt Code:
    1. void CGLCamera::_SetupProjection()
    2. {
    3. GLint vp[4];
    4. glGetIntegerv(GL_VIEWPORT,vp);
    5. gluPerspective(FOV(), (float)vp[2]/(float)vp[3], 0.01f, 100000.0f);
    6. }
    7.  
    8. void CGLCamera::_SetupView()
    9. {
    10. gluLookAt(ex3(_position),ex3(_lookAt),ex3(_up));
    11. }
    12.  
    13. // Returns product of projection and modelview matrix
    14. void CGLCamera::GetTransformation(GLfloat* m)
    15. {
    16. if (_PerspectiveChanged == true)
    17. {
    18. glMatrixMode(GL_MODELVIEW);
    19. glPushMatrix();
    20. glLoadIdentity();
    21. _SetupProjection();
    22. _SetupView();
    23. glGetFloatv(GL_MODELVIEW_MATRIX , m);
    24. memcpy(_PerspectiveMatrix ,m,16 * sizeof *m);
    25. glPopMatrix();
    26. _PerspectiveChanged = false;
    27. }
    28. else {
    29. memcpy(m,_PerspectiveMatrix,16* sizeof*m);
    30. }
    31. }
    To copy to clipboard, switch view to plain text mode 

    and GetQTrans:


    Qt Code:
    1. QTransform GetQTrans(GLfloat* m)
    2. {
    3. // In QTransform the dx and dy are stored in m31 and m32. which is nuts.
    4. // In 4x4 GL they are stored in 03 and 13, so that when you multiply
    5. // with a homogenous (x,y,z,1) vector you get them added automatically.
    6.  
    7. // Build QTransform of this matrix. QTransform 3x3 recieves the values per row,
    8. // whereas GL saves the 4x4 matrix per column.
    9. // m11 m12 m13 1 2 3 m00 m10 m30 0 1 3
    10. // QT: m21 m22 m23 4 5 6 GL: m01 m11 m31 4 5 7
    11. // dx dy m33 7 8 9 m03 m13 m33 12 13 15
    12.  
    13. // AAH! QTransform does not use m33, unless the transformation is not affine, m13<>0 and m23 <> 0
    14. QTransform trans;
    15. if (qFuzzyCompare(m[3] + 1, 1) && qFuzzyCompare(m[7] + 1, 1))
    16. trans = QTransform(m[0]/m[15], m[1]/m[15], m[4]/m[15], m[5]/m[15], m[12]/m[15], m[13]/m[15]);
    17. else
    18. trans = QTransform(m[0], m[1], m[3], m[4], m[5], m[7], m[12], m[13], m[15]);
    19. return trans;
    20. }
    To copy to clipboard, switch view to plain text mode 

    That was the Item->Scene transformation. Scene->View transformation looks like that:

    Qt Code:
    1. void resizeEvent(QResizeEvent *event)
    2. {
    3. cgl->makeCurrent();
    4. glViewport(0, 0, (GLint)event->size().width(), (GLint)event->size().height());
    5. // Get Viewport parameters
    6. GLint vp[4];
    7. glGetIntegerv(GL_VIEWPORT,vp);
    8. // Final viewport transformation.
    9. QTransform vtrans(vp[2]*0.5, 0,
    10. 0, -vp[3]*0.5,
    11. vp[0]+vp[2]*0.5,vp[1]+vp[3]*0.5);
    12. setTransform(vtrans);
    13. scene()->setSceneRect(QRect(-1,-1,2,2));
    14. }
    To copy to clipboard, switch view to plain text mode 

    Note the negative sign for the y-component. Needed to turn OpenGLs upside-down into common upperleft orientation.

    I copy pasted the code from a bigger project and created a little test environment for you to explore.

    There are five units included in the zip:

    • widget3d:
      CGL3dProjectedItem (base class for the gl transformation),
      CGL3dProxyWidget (new proxy for correct placement and drawing),
      CGLView (handles the opengl widget and viewport)
      CGLScene (scene, camera, mouse and keyboard)
    • Graphics: OpenGL-Camera, some drawing, some materials..
    • mathext: 3 and 4-dim vectors, unitycircle, arctan, ..
    • main.cpp: very small test program
    • test.h: 3dProjectedItem (base class for the gl transformation),


    You will need glee and glu in order to compile.



    Usage: Mouse move moves the lookat vector. Hold down <Shift> to increase speed.
    Same goes for WASD+QE to move around. Movement is deactivated when a widget is focussed.

    On the way to solve the selection problem.. I visualized myself the axes orientations. The blue box with the arrows indicates them. It is drawn in an item.paint, with the painter setup to the projected transformation by the scene. The bigger arrows are then drawn with opengl and the small ones with the painter. When I draw the axes in Drawbackground purely OpenGL I get the same matching directions. Then the blue z-axis is extended too. I guess the scene uses some ortho2d projection when painting the items.. So the mere axes orientation is probably not the problem.

    Looking forward to hear your comments! And thx in advance for any hint with the selection problem!

    Joh
    Attached Files Attached Files
    Last edited by JohannesMunk; 6th April 2009 at 21:48.

  2. The following user says thank you to JohannesMunk for this useful post:

    mortiferus (6th June 2011)

  3. #2
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Thumbs up Re: QGraphicsScene Widgets in OpenGL Projection

    FINALLY!!



    So stupid: Only thing wrong was, that I didn't call the inherited QGraphicsscene::MouseMove handler..

    Now everything works just fine!

    Code is still a bit messy, but should help to understand the concepts anyway.

    Hope it helps someone!

    Johannes
    Attached Files Attached Files
    Last edited by JohannesMunk; 2nd September 2009 at 14:22.

  4. The following 2 users say thank you to JohannesMunk for this useful post:

    mortiferus (6th June 2011), panithadrum (10th October 2013)

Similar Threads

  1. OpenGL and Qt Question
    By ToddAtWSU in forum Qt Programming
    Replies: 2
    Last Post: 18th April 2009, 18:04
  2. Saving QGraphicsScene with OpenGL to image
    By elbaschid in forum Qt Programming
    Replies: 1
    Last Post: 12th March 2009, 20:32
  3. multiple Opengl Widgets:
    By manmohan in forum Qt Programming
    Replies: 2
    Last Post: 2nd March 2009, 05:06
  4. OpenGL texture on QGraphicsScene background
    By Ovnan in forum Qt Programming
    Replies: 5
    Last Post: 11th July 2008, 10:39
  5. Using QGraphicsScene instead of OpenGL
    By ntp in forum Qt Programming
    Replies: 2
    Last Post: 7th April 2008, 21:16

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.