Paint a rect on qglwidget at specifit times

后端 未结 2 1125

I\'m using Qt 5.7 with c++ on ubuntu 16.04. I\'m trying to implement a class that inherits qglwidget, that renders images to the screen at a given rate (3-10 Hz).

I

相关标签:
2条回答
  • 2020-12-02 02:13

    This is a minimal sample application which mixes OpenGL code and QPainter in 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 the source for the texture image:

    /* 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 low image quality. Hi-res picture whould have been too large for this site.)

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

    The Qt project file testQGLWidgetHUD.pro:

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

    By the way, I didn't realize the OP was asking for QGLWidget. The sample uses the new QOpenGLWidget which is recommended since Qt5+.

    The QTimer is used for very simple kind of animation (to show that periodical painting is done).

    Btw. I stumbled upon a mistake (which hit me not 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 which do not work if left with default values.

    0 讨论(0)
  • 2020-12-02 02:16

    Well, finally this worked for adding a small 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);
    
    0 讨论(0)
提交回复
热议问题