【问题标题】:Initialize GLSL layout with glEnableVertexAttribArray使用 glEnableVertexAttribArray 初始化 GLSL 布局
【发布时间】:2015-06-26 08:39:27
【问题描述】:

我想将顶点、UV 和法线数组传递给着色器并使用 MVP 矩阵对其进行转换,因此我编写了一个简单的着色器程序:

#version 330 core
//Vertex shader
layout(location=0)in vec3 vertexPosition_modelspace;
layout(location=1)in vec2 vertexUV;
out vec2 UV;

uniform mat4 MVP;

void main(){
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
    UV = vertexUV;
}

#version 330
//Fragment Shader
in vec2 UV;
out vec3 color;
uniform sampler2D color_texture;

void main(void) {
    color = texture(color_texture, UV).rgb;
}

然后我需要传递一个顶点数组,它是这样初始化的:

glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], model_usage);

与 UV 和法线相同,类型仍然是 GL_ARRAY_BUFFER。

然后是绘制循环:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        for (Model* mdl : baseShader->getModels()) {

            glUseProgram(baseShader->getShaderProgram());

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, mdl->getTextureBuffer());
            glUniform1i(texture_location, 0);

            glm::mat4 mvp = RootEngine->projection_matrix * RootEngine->view_matrix * mdl->getModelMatrix();
            glUniformMatrix4fv(baseShader->getMVPlocation(), 1, GL_FALSE, &mvp[0][0]);

            glEnableVertexAttribArray(0);
            glBindBuffer(GL_ARRAY_BUFFER, mdl->getVertexBuffer());
            glVertexAttribPointer(0,  3, GL_FLOAT, GL_FALSE, 0, (void*)0);

            glEnableVertexAttribArray(1); // Matches layout (location = 1)
            glBindBuffer(GL_ARRAY_BUFFER, mdl->getUVsBuffer());
            glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

            glDrawArrays(GL_TRIANGLES, 0, mdl->getVertices()->size());

            glDisableVertexAttribArray(0);
            glDisableVertexAttribArray(1);

        }

        SDL_GL_SwapWindow(RootEngine->getMainWindow());

BaseShader 和 Model 是我自己的类,它们进行简单的初始化和 VBO 处理。

问题是实际上没有渲染任何东西。我尝试添加glEnableClientState(GL_VERTEX_ARRAY);

glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
...
glDeleteVertexArrays(1, &VertexArrayID);

但还是一无所获。当我不使用布局并使用 glVertexPointer 传递数据时,一切似乎都正常。

更新 1:我发现了阻止渲染顶点的原因。它是 VertexShader 中的统一变量。如果它被移除,则顶点正在被渲染,但是没有办法将矩阵传递给着色器。

【问题讨论】:

  • EnableVertexAttribArray 不应该在缓冲区定义之后调用?
  • OpenGL 文档没有说明调用顺序。并且由于 OpenGL 是一个大堆栈机器,因此首先选择布局元素然后绑定缓冲区是合乎逻辑的,所以这应该不是问题。
  • 你当然可以使用矩阵作为制服。如果您在使用 MVP 矩阵时您的对象消失了,那么您的矩阵只是将您的对象转换出查看体积。
  • glLoadIdentity() 对您的程序没有用处,因为您在着色器中使用自己的矩阵...
  • @Victor.Palyvoda,该程序用于使用 gl_ModelViewProjectionMatrix,但由于它在 OpenGL 3 中已被弃用,因此我重新编写了代码并忘记了 glLoadIdentity()。感谢您指出。

标签: c++ opengl glsl


【解决方案1】:

我刚刚传递了错误的纹理,所以模型是黑色的,因此不可见。谢谢大家的回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多