使用多个 VertexBuffers 绘制模型可能的位置

发布于 2024-11-08 04:49:30 字数 2254 浏览 0 评论 0 原文

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

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

我基本上想将位置日期“添加”到此缓冲区。 (可以通过某种方式完成吗?)

然后在使用 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);
    }

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

但可醉心 2024-11-15 04:49:30

听起来你想要 glDrawElementsInstanced

Sounds like you would want glDrawElementsInstanced

没企图 2024-11-15 04:49:30

Rotoglup 对我的问题的回答此处可能会有所帮助,特别是此链接有关实例化技术。

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

基本上,您使用一个 VBO 来保存几何图形,使用第二个 VBO 来保存每个实例的所有模型视图矩阵。然后,您使用 glVertexAttribDivisor 指示模型视图 VBO 应每个实例前进一次并调用 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.

烂人 2024-11-15 04:49:30

首先,你的 3D 网格看起来确实是静态的,不需要每一帧都调用 glGenBuffers。在初始化时,每个网格执行一次。

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

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

如果任何东西都是动态的并且所有形状都相似,请按照 Ben Voigt 的建议查看实例化;但只要避免重建每帧的所有内容就应该已经提高了你的 fps。

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

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文