在指定时间在qglwidget上绘制矩形 [英] Paint a rect on qglwidget at specifit times
问题描述
我在ubuntu 16.04上使用带有C ++的Qt 5.7.我正在尝试实现一个继承qglwidget的类,该类以给定的速率(3-10 Hz)将图像呈现到屏幕上.
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).
除此之外,我想在屏幕上的某个地方绘制一个小矩形,将其颜色从黑色更改为白色,反之亦然.当图像出现时,它应该从白色切换为黑色,并在下一个图像出现之前的预定时间切换回黑色. 现在,我正在使用
In addition to that I want to draw a small rect somewhere on the screen that changes its color from black to white and vice-versa. It should switch from white to black when the image appears, and switch back to black some predefined time before the next image comes. Right now I'm using a texture to load the images (from QImage objects), using
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
这是我的paintGL()重载:
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);
,我想知道是否有可能在小部件上绘制并使其同时渲染rect和图像.我尝试使用QPainter,但是一直在获取该rect来使图像消失(该rect不应该在图像上,而应该在小部件的某个角上,而现在什么也没画出来).
and I was wondering if it possible to draw on the widget and make it render both the rect and image at the same time. I've tried using QPainter but kept getting that drawing the rect made the image disappear(the rect shouldn't be on the image, but on some corner of the widget where nothing is drawn now).
非常感谢您的帮助!
推荐答案
这是一个最小的示例应用程序,它在绘制处理程序中混合了OpenGL代码和QPainter
:
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();
}
以及纹理图像的来源
/* 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.)
这两个文件必须编译并链接在一起. (我没有使用标头,而是在另一个文件的开头简单地(重新)声明了fluffyCat.cc中的变量.)
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.)
Qt项目文件testQGLWidgetHUD.pro
:
SOURCES = testQGLWidgetHUD.cc fluffyCat.cc
QT += widgets opengl
顺便说一句,我没有意识到OP要求的是QGLWidget
.该示例使用自Qt5 +以来推荐的新QOpenGLWidget
.
By the way, I didn't realize the OP was asking for QGLWidget
. The sample uses the new QOpenGLWidget
which is recommended since Qt5+.
QTimer
用于非常简单的动画类型(以表明完成了定期绘画).
The QTimer
is used for very simple kind of animation (to show that periodical painting is done).
顺便说一句.我偶然发现一个错误(这不是第一次打我...)
设置GL_TEXTURE_MIN_FILTER
和GL_TEXTURE_MAG_FILTER
很重要,因为这是两种罕见的OpenGL状态,如果保留默认值,它们将不起作用.
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.
这篇关于在指定时间在qglwidget上绘制矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!