PDA

View Full Version : converting GLUT/OpenGL to Qt/OpenGL - displaying issue



yoti13
23rd November 2012, 12:05
I am working on converting a pure GLUT/OpenGL/OpenCL code into Qt/OpenGL/OpenCL. For this, I use QGLWidget subclass named "GLWidget" for displaying the animation. My issue is that I would like to keep the GLUT displayfunc working of the first code : in main GLUT loop, I used `glutDisplayFunc(displayfunc);`

So, in the Qt/OpenGL, I tried to do this :


void GLWidget::initializeGL()
{
LoadGLTextures(); // load the textures.
glClearColor(0.0 ,0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

m_program = _compileProgram(vertexShader);

glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE);

// memsize of GPU data
unsigned int memSize = sizeof(cl_double4) * 4 * Galaxy->getNumParticles();

createVBO(memSize);

m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(displayfunc()));
m_timer->start(30);
}

with displayfunc :




void GLWidget::displayfunc()
{
if (Galaxy->isFirstLaunch)
{
gluLookAt (0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glScalef(0.03f, 0.03f, 0.03f);
drawPoints();
//Calling kernel for calculatig subsequent positions
Galaxy->runCLKernels();
Galaxy->isFirstLaunch = false;
glFlush();
swapBuffers();
return;
}
else {
clWaitForEvents(1, &Galaxy->glEvent);
drawPoints();
//Calling kernel for calculatig subsequent positions
Galaxy->runCLKernels();
glFlush();
swapBuffers();
}
update();
}

and drawPoints :


void GLWidget::drawPoints()
{
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_POINT_SPRITE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);

glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE);

glUseProgram(m_program);
glUniform1f( glGetUniformLocation(m_program, "pointRadius"), m_particleRadius );
glUniform1f( glGetUniformLocation(m_program, "pointScale"),m_pointScale);

GLuint vbo_disk;

glBindBuffer(GL_ARRAY_BUFFER, vbo_disk);
glVertexPointer(4, GL_DOUBLE, 4*sizeof(double), Galaxy->pos);
glEnableClientState(GL_VERTEX_ARRAY);

glColor4f(1.0f, 1.0f, 1.0f, 0.1f);
glDrawArrays(GL_POINTS, 0, Galaxy->getNumParticles_disk());

glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);

GLuint vbo_halo;

glBindBuffer(GL_ARRAY_BUFFER, vbo_halo);
glVertexPointer(4, GL_DOUBLE, 4*sizeof(double), &Galaxy->pos[Galaxy->getNumParticles_disk()]);
glEnableClientState(GL_VERTEX_ARRAY);

glColor4f(0.0f, 0.0f, 1.0f, 0.1f);
glDrawArrays(GL_POINTS, 0, Galaxy->getNumParticles_halo());

glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);

glDisable(GL_BLEND);
glDisable(GL_POINT_SPRITE);
}

Can I do without paintGL() function ?

I tried to add makeCurrent() into all the functions containing OpenGL functions but nothing displays in GLWidget, just black screen because of `glClearColor(0.0 ,0.0, 0.0, 0.0)`

Could you see what's wrong ?

d_stranz
25th November 2012, 00:45
QGLWidget:: paintGL() is called from the QGLWidget:: paintEvent() handler. Prior to calling this, QGLWidget sets the current GL context (by internally calling makeCurrent()). Implement paintGL() in your GLWidget derived class, and call your displayFunc() directly from that.

The whole point of using QGLWidget is that it provides its own internal callbacks for the OpenGL initialization, reshape, and display functions. So DO NOT install your own callback functions or make your own GL event loop.

If you set a breakpoint in your displayFunc method (which apparently you haven't), you will see that in your current implementation it never gets called, because your GLWidget has replaced your glutDisplayFunc callback with its own. So, either move your displayFunc() code into paintGL() or call it from paintGL(). If you do not reimplement paintGL in your own widget, nothing will ever be painted.

Likewise, you have to do the same with the other gl / glut callbacks - reimplement initializeGL(), resizeGL(), paintGL() (and the overlay versions of all of these if you use overlays), do not use gl / glut callbacks directly because QGLWidget will replace them.