GLSL属性位置返回-1

GLSL Attribute Location Returning -1

本文关键字:返回 位置 属性 GLSL      更新时间:2023-10-16

我显然误解了与GLSL有关的一些非常简单的事情,所有谷歌结果都指向一个显而易见的答案,即我没有使用我试图找到的变量,它已经被优化了-然而我使用的是有问题的变量。考虑以下非常的基本着色器:

顶点着色器

attribute vec2 TexCoord;
varying vec2 TexCoordA;
void main(){
gl_Position =  gl_ModelViewProjectionMatrix * gl_Vertex;
TexCoordA = TexCoord;
}

片段着色器

varying vec2 TexCoordA;
void main(){
gl_FragColor = vec3(TexCoordA.x, TexCoordA.y, 0); 
}

它们编译和链接很好——没有错误。然而,当我试图找到"TexCord"的位置时,使用"glGetAttribLocation"会返回-1。如果我将TexCourdA用于其他目的(例如调用"texture2D()"),那么我能够正确地找到TexCourd的位置。

你可能会问,为什么这很重要(因为除了纹理调用之外,你为什么还要使用UV coords?)?我正试图将一个像素渲染到所有UV坐标的帧缓冲区中,然后在第二次传递时再次读取它们——这是我能保证我想要的结果的唯一方法。

TL;DR既然上面的着色器编译和链接没有问题,为什么"glGetAttribLocation"会返回-1?

请求有关问题区域周围代码的信息如下(我以相同的方式加载了大约20-25个其他着色器,所以我相信问题不在这里):

问题行:

mPassOneProgram = LoadShader("PCT_UV_CORRECTION_PASS_1.vert", "PCT_UV_CORRECTION_PASS_1.frag");
mPassOneUVLocation = glGetAttribLocation(mPassOneProgram, "TexCoord");

着色器加载程序代码:

GLuint LoadShader(const char *vertex_path, const char *fragment_path) {
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
// Read shaders
std::string vertShaderStr = readFile(vertex_path);
std::string fragShaderStr = readFile(fragment_path);
const char *vertShaderSrc = vertShaderStr.c_str();
const char *fragShaderSrc = fragShaderStr.c_str();
GLint result = GL_FALSE;
int logLength;
// Compile vertex shader
std::cout << "Compiling vertex shader." << std::endl;
glShaderSource(vertShader, 1, &vertShaderSrc, NULL);
glCompileShader(vertShader);
// Check vertex shader
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result);
glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength);
std::vector<char> vertShaderError(logLength);
glGetShaderInfoLog(vertShader, logLength, NULL, &vertShaderError[0]);
std::cout << &vertShaderError[0] << std::endl;
OutputDebugString(&vertShaderError[0]);
// Compile fragment shader
std::cout << "Compiling fragment shader." << std::endl;
glShaderSource(fragShader, 1, &fragShaderSrc, NULL);
glCompileShader(fragShader);
// Check fragment shader
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &result);
glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);
std::vector<char> fragShaderError(logLength);
glGetShaderInfoLog(fragShader, logLength, NULL, &fragShaderError[0]);
std::cout << &fragShaderError[0] << std::endl;
OutputDebugString(&vertShaderError[0]);
std::cout << "Linking program" << std::endl;
GLuint program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &result);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
std::vector<char> programError( (logLength > 1) ? logLength : 1 );
glGetProgramInfoLog(program, logLength, NULL, &programError[0]);
std::cout << &programError[0] << std::endl;
OutputDebugString(&vertShaderError[0]);
glDeleteShader(vertShader);
glDeleteShader(fragShader);
return program;
}

通过解决了这个问题

gl_FrontColor = vec3(TexCoord.x, TexCoord.y, 0)

在"顶点"着色器和中

gl_FragColor = gl_Color;

在片段着色器中。

这基本上是一样的,我仍然不明白为什么它以前不起作用。我将把这个问题归结为编译器中的一个错误,因为似乎没有其他人能够找到问题。

glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result);
...
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &result);
...
glGetProgramiv(program, GL_LINK_STATUS, &result);

每一个都应该进行检查,以确保结果等于GL_TRUE,否则着色器没有正确编译。有关完整的着色器/程序类集,请参见此处。