属性的多个缓冲区如何在 openGL (ES) 着色器和 C++ api 中工作

pet*_*erk 4 c++ shader opengl-es glsl opengl-es-3.0

我有众所周知的立方体示例,并且一直在编写一些代码来测试它并了解有关着色器的更多信息。我的问题是如何分配多个缓冲区以在着色器中访问以及如何编写着色器代码来引用它们。那里的样本似乎依赖于某种隐式引用默认值,这些默认值隐藏了真正发生的事情以及如何在样本中对其进行操作。

我的缓冲区设置如下(数据省略)

        glGenBuffers(1, &vertexPosObject);
        glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
            sizeof(Vec3f), (void*)0);

        /* load index buffer with array of indices */
        glGenBuffers(1, &indexBufferObject);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

        /* load color buffer with array of colors */
        glGenBuffers(1, &colorBufferObject);
        glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertColors), vertColors, GL_STATIC_DRAW);

        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
            sizeof(Vec4f), 0);
Run Code Online (Sandbox Code Playgroud)

有了这个,我得到了一个立方体图并且可以旋转它。和。

        Matrix4d modelView;
        double rot = rc.timing().frameTime()*.3;
        rot = fmod(rot, ARTD_M_PI * 2);
        modelView.setRotation(Vec3d(0, 1, 1), rot);
        artdGlUniformMatrix4(modelViewId, modelView); // convenience call
Run Code Online (Sandbox Code Playgroud)

然后我可以在下面画它

        glUseProgram(cubeShader);

        glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

        const int vertexCount = 36;
        const int type = GL_UNSIGNED_INT; // unsigned short ??
        const int firstIndex = 0;

        // vertexCount is the number of verts in your vertex array object
        // firstIndex is the first index to use in an array of offsets (element index) into the vertex data.

        glDrawElements(GL_TRIANGLES, vertexCount, type, (void *)firstIndex);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
Run Code Online (Sandbox Code Playgroud)

我一直假设顶点数组被分配了一个“槽”

        glEnableVertexAttribArray(0);
Run Code Online (Sandbox Code Playgroud)

并且该插槽“0”隐含地是着色器作为其输入顶点所采用的。(???)

所以我想我会尝试将颜色数组分配给插槽“1”,索引数组句柄直接传递给 glDrawElements() 并使用索引数组寻址分配给插槽“0”的缓冲区检索着色器中的输入顶点

我一般认为人们可能需要多个缓冲区来处理各种法线、颜色等内容,并且需要访问这些缓冲区的值,并使用索引对它们进行寻址。所以一般情况下的答案是可取的。

我的问题是如何访问着色器中的颜色数组缓冲区以及访问其他缓冲区作为顶点着色器中的可索引数组???

如何将缓冲区绑定到各种着色器可访问标识符,以及如何从着色器代码中的这些标识符访问它们。理解这些关系是关键。

目前,这个着色器对用于绘制具有计算颜色的立方体。

    "uniform mat4 Projection;\n"
    "uniform mat4 Model;\n"

    "attribute vec4 vPosition;\n"
    "varying vec3 color;\n"
    "void main(){\n"
        "mat4 MVP = Model * Projection;\n"
        "gl_Position = vPosition * MVP;\n"
        "color = gl_Position.xyz + vec3(0.5);\n"
    "}\n"
Run Code Online (Sandbox Code Playgroud)

片段着色器

   "precision mediump float;\n"
    "varying vec3 color;\n"
    "void main()\n"
    "{\n"
        "gl_FragColor = vec4 ( color, 1.0 );\n"
    "}\n"
Run Code Online (Sandbox Code Playgroud)

原谅 C++ 字符串 :)

谢谢 !!

Rab*_*d76 5

如果要使用颜色属性,则必须向着色器添加一个新属性:

顶点着色器

attribute vec4 vPosition;
attribute vec4 vColor;

varying vec4 color;

uniform mat4 Projection;
uniform mat4 Model;

void main()
{
    mat4 MVP    = Model * Projection;
    gl_Position = vPosition * MVP;
    color       = vColor;
}
Run Code Online (Sandbox Code Playgroud)

通过 链接着色器程序后glLinkProgram,可以通过以下方式获取属性 ind3ex glGetAttribLocation

GLuint cubeShader = ....;

glLinkProgram(cubeShader);

GLint pos_attr_i   = glGetAttribLocation(cubeShader, "vPosition");
GLint color_attr_i = glGetAttribLocation(cubeShader, "vColor");
Run Code Online (Sandbox Code Playgroud)

这是必须glVertexAttribPointer分别用于的属性索引glEnableVertexAttribArray

glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
glVertexAttribPointer(pos_attr_i, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3f), (void*)0);

glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
glVertexAttribPointer(color_attr_i, 4, GL_FLOAT, GL_FALSE, sizeof(Vec4f), 0);

glEnableVertexAttribArray(pos_attr_i);
glEnableVertexAttribArray(color_attr_i);
Run Code Online (Sandbox Code Playgroud)