可能使用多个VertexBuffers绘制模型

时间:2011-05-19 03:45:06

标签: ios opengl-es vbo

(我决定尝试以不同的方式提出这个问题,以便可能推进如何做到这一点)

仅使用清单9-4作为OpenGL ES Apples iOS指南“使用顶点数据的最佳实践”的基础,“适用于iOS的OpenGL ES编程指南”

我想基本上“添加”这个缓冲区的日期。 (可以用某种方式完成吗?)

然后在使用glDrawElements时调用哪个标识符...

有没有办法做到这一点?显示的是我想做的视觉效果的例子。

    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);
    }

3 个答案:

答案 0 :(得分:0)

听起来你想要glDrawElementsInstanced

答案 1 :(得分:0)

Rotoglup对我的问题here的回答可能会有所帮助,特别是有关实例化技术的this link

我只是在技术列表中添加使用glVertexAttribDivisor 来传递每个实例(而不是每个顶点)属性,而不是使用统一缓冲区。

基本上,您使用一个VBO来保存几何体,而第二个用于保存每个实例的所有模型视图矩阵。然后使用glVertexAttribDivisor指示模型视图VBO应该每个实例前进一次,并且一次调用glDrawElementsInstanced来绘制所有对象。

答案 2 :(得分:0)

首先,你的3D网格看起来非常静态,没有必要每一帧调用glGenBuffers。初始化时每个网格执行一次。

你的for (int i = 0; i < numOfShapes; i++)对我毫无意义。你绑定了大量的缓冲区,并在循环之后调用glDrawElements,这意味着除非我遗漏了某些内容,否则只有最后一个glBindBuffers实际上会做一些事情。

如果您的所有场景都是静态的(只有相机移动),您可以构建一个巨大的VBO(就像您使用glGenBuffers一样),将所有数据放入其中,并使用不同的矩阵调用它4次。 / p>

如果有什么是动态的并且你的所有形状都相似,那就看Ben Voigt建议的实例;但只是避免重建每一帧的所有内容应该已经提升你的fps。

PS我没有时间完全阅读你的代码,但如果你每次只重复一个对象,我希望你只有一个vbo,多个glDrawArrays调用同一个VBO ......