Dipingi un rect su qglwidget in momentjs specifici

Sto usando Qt 5.7 con c ++ su Ubuntu 16.04. Sto cercando di implementare una class che eredita qglwidget, che rende le immagini sullo schermo ad una velocità determinata (3-10 Hz).

In aggiunta a ciò voglio disegnare un piccolo rect da qualche parte sullo schermo che cambia colore dal nero al bianco e viceversa. Dovrebbe passare dal bianco al nero quando appare l’immagine e tornare al nero un po ‘di tempo predefinito prima che arrivi l’immagine successiva. In questo momento sto usando una texture per caricare le immagini (dagli oggetti di QImage), usando

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

e questo è il mio sovraccarico paintGL ():

 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); 

e mi chiedevo se fosse ansible disegnare sul widget e renderlo sia il rect che l’immagine allo stesso tempo. Ho provato a usare QPainter, ma continuando a ottenere che il disegno il rect ha fatto scomparire l’immagine (il rect non dovrebbe essere sull’immagine, ma in qualche angolo del widget dove nulla è disegnato ora).

Gradirei qualsiasi aiuto!

    Questa è un’applicazione di esempio minima che miscela il codice OpenGL e QPainter nel gestore di vernice:

     #include  #include  // 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(); } 

    e la fonte per l’immagine della trama:

     /* 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" "[email protected]\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<@[email protected]`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>K9BJB4IS?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:<*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", }; 

    (Ci scusiamo per la scarsa qualità dell’immagine. L’immagine ad alta risoluzione sarebbe stata troppo grande per questo sito.)

    I due file devono essere compilati e da colbind insieme. (Invece di usare un’intestazione, ho semplicemente (ri) dichiarato la variabile in fluffyCat.cc all’inizio di un altro file.)

    Il file di progetto Qt testQGLWidgetHUD.pro :

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

    Istantanea del testQGLWidgetHUD

    A proposito, non mi ero reso conto che l’OP stava chiedendo QGLWidget . L’esempio utilizza il nuovo QOpenGLWidget che è raccomandato da Qt5 +.

    Il QTimer è usato per un tipo di animazione molto semplice (per mostrare che la pittura periodica è fatta).

    Btw. Mi sono imbattuto in un errore (che non mi ha colpito la prima volta …) È importante impostare GL_TEXTURE_MIN_FILTER e GL_TEXTURE_MAG_FILTER perché questi sono due dei rari stati OpenGL che non funzionano se vengono lasciati con valori predefiniti.

    Bene, finalmente questo ha funzionato per aggiungere un piccolo rect –

     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);