Draw a rectangle on qglwidget at a specific time

I am using Qt 5.7 with C ++ on ubuntu 16.04. I am trying to implement a class that inherits qglwidget, which displays images on the screen at a given speed (3-10 Hz).

In addition to this, I want to draw a small rectangle somewhere on the screen that changes color from black to white and vice versa. It should switch from white to black when the image appears, and switch back to black for a certain predetermined time until the next image appears. Right now I'm using a texture to load images (from QImage objects) using

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); 

and this is my paintGL () overload:

 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); drawTexture(QRect(0,0,1,1),texture,GL_TEXTURE_2D); swapBuffers(); glDisable(GL_TEXTURE_2D); 

and I was wondering if it's possible to draw a widget and make it display both a rectangle and an image at the same time. I tried using QPainter, but continued to get a picture that caused the image to disappear (the rectangle should not be on the image, but on some corner of the widget where nothing is drawn).

Would thank for any help!

0
c ++ qt rendering opengl
source share
2 answers

This is a minimal sample application that mixes OpenGL and QPainter code in a paint handler:

 #include <QtWidgets> #include <QOpenGLFunctions_1_1> // manually added types (normally provided by glib) typedef unsigned guint; typedef unsigned char guint8; extern const struct Image { guint width; guint height; guint bytes_per_pixel; /* 3:RGB, 4:RGBA */ guint8 pixel_data[1]; } fluffyCat; class GLWidget: public QOpenGLWidget, protected QOpenGLFunctions_1_1 { private: float _step; GLuint _idTex; QTimer _qTimer; public: GLWidget(QWidget *parent = 0): QOpenGLWidget(parent), _step(0.0f), _idTex(0) { _qTimer.setInterval(100); // 100 ms -> 10 Hz QObject::connect(&_qTimer, &QTimer::timeout, this, &GLWidget::timeout); } protected: virtual void initializeGL(); virtual void paintGL(); private: void timeout(); }; void GLWidget::initializeGL() { initializeOpenGLFunctions(); glClearColor(0.525, 0.733f, 0.851, 1.0); glGenTextures(1, &_idTex); glBindTexture(GL_TEXTURE_2D, _idTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, fluffyCat.width, fluffyCat.height, 0, GL_RGB, GL_UNSIGNED_BYTE, fluffyCat.pixel_data); glBindTexture(GL_TEXTURE_2D, 0); _qTimer.start(); } void GLWidget::paintGL() { // prepare OpenGL rendering QPainter qPainter(this); qPainter.beginNativePainting(); // do OpenGL rendering glColor3f(1.0f, 1.0f, 1.0f); bool tex2dOld = glIsEnabled(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); static GLfloat envColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor); glBindTexture(GL_TEXTURE_2D, _idTex); float x = sin(_step) * 0.5f, y = cos(_step) * 0.5f; #if 0 // does not work (no tex-coords) glRectf(x - 0.5f, y - 0.5f, x + 0.5f, y + 0.5f); #else // (not) 0 glBegin(GL_QUADS); glColor3f(1.0f, 1.0f, 1.0f); glTexCoord2i(0, 1); glVertex2f(x - 0.5f, y - 0.5f); glTexCoord2i(1, 1); glVertex2f(x + 0.5f, y - 0.5f); glTexCoord2i(1, 0); glVertex2f(x + 0.5f, y + 0.5f); glTexCoord2i(0, 0); glVertex2f(x - 0.5f, y + 0.5f); glEnd(); #endif // 0 glBindTexture(GL_TEXTURE_2D, 0); //if (!tex2dOld) glDisable(GL_TEXTURE_2D); // prepare Qt painting qPainter.endNativePainting(); // do Qt painting (HUD) QPen qPen; qPen.setWidth(1); qPen.setColor(QColor(Qt::black)); qPen.setStyle(Qt::SolidLine); qPainter.resetMatrix(); qPainter.setPen(qPen); qPainter.drawLine(0, 0, width(), height()); qPainter.drawLine(0, height(), width(), 0); } void GLWidget::timeout() { _step = fmod(_step + 0.1, 2 * 3.141); update(); // force redraw } int main(int argc, char **argv) { QApplication app(argc, argv); QMainWindow win; GLWidget view3d; win.setCentralWidget(&view3d); win.show(); return app.exec(); } 

and texture image source:

 /* GIMP RGB C-Source image dump (fluffyCat.cc) */ // manually added types (normally provided by glib) typedef unsigned guint; typedef unsigned char guint8; struct Image { guint width; guint height; guint bytes_per_pixel; /* 3:RGB, 4:RGBA */ guint8 pixel_data[16 * 16 * 3 + 1]; }; extern const Image fluffyCat; const Image fluffyCat = { 16, 16, 3, "x\211s\215\232\200gw'fx'at[cx^cw^fu\\itZerWn|ap~cv\204jnzedq^fr^kzfhv^Ra" "GRbMWdR\\jXer^qw_\311\256\226\271\253\235\275\264\252\315\277\260\304\255" "\231u~i\213\225\207l{fly'jx\\^nRlz_z\206nlx't~i\221\211s\372\276\243\375" "\336\275\376\352\340\356\312\301\235\216\212judgwcl~f\212\226u}\206h\212" "\224q\231\237z\232\236{\216\225v\225\230\200\306\274\244\376\360\327\376" "\361\331\376\360\341\326\275\272\253\240\244{\203p\202\220xp~e{\204^\222" "\230n\212\217g\240\242{\234\236z\214\222r\270\271\247\360\353\340\376\370" "\336\376\363\334\375\357\336\310\254\262\232\223\234\\gRfrX\204\220z\212" "\225g\225\232j\254\255\177\252\250{\225\226u\304\302\265\374\365\351\376" "\375\366\376\367\341\376\361\320\374\346\324\306\241\242\237\232\235n{fj" " xckyfu~fUX@VZCfnT \231\231\207\374\374\371\377\372\354\376\376\374\376\376" "\372\376\362\332\375\340\301\341\300\264\260\253\262jvdbq\\XkVJTDNTCCG8O" "TE\322\321\313\377\377\375\376\376\373\376\377\376\376\376\375\376\374\362" "\376\360\342\344\311\306\250\244\254R_PL^HXkT<@ 2OP@ 'dP\217\220\177\374\374" "\370\377\377\374\376\375\371\377\377\376\376\374\360\377\367\336\376\350" "\316\342\303\274\246\236\245jtbXdQTdNQYGU\\KchV\317\315\302\377\376\372\377" "\376\367\376\373\360\377\376\367\376\366\337\376\355\312\374\331\271\323" "\263\251\216\214\214\\hTP^HL\\FR[LMXI^dW\355\352\342\376\375\366\377\374" "\360\376\374\361\376\374\361\376\356\321\374\331\264\374\330\266\330\270" "\260\200||Y'SLVE>K9BJ<CN?VYP\347\330\322\376\366\345\376\363\330\376\367" "\337\377\372\350\374\342\314\326\243\210\375\350\314\352\317\304shc^'TV'" "RVbT>B4IS?PTD\244\232\216\374\355\320\376\354\311\376\351\306\376\362\332" "\374\344\321\267\206u\375\362\337\326\274\272\\POMNBT]LNZH:<*<A*TV>OI;\242" "\222\207\340\304\243\375\335\262\372\336\272\376\361\334\320\241\212\374" "\352\322\266\233\237c\\WFH;MR>\\'F~xP\220\214[pqE\211\202\\g]=\230\214'\313" "\266\207\344\303\240\362\336\274\323\257\201\333\304\240\305\252\204\254" "\232p\216\206\\\206\203U\232\224b\234\244b\246\257m\220\232'\224\227h~\202" "W\206\213]\204\210W\227\227i|\177RvzNlsGrtJwtLz}N{\204RlxF", }; 

(Sorry for the poor image quality. A high resolution image that was too large for this site.)

These two files must be compiled and linked to each other. (Instead of using the header, I simply (re-) declared a variable in fluffyCat.cc at the beginning of another file.)

Qt project file testQGLWidgetHUD.pro :

 SOURCES = testQGLWidgetHUD.cc fluffyCat.cc QT += widgets opengl 

Snapshot of the testQGLWidgetHUD

By the way, I did not understand that the OP requested QGLWidget . The example uses the new QOpenGLWidget which is recommended with Qt5 +.

QTimer used for very simple animations (to show that periodic painting is being done).

Btw. I came across an error (which hit me for the first time ...) It is important to set GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER because these are two of the rare OpenGL states that do not work if you leave the default values.

+2
source share

Well, finally, it worked to add a small rectangle -

 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); QPainter qPainter(this); QPainterPath path; path.addRect(10, 10, 30,30); QPen pen(Qt::black, 1); qPainter.setPen(pen); qPainter.fillPath(path, Qt::black); qPainter.drawPath(path); qPainter.end(); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glShadeModel( GL_FLAT ); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_TEXTURE_2D); glColor3f(0.5, 0.5, 0); glBindTexture(GL_TEXTURE_2D, texture); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex2f(0.5f, -0.5f); // vertex 1 glTexCoord2f(0.0f, 0.0f); glVertex2f(0.5f, 0.5f); // vertex 2 glTexCoord2f(1.0f, 0.0f); glVertex2f(-0.5f, 0.5f); // vertex 3 glTexCoord2f(1.0f, 1.0f); glVertex2f(-0.5f, -0.5f); // vertex 4 glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); 
0
source share

All Articles