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

Joe*_*ewd 12 c++ opengl shader vertex-shader

我正在尝试将属性传递给我的顶点着色器但是由于某种原因它在第三个属性位置上给我一个-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);
}
Run Code Online (Sandbox Code Playgroud)

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

[..]
Run Code Online (Sandbox Code Playgroud)

Nic*_*las 25

你应该停止使用glGetAttribLocation.指定每个属性的位置,无论是与glBindAttribLocation链接程序的明确属性的位置之前或,如果这是提供给您.

这样,如果编译器优化了一个属性(这就是这里发生的事情;你的片段着色器可能不使用其中一个插值),你就不在乎了.您将使用属性索引的标准约定正常设置数组.另外,每次要使用不同的程序渲染时,您都不必一直询问属性位置是什么; 你知道它是什么位置,因为你分配了它.

如果你不能/不会,那么你无能为力.如果您实际上没有使用它们,编译器将优化远离属性.您唯一能做的就是检测它返回-1并且不为该属性设置数组.

  • 如果某人仅使用glBindAttribLocation进行分配,则它将不适用于Radeon卡.您需要使用GLSL代码中输入声明的布局直接分配.最近,我失去了很多时间试图找出代码在nVidia上运行的原因并且不在Radeon卡上.似乎AMD家伙有点忽略了glBindAttribLocation. (2认同)
  • 需要注意的是,在 Nvidia 卡上,我的驱动程序忽略了 glBindAttribLocation 和 GLSL 中给出的显式位置。只有当我真正确保顶点属性的使用时,glGetAttribLocation 才会返回-1。 (2认同)