当检索现有着色器属性时,glGetAttribLocation返回-1

glGetAttribLocation returns -1 when retrieving existing shader attribute

本文关键字:glGetAttribLocation 返回 属性 检索      更新时间:2023-10-16

我试图将属性传递给我的顶点着色器,但由于某种原因,它一直给我一个-1在第三个属性位置,我要求openGl通过glGetAttribLocation()检索。目前它一直给我一个-1的texCoord属性,如果我切换texAttrib和colAttrib周围(切换行代码)它给我一个-1的颜色属性,而不是纹理,我不知道为什么?由于-1被传递给glVertexAttribPointer,我得到1281 OpenGL错误:GL_INVALID_VALUE。

顶点着色器:

#version 150
in vec3 position;
in vec3 color;
in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
    Color = color;
    Texcoord = texcoord;
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
}
OpenGL代码:

basicShader.Use();
// Buffers and shaders
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
// Make it active vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Build basic triangle
float vertices[] = {
    // position         // color          // textures
    -0.5f,  0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
     0.5f,  0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
     0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
    -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f// Bottom-left
};
GLuint elements[] = {
    0, 1, 2,
    2, 3, 0
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLint posAttrib = glGetAttribLocation(basicShader.shaderProgram, "position");
glEnableVertexAttribArray(posAttrib); // Enable attribute first before specifiying attributes
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0); // 6 float sizes is every new vertex
GLint colAttrib = glGetAttribLocation(basicShader.shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); // same for color + offset
GLint texAttrib = glGetAttribLocation(basicShader.shaderProgram, "texcoord"); // Returns -1
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); // 6 offset from beginning
[..]

你应该停止使用glGetAttribLocation每个属性分配一个位置,可以在链接程序之前使用glBindAttribLocation,也可以使用显式属性位置(如果有的话)。

这样,如果编译器把一个属性优化掉了(就像这里发生的那样;你的片段着色器可能不使用插值值之一),你不会在意。您将像往常一样设置数组,使用属性索引的标准约定。另外,每次你想用不同的程序渲染时,你不必一直问属性位置是什么;你知道是什么位置,因为你分配了它。

如果你不能/不愿意,那么你什么也做不了。如果你不实际使用属性,编译器会把它们优化掉。您唯一能做的就是检测它返回-1,而不为该属性设置数组。

相关文章:
  • 没有找到相关文章