QOpenGL QTimer, how do I animate this?
Hi everyone,
I'm drawing a large amount of triangles on the screen using the intialize-resize-paint method.
The program works, but without animation.
I've been trying for a long time to figure out how to use a Timer to animate this, but I haven't been able to find a way.
(Background info: the animation I want is to make the triangles rotate and scale individually.)
Can somebody help me?
Since it is quite a large program, I have brought the code down to structure only.
Thank you ahead of time!
In the main:
Code:
int main(int argc, char **argv)
{
GlWidget w;
w.show();
return a.exec();
}
In the glwidget header file:
Code:
{
Q_OBJECT //this macro is included because we might want to use signals and slots
public:
~GlWidget();
QSize sizeHint
() const;
//to set reasonable default sizes
protected:
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
private:
makeTriangles();
QVector<QVector3D> vertices, colors;
};
In the glwidget source file:
Code:
#include "glwidget.h"
//! [0]
{
}
GlWidget::~GlWidget()
{
}
QSize GlWidget
::sizeHint() const {
}
//! [0]
//! [1]
void GlWidget::initializeGL()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
shaderProgram.link();
makeTriangles();
}
//! [1]
//! [2]
void GlWidget::resizeGL(int width, int height)
{
if (height == 0) {
height = 1;
}
pMatrix.setToIdentity();
pMatrix.perspective(60.0, (float) width / (float) height, 0.001, 1000);
glViewport(0, 0, width, height);
}
//! [2]
//! [3]
void GlWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 mMatrix;
QMatrix4x4 vMatrix;
shaderProgram.bind();
shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
shaderProgram.setAttributeArray("color", colors.constData());
shaderProgram.enableAttributeArray("color");
shaderProgram.setAttributeArray("vertex", vertices.constData());
shaderProgram.enableAttributeArray("vertex");
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
shaderProgram.disableAttributeArray("vertex");
shaderProgram.disableAttributeArray("color");
shaderProgram.release();
}
GlWidget::makeTriangles()
{
/*specify vertices and colors of triangles, here, the variables vertices and color are defined*/
}
//! [3]
Re: QOpenGL QTimer, how do I animate this?
How are you using the timer? I think the simplest approach would be to make each triangle a QObject and use QPropertyAnimation to animate its state. Then through the use of signals, notify the view that it needs to be redrawn.
Re: QOpenGL QTimer, how do I animate this?
One way would be to add Qt properties for values you want to animate individually and then use QPropertyAnimation to drive the value changes.
You would then also connect the properties' change signals to the updateGL() slot, so that it is called whenever any of those properties changes.
Cheers,
_
Re: QOpenGL QTimer, how do I animate this?
I tried using a QTimer, (copying the idea from a graphicsscene application I have made)
adding a declaration in the header:
Code:
public slots:
void doSomething();
adding the following lines to the constructor:
Code:
connect(timer1,SIGNAL(timeout()),this, SLOT(doSomething()));
timer1->start(10);
and finally adding the slot definition in the source file to test:
Code:
void GlWidget::doSomething()
{
qDebug() << "I'm doing something!"; //here I would like to call the function makeTriangles() to change the properties 'colors' and 'vertices'
}
But this apparentlly doesn't work.
Quote:
I think the simplest approach would be to make each triangle a QObject and use QPropertyAnimation to animate its state. Then through the use of signals, notify the view that it needs to be redrawn.
Could you give me an example on how to do this, I have no clue how to implement that?
Re: QOpenGL QTimer, how do I animate this?
Quote:
Originally Posted by
JerichoJosh
Could you give me an example on how to do this, I have no clue how to implement that?
Have a look at the Animation Framework docs.
Re: QOpenGL QTimer, how do I animate this?
Could you help me to implement a QTimer?
the documentation you gave me remains too abstract for me, and mostly related to qPainter
Re: QOpenGL QTimer, how do I animate this?
I think what you will have to do is change values in your time slot and then call updateGL()
That will result in another call to paintGL() in which you can update your GL data.
Cheers,
_
Re: QOpenGL QTimer, how do I animate this?
Quote:
Originally Posted by
JerichoJosh
Could you help me to implement a QTimer?
the documentation you gave me remains too abstract for me, and mostly related to qPainter
There is not a single reference to QPainter in the documentation I gave you.
Re: QOpenGL QTimer, how do I animate this?
Use QOpenGLWindow with the frameSwapped signal. This is my example with Qt 6.7 that prints delta time to the console:
main.cpp
Code:
#include <QtCore/QElapsedTimer>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QSurfaceFormat>
#include <QtOpenGL/QOpenGLWindow>
#include <QtWidgets/QApplication>
class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
{
public:
OpenGLWindow()
{
setTitle("OpenGL ES 2.0, Qt6, C++");
resize(380, 380);
QSurfaceFormat surfaceFormat;
surfaceFormat.setSwapInterval(1);
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
setFormat(surfaceFormat);
}
private:
void initializeGL() override
{
initializeOpenGLFunctions();
glClearColor(0.2f, 0.2f, 0.2f, 1.f);
m_elapsedTimer.start();
}
void resizeGL(int w, int h) override
{
glViewport(0, 0, w, h);
}
void paintGL() override
{
float dt = m_elapsedTimer.elapsed() / 1000.f;
m_elapsedTimer.restart();
qDebug() << dt;
glClear(GL_COLOR_BUFFER_BIT);
}
private:
QElapsedTimer m_elapsedTimer;
};
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt
::ApplicationAttribute::AA_UseDesktopOpenGL);
OpenGLWindow w;
w.show();
return app.exec();
}