PDA

View Full Version : Multiple VBO with QGLBuffer



brijesh
21st March 2013, 11:00
---------
SITUATION
---------
In a QGraphicsView - QGraphicsScene framework ...

I have two VBOs declared as ...

QVarLengthArray<Vertex> mVertices1;
QGLBuffer mVBO1;

QVarLengthArray<Vertex> mVertices1;
QGLBuffer mVBO2;

They are instantiated in the scene constructor as ...

mVBO1.create();
mVBO1.bind();
mVBO1.setUsagePattern(QGLBuffer::StaticDraw);
mVBO1.allocate(mVertices1.data(), sizeof(Vertex)*nVertices1);

mVBO2.create();
mVBO2.bind();
mVBO2.setUsagePattern(QGLBuffer::StaticDraw);
mVBO2.allocate(mVertices2.data(),sizeof(Vertex)*nV ertices2);


In the draw background method of QGraphicsScene, I am ...

// Binding my shader program mShaderProgram.bind();
// Initialising my attribute variables mShaderProgram.attributeLocation("
// Enabling the attribute array mShaderProgram.enableAttributeArray( ..
// Setting the attribute Buffer mShaderProgram.setAttributeBuffer(...


Further, the draw calls are made as below ...

if (mVBO1.bind()) // mVBO1 draw block
{
glDrawArrays(GL_LINES,0,nVertices1);
// mVBO1.release();
}

if (mVBO2.bind()) // mVBO2 draw block
{
glDrawArrays(GL_LINE_STRIP,0,nVertices2);
//mVBO2.release();
}

Finally in the drawbackground method itself ..

// Disabling the attribute arrays mShaderProgram.disableAttributeArray(...
// Releasing the shader program mShaderProgram.release();


---------
PROBLEMS
---------
Independently, each of the "if" blocks shown above render the expected values.

However, when i wish to use both the VBOs together (mVBO1 and mVBO2), during the second or subsequent rendering loops
glDrawArrays within mVBO1 draw block will render nVertices1 values as GL_LINES from mVBO2 [mVertices2.data]

I tried releasing the VBOs (mVBO2.release()) but that results in a crash at glDrawArrays(GL_LINES,0,nVertices1);

Any help, ideas to fix this is greatly appreciated.

Note .. Binding the QGLBuffers (VBOs) return true, their buffer ids are also distinct when checked using the QGLBuffers::bufferid() api !!

wysota
21st March 2013, 21:59
How do you want to use them "together"? I think only one buffer can be bound at the same time.

brijesh
22nd March 2013, 04:59
Yes, I agree that only one buffer can be bound at the same time.
I want to use two vertex buffer objects.
.. Bind one and draw from it.
.. Then bind the other one and draw from the second one.

I do not release the buffer objects as they result in the program crashing !!

I have attached sample project using QT 4.8 that demonstrates the problem.
Comments in scene.cpp line 98-102 describe the problem
/* PROBLEM !!
* The follwing glDrawArrays (GL_LINE_STRIP ... renders from VBO2 !!
* Instead of the horizontal line strip in red color, this draws the vertical line strip with data from VBO2
* If the mVB02.bind() block below is commented then the red horizontal strip is drawn correctly.
*/

lanz
22nd March 2013, 06:58
You should initialize QVarLengthArrays prior to their use

nVertices1 = 4;
mVertices1.resize(nVertices1);
(the same for the second array)

brijesh
22nd March 2013, 09:18
Qt doc says QVarLengthArray is default initialised to 256 if not specified.
Nevertheless, I tried your suggestion
.. mVertices1.resize(4);
as well as
.. mVertices2.resize(8);

But that did not solve my problem :(

Is the code working on your machine with those changes and rendering both the red horizontal lines & blue vertical lines ?

lanz
22nd March 2013, 12:53
mShaderProgram.setAttributeBuffer(inPositionLocati on, GL_FLOAT, 0, 3, sizeof(MyVertex));
mShaderProgram.setAttributeBuffer(inColorLocation, GL_FLOAT, 12, 3, sizeof(MyVertex));
From the docs:

Sets an array of vertex values on the attribute at location in this shader program, starting at a specific offset in the currently bound vertex buffer.
So you should call it after you bind specific buffer, I get it to work with the following code:

if (mVBO1.bind()) {
mShaderProgram.setAttributeBuffer(inPositionLocati on, GL_FLOAT, 0, 3, sizeof(MyVertex));
mShaderProgram.setAttributeBuffer(inColorLocation, GL_FLOAT, 12, 3, sizeof(MyVertex));
glDrawArrays(GL_LINES,0,nVertices1);
}
if (mVBO2.bind())
{
mShaderProgram.setAttributeBuffer(inPositionLocati on, GL_FLOAT, 0, 3, sizeof(MyVertex));
mShaderProgram.setAttributeBuffer(inColorLocation, GL_FLOAT, 12, 3, sizeof(MyVertex));
glDrawArrays(GL_LINES,0,nVertices2);
}

So in your case these commands were executed with second buffer still bound from the previous call (and hence crash when you tried to release buffer).

brijesh
22nd March 2013, 18:25
Thanks for the solution.
That works perfect !!