glGetAttribLocation returns -1 when retrieving existing shader attribute

坚强是说给别人听的谎言 提交于 2019-11-27 21:21:38

问题


I'm trying to pass in attributes to my vertex shader but for some reason it keeps giving me a -1 on the 3rd attribute location I'm asking openGl to retrieve via glGetAttribLocation(). Currently it keeps giving me a -1 for the texCoord attribute and if I switch the texAttrib and colAttrib around (switching the lines in code) it gives me a -1 on the color property instead of the texture and I have no idea why? Since a -1 is being passed to glVertexAttribPointer I get the 1281 OpenGL error: GL_INVALID_VALUE.

My vertex shader:

#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 code:

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

[..]

回答1:


You should stop using glGetAttribLocation. Assign each attribute a location, either with glBindAttribLocation before linking the program or with explicit attribute locations, if that's available to you.

That way, if the compiler optimizes an attribute away (which is what's happening here; your fragment shader probably doesn't use one of the interpolated values), you won't care. You'll set up your arrays as normal, using a standard convention for attribute indices. Plus, you won't have to keep asking what an attribute location is every time you want to render with a different program; you know what location it is because you assigned it.

If you can't/won't, then there's nothing you can do. The compiler will optimize away attributes if you're not actually using them. The only thing you can do is detect that it returns -1 and not set up the array for that attribute.



来源:https://stackoverflow.com/questions/15639957/glgetattriblocation-returns-1-when-retrieving-existing-shader-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!