QGLWidget Cube is not drawn
-
I have this example in QT4 which draws a cube with vowels using
QGLWidget
. However nothing gets drawn.The code to draw the cube looks like this:
void VowelCube::paintEvent(QPaintEvent * /*event*/) { QPainter painter(this); drawBackground(&painter); drawCube(); drawLegend(&painter); }
void VowelCube::drawCube() { glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); GLdouble x = 3.0 * GLdouble(width()) / height(); glOrtho(-x, +x, -3.0, +3.0, 4.0, 15.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glTranslatef(0.0, 0.0, -10.0); glScalef(scaling, scaling, scaling); glRotatef(rotationX, 1.0, 0.0, 0.0); glRotatef(rotationY, 0.0, 1.0, 0.0); glRotatef(rotationZ, 0.0, 0.0, 1.0); glEnable(GL_MULTISAMPLE); glCallList(glObject); setFont(QFont("Times", 24)); qglColor(QColor(255, 223, 127)); renderText(+1.1, +1.1, +1.1, QChar('a')); renderText(-1.1, +1.1, +1.1, QChar('e')); renderText(+1.1, +1.1, -1.1, QChar('o')); renderText(-1.1, +1.1, -1.1, QChar(0x00F6)); renderText(+1.1, -1.1, +1.1, QChar(0x0131)); renderText(-1.1, -1.1, +1.1, QChar('i')); renderText(+1.1, -1.1, -1.1, QChar('u')); renderText(-1.1, -1.1, -1.1, QChar(0x00FC)); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); }
The methods using
QPainter
work well and do there drawing part. However the OpenGL Part drawing the cube does nothing.
Is it an Issue because something change to QT5 ?The full Source code taken from C++ GUI Programming with QT4 can be found here:
https://github.com/cggos/CPPGUIProgrammingWithQt4/tree/master/chap20/vowelcube
-
You most likely forgot to set the current context - see https://doc.qt.io/qt-5/qglwidget.html#paintEvent
Simply don't use paintEvent() but paintGL(): https://doc.qt.io/qt-5/qglwidget.html#details -
There's an active painter while gl commands are issued and for this to work these calls need to be encapsulated in QPainter::beginNativePainting()/QPainter::endNativePainting() calls, for example like this:
void VowelCube::paintEvent(QPaintEvent * /* event */) { QPainter painter(this); drawBackground(&painter); painter.beginNativePainting(); drawCube(); painter.endNativePainting(); drawLegend(&painter); }
These methods were introduced in Qt 4.6 and I think the book targets something like 4.3, so maybe that's the reason.
On another note - while some parts of that book are perfectly valid today the parts about OpenGL are quite obsolete. I mean the code might work with some tweaks but its very inefficient and no code should be written today using these techniques.
In this example alone there is QGLWidget, fixed pipeline OpenGL and display lists - all very much obsolete and have only historical value. -
Thanks for the clarification. As i understand correctly from the docs the whole class
QGLWidget
is obsolet and should be replaced withQOpenGLWidget
.Out of curiosity i updatetd the paint event like menthioned. However only the cube gets drawn with OpenGL but is missing the vowels written on the cube.
it looks like all the
renderText
calls indrawCube()
still don't work. -
There's probably some minor tweak like that needed in another place, but, like I said - all this code (not only QGLWidget) is obsolete and I don't think it's wort the time to try and run it.
A modern OpenGL application uses shaders and buffers. Almost all (if not all) of the glXXX calls here should not be used anymore and have modern replacements.