优化掉的 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 时使用的那个。
所以我要发疯了。
我正在编写一个 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 时使用的那个。