OpenGL - 需要一个简单的概念澄清

Posted

技术标签:

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

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

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

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

【问题讨论】:

【参考方案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?

以上是关于OpenGL - 需要一个简单的概念澄清的主要内容,如果未能解决你的问题,请参考以下文章

澄清server push/websocket/sse的一些概念

使用 glut 的 OpenGL 三角形旋转 - 需要一个简单的修正

标准化和归一化概念澄清与梳理

标准化和归一化概念澄清与梳理

Opengl ES 基础概念

简单的澄清对象 Swift 语言