PDA

View Full Version : OpenGL Runtime Error



kango
17th February 2013, 17:45
Hi, I'm trying to animate the motion of the upper arm by using a series of x,y and z coordinates of the elbow. the runtime error occurs after i rotated for a while by using the mouse. i believe the error is due to the "counter++" in "void MyPanelOpenGL::mouseMoveEvent(QMouseEvent *event)" as the animation works if i don't try to do any rotation.

Can anyone help me solve this issue? Any help will be greatly appreciated. Thanks.



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


extern QList<FileData> points;
int counter = 0;



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

rotationY = -90.0;

}



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();
glOrtho(-60,60,-60,60,-620,620);
glMatrixMode(GL_MODELVIEW);

}

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

glColor3ub(0,0,0);

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

glEnd();
}

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

glColor3ub(0,0,0);

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

glEnd();
}

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

glColor3ub(0,0,0);


//Arm
glVertex3f(-50, 0, 0);
glVertex3f(points[i].ElbowY, -points[i].ElbowZ, points[i].ElbowX);

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();
drawarm(counter);

if ( counter < points.size()-1 )
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
counter++;
timer->start(500);

}

}



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();

counter++;
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
17th February 2013, 18:20
What is the size of "points"?

kango
18th February 2013, 01:22
size of "points" is the number of sets of data i've recorded into a QList. it exits the loop and stop redrawing after reading the last set of coordinates.

lanz
18th February 2013, 05:46
You are updating counter in two places, one time in paintGL, and second time in mouseMoveEvent.
Although you do check it in paintGL, you do it after calling drawarm (counter) with (possibly) incorrect counter value.

wysota
18th February 2013, 09:38
Furthermore you are creating new timers there each time you draw the scene. Which means a memory consumption and possibly wacky results. paintGL() is meant to paint the scene and only paint the scene, nothing more. No counting, no creating objects -- just painting. I think I already suggested in some other thread that you use a QPropertyAnimation instead of a timer. Please consider that, you'll get code that is predictable. In contrast your current code is not -- try to think what happens when you start resizing the window very quickly.

kango
18th February 2013, 15:14
Furthermore you are creating new timers there each time you draw the scene. Which means a memory consumption and possibly wacky results. paintGL() is meant to paint the scene and only paint the scene, nothing more. No counting, no creating objects -- just painting. I think I already suggested in some other thread that you use a QPropertyAnimation instead of a timer. Please consider that, you'll get code that is predictable. In contrast your current code is not -- try to think what happens when you start resizing the window very quickly.

Thanks for the suggestion but is it possible to gave me a quick example on how i can change to a QPropertyAnimation? i've read the documentation but still could not really understand as i'm very new to programming. Or is there anyway i could just add some constraints to my counter in my mouseEvent to make it work?

wysota
18th February 2013, 15:57
You need to add a property to your class representing the robot that keeps track of the current angle of the arm. Then you can animate this property having a start and end value for the angle. Qt will then interpolate the movement properly. I have no idea what your mouse move event is supposed to do so I can't give you a precise example for your usecase.

kango
18th February 2013, 16:22
unlike my previous program in another thread, my current program is using the coordinates of the elbow to plot out arm position instead of using angles. so my start value and end value will be the start and end value of my counter?

do you know of any good tutorials or examples on using qproperty from scratch?

the mouseevent is just to allow rotation of the view in the y-direction.

wysota
18th February 2013, 16:56
my current program is using the coordinates of the elbow to plot out arm position instead of using angles.
It doesn't change anything. A value is a value.


do you know of any good tutorials or examples on using qproperty from scratch?

Qt Reference Manual.