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,
"x211s215232200gw`fx`at[cx^cw^fu\itZerWn|ap~cv204jnzedq^fr^kzfhv^Ra"
"GRbMWdR\jXer^qw_311256226271253235275264252315277260304255"
"231u~i213225207l{fly`jx\^nRlz_z206nlx`t~i221211s372276243375"
"336275376352340356312301235216212judgwcl~f212226u}206h212"
"224q231237z232236{216225v225230200306274244376360327376"
"361331376360341326275272253240244{203p202220xp~e{204^222"
"230n212217g240242{234236z214222r270271247360353340376370"
"336376363334375357336310254262232223234\gRfrX204220z212"
"225g225232j254255177252250{225226u304302265374365351376"
"375366376367341376361320374346324306241242237232235n{fj"
"xckyfu~fUX@VZCfnT231231207374374371377372354376376374376376"
"372376362332375340301341300264260253262jvdbq\XkVJTDNTCCG8O"
"TE322321313377377375376376373376377376376376375376374362"
"376360342344311306250244254R_PL^HXkT<@2OP@`dP217220177374374"
"370377377374376375371377377376376374360377367336376350"
"316342303274246236245jtbXdQTdNQYGU\KchV317315302377376372377"
"376367376373360377376367376366337376355312374331271323"
"263251216214214\hTP^HL\FR[LMXI^dW355352342376375366377374"
"360376374361376374361376356321374331264374330266330270"
"260200||Y`SLVE>K9BJ<CN?VYP347330322376366345376363330376367"
"337377372350374342314326243210375350314352317304shc^`TV`"
"RVbT>B4IS?PTD244232216374355320376354311376351306376362332"
"374344321267206u375362337326274272\POMNBT]LNZH:<*<A*TV>OI;242"
"222207340304243375335262372336272376361334320241212374"
"352322266233237c\WFH;MR>\`F~xP220214[pqE211202\g]=230214`313"
"266207344303240362336274323257201333304240305252204254"
"232p216206\206203U232224b234244b246257m220232`224227h~202"
"W206213]204210W227227i|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.