首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在特定时间在qglwidget上绘制矩形

在特定时间在qglwidget上绘制矩形
EN

Stack Overflow用户
提问于 2017-02-23 22:04:53
回答 2查看 947关注 0票数 0

我在ubuntu16.04上使用带有c++的Qt 5.7。我正在尝试实现一个继承qglwidget的类,它以给定的速率(3-10 Hz)将图像渲染到屏幕上。

除此之外,我想在屏幕上的某个地方画一个小矩形,它的颜色从黑色变成白色,反之亦然。它应该在图像出现时从白色切换到黑色,并在下一张图像到来之前的某个预定时间切换回黑色。现在,我正在使用纹理加载图像(来自QImage对象),使用

代码语言:javascript
复制
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());

这是我的paintGL()重载:

代码语言:javascript
复制
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);

我想知道是否有可能在小部件上绘制,并使其同时渲染矩形和图像。我试过使用QPainter,但一直在绘制矩形使图像消失(矩形不应该在图像上,而是在小部件的某个角落,现在什么都没有绘制)。

将非常感谢您的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-24 00:09:19

这是一个在绘图处理程序中混合了OpenGL代码和QPainter的最小示例应用程序:

代码语言:javascript
复制
#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();
}

和纹理图像的源:

代码语言:javascript
复制
/* 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",
};

(对不起,画质不好。高分辨率图片对于这个站点来说可能太大了。)

这两个文件必须编译并链接在一起。(我没有使用头文件,而是在另一个文件的开头用fluffyCat.cc (重新)声明了这个变量。)

Qt项目文件testQGLWidgetHUD.pro

代码语言:javascript
复制
SOURCES = testQGLWidgetHUD.cc fluffyCat.cc

QT += widgets opengl

顺便说一下,我没意识到特工要找的是QGLWidget该示例使用自Qt5+以来推荐的新QOpenGLWidget

QTimer用于非常简单的动画类型(以显示已完成周期性绘制)。

顺便说一句。我偶然发现了一个错误(这并不是第一次打击我...)设置GL_TEXTURE_MIN_FILTERGL_TEXTURE_MAG_FILTER很重要,因为这是两种罕见的OpenGL状态,如果保留默认值,它们将不起作用。

票数 2
EN

Stack Overflow用户

发布于 2017-02-27 18:50:56

好的,最后这对添加一个小长方体起作用了-

代码语言:javascript
复制
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);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42417987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档