Shared context and VAOs

Started by
1 comment, last by Katie 12 years, 6 months ago
Hi,

I am on OGLES2 on iOS5 and I have two threads handling the bulk of my program, one thread loads data including my vertex model information, and the other draws everything.

I have only just got a handle on what VAOs do so I set them up as I had seen them elsewhere, all the code works apart from the point where the VAO fails to bind on the second thread so your welcome to jump to the next bit of text.

The loading thread does this per model.


glGenVertexArraysOES(1, &puiVAO);
glBindVertexArrayOES(puiVAO);

if (!puiVbo)
puiVbo = new GLuint[modScene.nNumMesh];
if (!puiIndexVbo)
puiIndexVbo = new GLuint[modScene.nNumMesh];

glGenBuffers(modScene.nNumMesh, puiVbo);

for (unsigned int i = 0; i < modScene.nNumMesh; ++i)
{
// Load vertex data into buffer object
SPODMesh& Mesh = modScene.pMesh;
unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;

glBindBuffer(GL_ARRAY_BUFFER, puiVbo);
glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW);

// Load index data into buffer object if available
puiIndexVbo = 0;

if (Mesh.sFaces.pData)
{
glGenBuffers(1, &puiIndexVbo);
uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, puiIndexVbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW);
}
}

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArrayOES(0);


The drawing thread then does this (for simple meshes):


glBindVertexArrayOES(puiVAO); THROWS ERROR!

for(unsigned int i = 0; i < modScene.nNumMeshNode; ++i)
{
SPODMesh& Mesh = modScene.pMesh[i32MeshIndex];

// bind the VBO for the mesh
glBindBuffer(GL_ARRAY_BUFFER, puiVbo[i32MeshIndex]);

// bind the index buffer, won't hurt if the handle is 0
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, puiIndexVbo[i32MeshIndex]);

// Set the vertex attribute offsets
glVertexAttribPointer(SNAVERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sVertex.nStride, Mesh.sVertex.pData);
glVertexAttribPointer(SNANORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sNormals.nStride, Mesh.sNormals.pData);

if(Mesh.nNumUVW) // Do we have texture co-ordinates?
{
glVertexAttribPointer(SNATEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, Mesh.psUVW[0].nStride, Mesh.psUVW[0].pData);
}

// Draw the Indexed Triangle list
glDrawElements(GL_TRIANGLES, Mesh.nNumFaces*3, GL_UNSIGNED_SHORT, 0);
}
glBindVertexArrayOES(0);



Now the problem here is that the shared vertex data between my two contexts do not share VAO data (according to many sources), so how on earth do I build a VAO from the drawing mechanism after the vertex data has been set on the other thread and flushed ready for use on the rendering context? From what I have heard these VAO objects offer a big deal of efficiency boost by storing data on the graphics device so I am keen to find a fix.

Any clues, corrections or declarations of impossibility are welcome.

Thanks,
EnlightenedOne
Advertisement
If GL ES is anything like GL, then you can't simply make a GL function call from another thread because the GL context can only be current to a single thread.
On GL, you need to call wglMakeCurrent (Windows) or glXMakeCurrent(*nix)
I'm guessing Apple has a aglMakeCurrent.

Perhaps you need http://www.khronos.org/opengles/documentation/opengles1_0/html/eglMakeCurrent.html
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
GLES is, indeed, not multithreadsafe. Do not make calls into the OpenGL entry points from more than one thread at a time.

This topic is closed to new replies.

Advertisement