GLSL属性已优化

时间:2017-06-07 20:13:33

标签: android opengl-es-2.0 glsles

所以我要放松心情了。

我正在编写一个Android应用程序,确切地说是一个原生活动。一切都很好,除了属性和制服似乎在我的着色器中进行了优化。

顶点着色器:

#version 100

attribute vec3 position;

void main() {

    gl_Position = vec4(position, 1);

}

Fragment Shader:

#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获取位置索引时,它返回-1。我还尝试在连接glBindAttribLocation之前绑定它。

使用glGetActiveAttrib查询所有attributs只返回一些垃圾。同样适用于制服"颜色"在片段着色器中。

我尝试在手机(Galaxy S3)和Visual Studio Emulator For Android上运行它,两者都有相同的结果。

我的猜测是他们已经过优化,但他们不应该这样做,因为我清楚地使用它们并且它们会对输出做出贡献。

提前致谢!

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

编译着色器之后和链接之前,需要使用glBindAttribLocation显式绑定属性位置。

绑定位置后,链接程序。

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

不要查询,只需设置即可。如果要查询,请确保已启用着色器程序,并且首先绑定并激活流。