PDA

View Full Version : OpenGL update() function updating too fast



kango
13th February 2013, 16:43
Hi, i'm trying to animate a moving arm using opengl.

i'm using update() at the end of my paintGL() function but the animation is currently too quick. is there anyway i can control the speed of the update() function?

in addition, can i know what is the difference between update() and updateGL() as my program crashes when i used updateGL() instead of update()?

Any help will be appreciated. Thanks.

Below is my code

#include "mypanelopengl.h"
#include <cmath>



MyPanelOpenGL::MyPanelOpenGL(QWidget *parent) :
QGLWidget(parent)
{

angle = 0.0;
flag = true;

}




void MyPanelOpenGL::initializeGL()
{
qglClearColor(Qt::white);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
gluLookAt(-5,0,0,0,0,0,0,1,0);
}


void MyPanelOpenGL::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-5.0, 5.0, -5.0, 5.0, -15.0, 15.0);
glOrtho(0,10,0,10,-5,5);
glMatrixMode(GL_MODELVIEW);

}

void MyPanelOpenGL::drawspine()
{
glBegin(GL_LINES);

glColor3ub(0,0,0);

//Spine
glVertex3f(0, -5, 0);
glVertex3f(0, 5, 0);

glEnd();
}

void MyPanelOpenGL::drawshoulder()
{
glBegin(GL_LINES);

glColor3ub(0,0,0);

//Shoulder
glVertex3f(-5, 0, 0);
glVertex3f(5, 0, 0);

glEnd();
}

void MyPanelOpenGL::drawarm()
{
glBegin(GL_LINES);

glColor3ub(0,0,0);

//Arm
glVertex3f(-5, 0, 0);
glVertex3f(-5, -5, 0);

glEnd();

}


void MyPanelOpenGL::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslated(5.0, 5.0, 0.0);
glLineWidth(1);
glColor3f(0, 0.7f, 0.7f);


glRotatef(rotationY, 0.0, 1.0, 0.0);


drawspine();
drawshoulder();
glPushMatrix();
glRotatef(angle,1,0,0);
drawarm();
glPopMatrix();
if(flag)
{
if(angle <90)
angle++;
else
flag = false;
}
else
{
if(angle > 0)
angle--;
else
flag = true;
}


update();

}



void MyPanelOpenGL::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
}

void MyPanelOpenGL::mouseMoveEvent(QMouseEvent *event)
{
GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
} else if (event->buttons() & Qt::RightButton) {
rotationX += 180 * dy;
rotationZ += 180 * dx;
updateGL();
}
lastPos = event->pos();
}

wysota
13th February 2013, 16:51
i'm using update() at the end of my paintGL() function
That doesn't make sense.


is there anyway i can control the speed of the update() function?
Use a QTimer, QTimeLine or a QPropertyAnimation.


in addition, can i know what is the difference between update() and updateGL() as my program crashes when i used updateGL() instead of update()?
You can look it up in Qt source code: http://qt.gitorious.org/qt/qt/blobs/4.8/src/opengl/qgl.cpp

updateGL() calls glDraw(), update() schedules a paint event which ultimately calls both glDraw() and updateOverlayGL().

Your crash is caused by an infinite loop that happens because from within code called as a result of updateGL() you synchronously call updateGL() again.

kango
13th February 2013, 17:32
QTimer solved my problem. Thanks so much.

wysota
13th February 2013, 17:53
I had a quick look at your code. I really suggest you make "angle" a property and use QPropertyAnimation instead of that timer. This will give you much better control over what is going on in your program assuming you want it to do some more things than to just animate one single arm movement or if you want to make it look more realistic (e.g. by changing linear movement to non-linear one that contains some ease-in/ease-out behaviour).