How to draw middle portion of vertex array



  • I have a small application that draws information from a file. The data is dynamically loaded and may vary in size or content depending on what file is read. I had previously been loading this data into a QGLBuffer, which I would bind before drawing. While this provides pretty good performance, I have run into a lot of compatibility issues with older video cards that do not support this. Because of that, I want to offer a fallback method that uses simple vertex arrays instead of VBOs. So some example code might look like this:

    Binding the initial QGLBuffer (the vertices array is a std::vector<QVector3D> that is built while parsing the file)
    @ qglbuffer = new QGLBuffer(QGLBuffer::VertexBuffer);
    if (qglbuffer->create())
    {
    if (qglbuffer->bind())
    {
    qglbuffer->setUsagePattern(QGLBuffer::StaticDraw);
    qglbuffer->allocate(vertices.data(), sizeof(QVector3D)*vertices.size());
    qglbuffer->release();
    }
    }@

    Drawing loop
    @ if (qglbuffer->bind())
    {
    glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)NULL);
    glDrawArrays(GL_LINES, 0, vertices.size());
    qglbuffer->release();
    }
    else
    {
    glVertexPointer(3, GL_FLOAT, 0, vertices.data());
    glDrawArrays(GL_LINES, 0, vertices.size());
    }@

    So the idea is that if the QGLBuffer fails to bind then it resorts to the vertex array methods. This works fine as long as I want to draw the entire vertex array, but I have had a very difficult time figuring out how to draw only a portion of this array. I have one case where I use both a vertices array and an indices array along with glDrawElements(). This works fine with the QGLBuffer method since I can just supply the appropriate offset and then limit the element count to constrain the information that is drawn (see below).

    @ bool buffer1success = vertexBuffer->bind();
    glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)NULL);
    bool buffer2success = indicesBuffer->bind()
    if ((buffer1success == true) && (buffer2success == true))
    {
    glDrawElements(GL_TRIANGLES, endCount-startCount, GL_UNSIGNED_INT, (GLvoid*)(startCount*sizeof(GLuint)));
    indicesBuffer->release();
    verticesBuffer->release();
    }
    else
    {
    // can't figure out what to do here???
    }@

    In this case I only want to draw the data between startCount and endCount, not the entire array. My problem is that I cannot figure out an equivalent method that will work with simple vertex arrays. Everything I have come across requires some form of buffer binding or extremely slow glBegin/glEnd calls.

    Does anyone know of a good way to do something equivalent to QGBuffer/glDrawElements( , count, , offset) but only using simple vertex arrays?

    Any help would be greatly appreciated!

    Thanks in advance



  • From what I have read, I only have 2 options for drawing indexed vertex arrays: glDrawElements() and glDrawRangeElements(). The latter requires knowledge of the min and max index that is referenced for a specific range of vertices, but this would be costly to compute for my circumstances. So that makes me think all I am left with is glDrawElements(), but for a vertex array and not a VBO. Please correct me if I am wrong.

    So here is what I have been trying
    @ glVertexPointer(3, GL_FLOAT, 0, vertices.data());
    glDrawElements(GL_TRIANGLES, endCount-startCount, GL_UNSIGNED_INT, indices + startCount*sizeof(GLuint));@

    But this will not compile. The indices array is a std::vector<GLuint>, which I think might be part of my problem. Is was dynamically allocated and is not just a simple predefined array like
    @GLuint indices[20] = { .... };@

    So how can I make glDrawElements work with a std::vector<GLuint> array of indices?


  • Lifetime Qt Champion

    Hi,

    If you are using C++11 the vector has now a data function otherwise, you can use Qt's QVector

    Hope it helps


Log in to reply
 

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