所以我要放松心情了。
我正在编写一个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上运行它,两者都有相同的结果。
我的猜测是他们已经过优化,但他们不应该这样做,因为我清楚地使用它们并且它们会对输出做出贡献。
提前致谢!
答案 0 :(得分:1)
就像Columbo在评论中所说的那样,这只是我的一个愚蠢的错误。我创建了一个新变量来保存程序ID,而不是使用我在类中声明的那个。这是我后来在调用glGetAttribLocation和glUseProgram时使用的那个。
答案 1 :(得分:0)
编译着色器之后和链接之前,需要使用glBindAttribLocation
显式绑定属性位置。
绑定位置后,链接程序。
稍后,使用glVertexAttribPointer
直接绑定到您指定的位置(确保使用`glEnableVertexAttribArray启用流)。
不要查询,只需设置即可。如果要查询,请确保已启用着色器程序,并且首先绑定并激活流。