How to draw middle portion of vertex array
-
wrote on 12 Oct 2013, 21:04 last edited by
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
-
wrote on 13 Oct 2013, 10:50 last edited by
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?
-
Hi,
If you are using C++11 the vector has now a data function otherwise, you can use Qt's QVector
Hope it helps
1/3