Draw Model Using Multiple VertexBuffers for position possibly
(i decided to try to ask this question in a different way to possibly advance how to do this)
using listing 9-4 only as a basis under "Best Practices for Working with Vertex Data" of 开发者_JAVA技巧Apples iOS guide for OpenGL ES, "OpenGL ES Programming Guide for iOS"
i want to basically "add" position date to this buffer. (can it be done in some way?)
and then just call up which identifier when using glDrawElements...
is there a way to do this? shown is example of what i want to do to give a visual.
typedef struct VertexData3D
{
GLfloat position[3];
GLfloat normal[3];
} VertexData3D;
GLuint test1Buffer;
GLuint test2Buffer;
GLuint index1Buffer;
GLuint index2Buffer;
const VertexData3D test1Buffer[] = {...};
const VertexData3D test2Buffer[] = {...};
const GLushort indices1[] = {...};
const GLushort indices2[] = {...};
void CreateBuffers()
{
// Static position data
glGenBuffers(1, &test1Buffer);
glBindBuffer(GL_ARRAY_BUFFER, test1Buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(test1VertexData), test1VertexData, GL_STATIC_DRAW);
glGenBuffers(1, &test2Buffer);
glBindBuffer(GL_ARRAY_BUFFER, test2Buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(test2VertexData), test2VertexData, GL_STATIC_DRAW);
// Static index data
glGenBuffers(1, &index1Buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index1Buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);
glGenBuffers(1, &index2Buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index2Buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, sizeof(VertexData3D), (void*)0);
glNormalPointer(GL_FLOAT, sizeof(VertexData3D), (void*)12);
}
// sometimes in the model, draw out this test1model.
void DrawModelusingTest1()
{
glBindBuffer(GL_ARRAY_BUFFER, test1VertexData);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index1Buffer);
glDrawElements(GL_TRIANGLES, theNumberInIndex1, GL_UNSIGNED_SHORT, (void*)0);
}
// sometimes in the model, draw out this test2model.
void DrawModelusingTest2()
{
glBindBuffer(GL_ARRAY_BUFFER, test2VertexData);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index2Buffer);
glDrawElements(GL_TRIANGLES, theNumberInIndex2, GL_UNSIGNED_SHORT, (void*)0);
}
Sounds like you would want glDrawElementsInstanced
Rotoglup's answer to my question here may help, specifically this link regarding instancing techniques.
I'd just add to the list of techniques the use of glVertexAttribDivisor to pass per instance (instead of per vertex) attributes, instead of using uniform buffers.
Basically, you use one VBO to hold the geometry and a second one to hold all the model-view matrices for each instance. You then use glVertexAttribDivisor to indicate that the model-view VBO should be advanced once per instance and call glDrawElementsInstanced a single time to draw all your objects.
First, your 3D mesh seems really static, there is no need to call glGenBuffers each and every frame. Do it once per mesh, at initialisation.
Your for (int i = 0; i < numOfShapes; i++)
makes no sense to me. You bind tons of buffers, and call glDrawElements
after the loop, which means that unless I'm missing something, only the last glBindBuffers actually do something.
If ALL your scene is static (only the camera moves), you can build a single, huge VBO (just like you did with glGenBuffers), put all your data in it, and call it 4 times with different matrices.
If anything is dynamic AND all your shapes are similar, look at instancing as Ben Voigt suggested; but simply avoiding to rebuild everything each frame should already boost your fps.
P.S I don't have the time to fully read your code, but if you only have ONE object repeated every time, I do hope you only have ONE vbo with multiple glDrawArrays calls to the same VBO...
精彩评论