OpenGL and Threads



  • Hi

    I'm developing a software that displays a complex object made by faces (12). Each face is calculated using some CPU intensive calculations, and the face with higher resolution has 16793604 vertexs.

    For the viewer I'm using libQGLViewer that enables zoom and rotation, and I'm offloading the CPU intensive calculations for a working thread. The problem is that I can't create a OpenGL display list inside that working thread, and if I construct it in the main thread, it takes around 2 seconds for create a display list for each face, and it freezes the user interaction (as obvious).

    There is any way of create that display lists in the working thread ? I have read some documentation, and some forum posts, and I think it can solved by creating a new context for each working thread, and then share that context with the main thread, but until now I couldn't make it working.

    @
    QGLContext* newContext = new QGLContext(QGLFormat::defaultFormat());
    newContext->create();
    @

    I tried this code, but I get seg. fault when creating a display list.

    The class that use this code needs to inherit from some OpenGL widget ?
    There are some code missing ?

    Thanks in advice



  • Did you call
    @
    newContext->makeCurrent();
    @
    ? You always have to do this before using gl*() commands...

    Apart from that, maybe these links will help you:

    http://doc.qt.nokia.com/qq/qq06-glimpsing.html#writingmultithreadedglapplications

    http://git.zx2c4.com/qt/tree/tests/auto/qglthreads/tst_qglthreads.cpp?h=master-stable&id=7cd7785deb5d2cccaa712699c1dda1980a5983e5



  • I tried the makeCurrent but I got error.

    As suggested by pcpower in irc (thanks), I have changed my code, and now instead of display lists I'm using Virtual Buffer Objects, with QGLBuffer. If my code is not threaded everything is working fine, but when I run threads, the buffers are created by threads (without error), but nothing is displayed - I think its because they have different contexts. Here's a sample of my code:

    viewer.cpp:
    @
    Viewer::Viewer(QWidget *parent) : QGLViewer(parent) {}

    void Viewer::draw()
    {
    for(int i=0; i<facesToDisplay; i++)
    faces[i]->draw();
    }

    void Viewer::loadNeededFaces()
    {
    for(int i=0; i<totalFaces; i++)
    {
    if(faceIsNeeded(i))
    QtConcurrent::run(this, &Viewer;::loadFace, i);
    }
    }

    void Viewer::loadFace(int faceNumber)
    {
    Face* face = new Face(faceNumber);
    face->createBuffer();
    }
    @

    Face.cpp
    @
    void Face::createBuffer()
    {
    vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);
    vertexBuffer->create();
    vertexBuffer->bind();
    vertexBuffer->setUsagePattern(QGLBuffer::StaticDraw);
    vertexBuffer->allocate(vertexs, 3totalVerticessizeof(GLfloat));
    }

    void Face::draw()
    {
    vertexBuffer->bind())
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
    glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_INT, 0);
    glDrawArrays(GL_QUAD_STRIP, 0, totalVertices);
    glDisableClientState(GL_VERTEX_ARRAY);
    }
    @

    The idea is to have a main GUI thread (instance of Viewer) to display the visible faces, and forecast the faces that will needed soon, to preload them using working threads, so when the user rotates the object, the faces that will appear are already precalculated (and possible in the GPU), so the loading will be smooth.

    The code isn't 100% correct, its just a sample of my code. Anyone can give me a hint on how to put that code working ? I think I need to get some context and then use makeCurrent. I have already tried to pass to the Face instance, a pointer to the Viewer, and then call the makeCurrent on that pointer, but with no success - "QGLContext::makeCurrent(): Failed."


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.