PDA

View Full Version : QGLWidget override not updating



Dan42
24th April 2016, 04:18
So, I'm trying bring over some code to a Qt project I'm working on. Previously I had a interaction class which allowed me to interact with an openGL window. I'm trying to use the same code (modified for Qt) to allow me to interact with a QGLWidget.

The problem being, that there is no change to the initial output. The code plots the initial input, but after that, their is no change due to mouse events, keyboard events, etc. There is a lot more code, but hopefully this should be sufficient to answer my question. I'm also a bit of a novice and just started playing with Qt, so with any luck it's not something too stupid.

QGLWidget Header:


#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QGLWidget>
#include "Point2D.h"

class GLWidget : public QGLWidget
{
Q_OBJECT

public:
GLWidget(QWidget *parent);
~GLWidget();

void initializeGL();
void resizeGL(int, int);
void paintGL();
void mousePressEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void keyPressEvent(unsigned char, int, int);

private:
static double m_xRotate;
static double m_yRotate;
static double m_zRotate;
static double m_xTrans;
static double m_yTrans;
static double m_zTrans;
static Point2D m_LDownPos;
static Point2D m_RDownPos;
static Point2D m_MDownPos;
static int m_LButtonDown;
static int m_RButtonDown;
static int m_MButtonDown;

};

#endif // GLWIDGET_H

QGLWidget Class:


#include "glwidget.h"
#include <QMouseEvent>
#include <stdlib.h>
#include <GL\glut.h>

#include "Curve.h"
#include "Color.h"


#define TRUE 1
#define FALSE 0

extern unsigned C;

Point2D GLWidget::m_LDownPos;
Point2D GLWidget::m_RDownPos;
Point2D GLWidget::m_MDownPos;
int GLWidget::m_LButtonDown;
int GLWidget::m_RButtonDown;
int GLWidget::m_MButtonDown;
double GLWidget::m_xRotate;
double GLWidget::m_yRotate;
double GLWidget::m_zRotate;
double GLWidget::m_xTrans;
double GLWidget::m_yTrans;
double GLWidget::m_zTrans;


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

}

GLWidget::~GLWidget()
{

}

void GLWidget::initializeGL()
{

glClearColor(1.0, 1.0, 1.0, 1.0);

GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_FILL);
gluQuadricNormals(qobj, GLU_SMOOTH);


//glClearColor (0.0, 0.0, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
// specify the back of the buffer as clear depth
glClearDepth(1.0f);

double eqn[] = { 0.01f,0.0f,0.01f,-1.0f };
// enable clip plane
glClipPlane(GL_CLIP_PLANE0, eqn);

float LightAmbient[] = { 1.0f, 1.0f, 1.0f, 1.0 };
float LightDiffuse[] = { 0.7f, 0.7f, 0.7f, 1.0f };
float LightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float LightPosition[] = { 3.0f, 3.0f, 3.0f, 1.0f };

float RedSurface[] = { 1.0f, 0.0f, 0.0f, 1.0f };
float GreenSurface[] = { 0.0f, 1.0f, 0.0f, 1.0f };
float BlueSurface[] = { 0.0f, 0.0f, 1.0f, 1.0f };

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);

glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);

float no_mat[] = { 0.0f,0.0f,0.0f,1.0f };
float mat_ambient[] = { 0.7f,0.7f,0.7f,1.0f };
float mat_ambient_color[] = { 0.8f,0.3f,0.7f,1.0f };
float mat_diffuse[] = { 0.7f,0.7f,0.7f,1.0f };

float mat_specular[] = { 0.7f,0.7f,0.7f,1.0f };

float no_shininess[] = { 0.0 };
float low_shininess[] = { 5.0 };
float high_shininess[] = { 100.0 };
float mat_emission[] = { 0.2f,0.1f,0.1f,0.0f };

glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
//glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);

}

void GLWidget::resizeGL(int w, int h)
{
//Setup Viewing Transform: This calculates windows coordinates
glViewport(0, 0, (GLsizei)w, (GLsizei)h);

//Setup Projection: Device coordinates
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0f, (double)w / (double)h, 0.1f, 1000.0f);

//Set up Modeling and Viewing transform: Get Eye coordinates
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -10.0f);

}

void GLWidget::paintGL()
{
static Curve m;
m.calculateSwitch();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glTranslated(m_xTrans, m_yTrans, m_zTrans);
glRotated(m_xRotate, 1.0, 0.0, 0.0);
glRotated(m_yRotate, 0.0, 1.0, 0.0);
glRotated(m_zRotate, 0.0, 0.0, 1.0);

glMaterialfv(GL_FRONT, GL_DIFFUSE, BROWN);

m.drawCtrlPositions();

if (C == 1)
{
m.readCtrlPositions("input.txt", "v");
m.drawCtrlPositions();
}

glPopMatrix();

swapBuffers();
}

void GLWidget::mousePressEvent(QMouseEvent *e)
{
QMouseEvent *m = e;
int x = m->x();
int y = m->y();

switch (m->button())
{
case Qt::LeftButton:
m_LButtonDown = TRUE;
m_LDownPos.setPx(x);
m_LDownPos.setPy(y);
break;
case Qt::RightButton:
m_RButtonDown = TRUE;
m_RDownPos.setPx(x);
m_RDownPos.setPy(y);
break;
case Qt::MiddleButton:
m_MButtonDown = TRUE;
m_MDownPos.setPx(x);
m_MDownPos.setPy(y);
break;
default:
break;

} //End of switch

updateGL();
}

void GLWidget::mouseReleaseEvent(QMouseEvent *e)
{
QMouseEvent *m = e;

switch (m->button())
{
case Qt::LeftButton:
m_LButtonDown = FALSE;
break;
case Qt::RightButton:
m_RButtonDown = FALSE;
break;
case Qt::MiddleButton:
m_MButtonDown = FALSE;
break;
default:
break;

} //End of switch

updateGL();
}

void GLWidget::mouseMoveEvent(QMouseEvent *e)
{
QMouseEvent *m = e;
int x = m->x();
int y = m->y();

/* find out what action to perform */
if (m->button() == Qt::LeftButton)
{
m_yRotate -= (m_LDownPos.getPx() - (double)x) / 2.0;
m_xRotate -= (m_LDownPos.getPy() - (double)y) / 2.0;

m_LDownPos.setPx(x);
m_LDownPos.setPy(y);
}

if (m->button() == Qt::RightButton)
{
m_xTrans -= (m_RDownPos.getPx() - (double)x) / 10.0f;
m_yTrans += (m_RDownPos.getPy() - (double)y) / 10.0f;

m_RDownPos.setPx(x);
m_RDownPos.setPy(y);
}

if (m->button() == Qt::MiddleButton)
{
m_zTrans -= (m_MDownPos.getPy() - (double)y) / 10.0f;

m_MDownPos.setPx(x);
m_MDownPos.setPy(y);
}

updateGL();
}

void GLWidget::keyPressEvent(unsigned char Key, int x, int y)
{
switch (Key)
{
case 27:
case 'q':
exit(0);
break;
};

updateGL();
}

d_stranz
24th April 2016, 18:15
First, what is the point of making all of your coordinate and transform variables static members of the class? They aren't used in a way that would require it, and in fact will prevent you from using another instance of the same class in a different window - all the variables will have the same value everywhere.

Not only that, but if I am following the code correctly, they never get initialized before they are used in paintGL(). m_xTrans, for example doesn't appear to have any value assigned until the mouseMoveEvent occurs, and then only if the right button is pressed. So until you move the mouse with the right button pressed, it has whatever value the compiler decided to randomize it to. Likewise all of your other variables.

I think your problem is more a lack of C++ experience than it is a lack of Qt knowledge.

First, what is the point of making all of your coordinate and transform variables static members of the class? They aren't used in a way that would require it, and in fact will prevent you from using another instance of the same class in a different window - all the variables will have the same value everywhere.

Not only that, but if I am following the code correctly, they never get initialized before they are used in paintGL(). m_xTrans, for example doesn't appear to have any value assigned until the mouseMoveEvent occurs, and then only if the right button is pressed. So until you move the mouse with the right button pressed, it has whatever value the compiler decided to randomize it to. Likewise all of your other variables.

I think your problem is more a lack of C++ experience than it is a lack of Qt knowledge.

Dan42
24th April 2016, 22:28
Hey, thanks for the response. So, I followed your recommendation and removed the static condition from the member variables. I also initialize the variables to zero. This gave me the same output as before.

This still leaves me with the same problem I was having before. An inability to interact with the QGLWidget. I suspect the mouse events are being calculated, but not displayed for some reason as there is an increase in processor usage when I attempt to interact with the widget. Would you be able to help me solve this issue?

d_stranz
25th April 2016, 20:33
Don't know why my comment double-posted. The site hiccuped when I clicked "Post Quick Reply" and I guess that's the result.

You have some mystery code in there - like the static Curve variable "m" that calls "calculateSwitch() and then is used to "drawCtrlPositions()".

By the way, you have a call to swapBuffers() at the end of paintGL(). You know that QGLWidget automatically swaps buffers by default on exit from paintGL(), right? (QGLWidget::setAutoBufferSwap()) So maybe your failure to see any changes is because as soon as you swap buffers to the updated one, QGLWidget swaps back to the old one.