PDA

View Full Version : How to update a OpenGL GLWidget embedded within QT?



sonda
19th March 2013, 01:29
Hi everyone!
I am developing a really simple application using QT and OpenGL. The application contains a few buttons for interaction and a widget tab containing 3 pages, the first two for analysing and processing some data and the third contains a GLWidget which should draw the result points in a 3d space.
At the beginning the 3d space doesn't contain any points and after all the data are processed it should draw the 3 points.
So far I have tried to call an external function to paintGL() to draw a solid cube at the centre of the scene. The method is correctly called but the widget does not display any cube.
If you want I can post part of the code and if you have any questions then please do not hesitate to ask me.
I hope someone of you can help me with this.

wysota
19th March 2013, 06:31
Just call update() on the widget.

sonda
19th March 2013, 15:17
I have tried but it doesn't work, so I decided to post my code.

glwidget.cpp


GLWidget::GLWidget(QWidget *parent) :
QGLWidget(parent)
{
connect(&timer, SIGNAL(timeout()), this, SLOT(updateGL()));
timer.start(1000);
}

void GLWidget::initializeGL(int w, int h) {
glClearColor(0.2f, 0.2f, 0.2f, 1);
glViewport(0, 0, w, h);
// Setup light
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = {2.0f, 5.0f, 5.0f, 0.0f };
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_DOUBLE);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glDepthFunc(GL_LESS);
glEnable(GL_COLOR_MATERIAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 0.0001, 1000.0);
glMatrixMode(GL_MODELVIEW);
current_view= TOP_VIEW;

}

/ Display
void GLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
setView();
if (current_view == EXPLORING_VIEW)
calculate_lookpoint();
gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
// Draw axis and add points
drawAxis();
int ind;
Skyline s;
if (s.skylineGenerated()) {
drawCube();
cout << "Generated" << endl;
}
swapBuffers();
}

void GLWidget::drawCube(void){
cout << "Drawn\n";
glTranslatef(0.0,0.0,0.0);
glColor3f(1.0,0.0,0.0);
glutSolidCube(2.0);
update();
}

// Reshape
void GLWidget::resizeGL(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (48.0, (GLfloat) w/(GLfloat) h, 10.0, 800.0);
glMatrixMode (GL_MODELVIEW);
}



Despite the fact I call update(), when I click on the tab containing this widget no cube is shown. Furthermore the light is not working. Can you please help me? Ah I have the entire Opengl program in a class and everything is working but I don't understand why the GLWidget is not working like the original program.

wysota
19th March 2013, 16:25
Your drawCube() doesn't make sense. If you want to draw something, you are supposed to call update() and draw what needs to be drawn in paintGL().

sonda
19th March 2013, 16:35
I have modified the code for paintGL() but this time everything (axis and cube) is rotating:


void GLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
setView();
if (current_view == EXPLORING_VIEW)
calculate_lookpoint();
gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
// Draw axis and add points
drawAxis();
int ind;
Skyline s;
if (s.skylineGenerated()) {
glPushMatrix();
glTranslatef(0.0,0.0,0.0);
glColor3f(1.0,0.0,0.0);
glRotatef(0.5,1,0,1);
glSolidCube(2.0);
glPopMatrix();
update();
}
swapBuffers();
}


And why the light is not working?

wysota
19th March 2013, 17:51
You are not supposed to be calling update() from within paintGL(). The latter will be called by Qt as a result of the call to the former. Have you gone through at least one Qt OpenGL example?

sonda
19th March 2013, 18:21
Yes I have seen lots of examples. Anyway I have decided to use my original program and execute it within the GLWidget. So I added this line


void Sk::on_pushButton_clicked()
{

process.start("/home/user/Desktop/Test");

}


How can I display the external program within the GLWidget?

wysota
19th March 2013, 18:25
How can I display the external program within the GLWidget?
You can't.

sonda
19th March 2013, 18:31
But I have read about QX11embedContainer, I have tried to include the library but it gives me an error. So the only way to run that executable is to use an external window???

wysota
19th March 2013, 20:23
But I have read about QX11embedContainer, I have tried to include the library but it gives me an error.
QX11EmbedContainer requires "the other application" to know how to embed itself into a given X window.


So the only way to run that executable is to use an external window???
Basically yes.