【问题标题】:OpenGL - need a simple concept clarificationOpenGL - 需要一个简单的概念澄清
【发布时间】:2017-01-08 19:18:46
【问题描述】:

我了解如何创建顶点和片段着色器以及如何创建顶点数组并将它们放在缓冲区中,但是如何将两者联系起来?

含义 - 当我运行我的程序时,它如何知道当前活动缓冲区上的顶点数组应该“馈入”到顶点着色器?

这只是通过使用glVertexAttribPointer 来完成的吗?

【问题讨论】:

    标签: opengl


    【解决方案1】:

    没有真正意义上的“当前活动缓冲区”。 (嗯,有,但它仅在 VAO 规范时与非直接状态访问 API 相关。)

    顶点数组对象 (VAO) 将指针(通过glVertexAttribPointer 设置)保存到内存缓冲区中的数据中。与这些缓冲区的绑定是 VAO 状态的一部分。当您绑定一个 VAO 时,随后的 glDraw* 命令会将顶点从绑定到当前 VAO 的缓冲区传输到管道。

    为简单起见,下面是 VAO 的大致含义,以及用于设置该状态的相关 OpenGL 4.5 直接状态访问函数名称:

    struct VertexArrayObject
    {
        // VertexArrayElementBuffer
        uint element_buffer;
    
        struct Binding {
            // VertexArrayVertexBuffers
            uint buffer;
            intptr offset;
            sizei stride;
    
            // VertexArrayBindingDivisor
            uint divisor;
        } bindings[];
    
        struct Attrib {
            // VertexArrayAttribBinding
            uint binding; // This is an index into bindings[]
    
            // EnableVertexArrayAttrib
            bool enabled;
    
            // VertexArrayAttrib*Format
            int size;
            enum type;
            boolean normalized;
            boolean integer;
            boolean long;
            uint relativeoffset;
        } attribs[];
    };
    

    当您调用 glVertexAttribPointer 时,它实际上对当前绑定的 VAO 执行以下操作:

    vao.attribs[index].binding = index;
    vao.attribs[index].size = size;
    vao.attribs[index].type = type;
    vao.attribs[index].normalized = normalized;
    vao.attribs[index].relativeoffset = 0;
    vao.bindings[index].buffer = current ARRAY_BUFFER;
    vao.bindings[index].offset = pointer;
    vao.bindings[index].stride = stride; // if stride == 0 computes based on size and type
    

    【讨论】:

    • 好的,只是为了确保我理解 - 使用 VAO(不推荐)的替代方法是每次您必须告诉 GPU 如何处理数据时“重新声明”glVertexAttribPointer在缓冲区中?
    • 错什么?您必须使用 OpenGL 3 及更高版本的 VAO 将基元传输到 GPU。
    • 另外,在glVertexAttribPointer的第一个参数中,我写了一个对着色器变量的引用,对吧?这就是程序知道将顶点发送到着色器的方式吗?
    • 是的,它是属性索引,您可以在着色器中使用layout(location = n) 说明符指定它。
    • 好的,谢谢!最后一个问题,我发誓!哈哈,我很确定答案是“是”,但我想仔细检查一下。所以VAO的整个想法是我绑定一个,然后创建并绑定一个缓冲区和一些数据,一个glVertexAttribPointer等......然后绑定另一个VAO,并用其他数据和一个不同的指针创建一个不同的缓冲区,然后我可以在 VAO 之间切换,随后的绘图调用将使用当前有界的 VAO?
    猜你喜欢
    • 2018-09-13
    • 1970-01-01
    • 2013-07-22
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    相关资源
    最近更新 更多