优化掉的 GLSL 属性

GLSL attributes optimized out

所以我要发疯了。

我正在编写一个 android 应用程序,准确地说是一个本机 activity。一切都很好,除了属性和制服似乎在我的着色器中被优化了。

顶点着色器:

#version 100

attribute vec3 position;

void main() {

    gl_Position = vec4(position, 1);

}

片段着色器:

#version 100

precision highp float;

uniform vec3 color;

void main() {

    gl_FragColor = vec4(color, 1);

}

着色器编译:

unsigned int shader = glCreateProgram();

unsigned int v = glCreateShader(GL_VERTEX_SHADER);
unsigned int f = glCreateShader(GL_FRAGMENT_SHADER);


glShaderSource(v, 1, &vertex, nullptr);
glShaderSource(f, 1, &fragment, nullptr);


glCompileShader(v);
if (check_error(v, GL_COMPILE_STATUS, false)) {
    LOGE("Failed to compile vertex shader");
}

glCompileShader(f);
if (check_error(f, GL_COMPILE_STATUS, false)) {
    LOGE("Failed to compile fragment shader");
}


glAttachShader(shader, v);
glAttachShader(shader, f);

glLinkProgram(shader);
if (check_error(shader, GL_LINK_STATUS, true)) {
    LOGE("Failed to link shader");
}

glValidateProgram(shader);
if (check_error(shader, GL_VALIDATE_STATUS, true)) {
    LOGE("Failed to validate shader");
}

错误检查代码:

static bool check_error(unsigned int shader, unsigned int param, bool isProgram) {
int res = 123;
char log[2048] = { 0 };
if (isProgram) {
    glGetProgramiv(shader, param, &res);
    if (res == 0) {
        glGetProgramInfoLog(shader, sizeof(log), 0, log);
        LOGE("Shader: %s", log);
        return true;
    }
} else {
    glGetShaderiv(shader, param, &res);
    if (res == 0) {
        glGetShaderInfoLog(shader, sizeof(log), 0, log);
        LOGD("Shader %s", log);
        return true;
    }
}

return false;
}

一切都编译得很好。但是当我稍后调用 glGetAttribLocation 来获取位置索引时,它 return -1。在与 glBindAttribLocation 链接之前,我也尝试过绑定它。

使用 glGetActiveAttrib 查询所有属性只是 return 一些垃圾。片段着色器中的统一 "color" 也是如此。

我已经在我的 phone (Galaxy S3) 和 Visual Studio Emulator For Android 上尝试了 运行,两者的结果相同。

我的猜测是它们被优化掉了,但它们不应该被优化,因为我显然在使用它们并且它们对输出有贡献。

提前致谢!

在编译着色器之后 link 它们之前,您需要使用 glBindAttribLocation.

显式绑定属性位置

绑定位置后,link程序。

稍后,直接绑定到您使用 glVertexAttribPointer 指定的位置(确保使用 `glEnableVertexAttribArray 启用流)。

不查询,直接设置。如果要查询,请确保着色器程序已启用,并且流已绑定并激活。

正如Columbo在评论中所说的那样,这只是我的一个愚蠢的错误。我创建了一个新变量来保存程序 ID,而不是使用我在 class 中声明的那个。这是我后来在调用 glGetAttribLocation 和 glUseProgram 时使用的那个。