如何解决如果没有错误,为什么 GL 函数调用返回的位置为 -1?
在下面的程序中,最后一个打印函数打印 -1,这是名为 num 的统一位置。我给函数 glGetUniformLocation() 提供了正确的参数,结果得到了 -1,不知道为什么?
附言着色器编译成功。
GLuint program = glCreateProgram();
GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);
const GLchar* const shaderSrc = {
"#version 310 es\n"
"\n"
"// Input layout qualifier declaring a 16 x 16 (x 1) local\n" "// workgroup size\n"
"layout (local_size_x = 16,local_size_y = 16) in;\n"
"uniform int num;\n"
"\n"
"void main(void)\n"
"{\n"
"//Do Nothing \n"
"}\n"
};
glShaderSource(computeShader,1,&shaderSrc,NULL);
glCompileShader(computeShader);
int result;
glGetShaderiv(computeShader,GL_COMPILE_STATUS,&result);
if(result == GL_FALSE){
int length;
glGetShaderiv(computeShader,GL_INFO_LOG_LENGTH,&length);
char* message = static_cast<char*>(malloc(length));
glGetShaderInfoLog(computeShader,length,&length,message);
__android_log_print(ANDROID_LOG_INFO,"MyLog","Shader Compile Error: %s",message);
free(message);
}
GL_CALL(glAttachShader(program,computeShader));
GL_CALL(glLinkProgram(program));
GL_CALL(glValidateProgram(program));
GL_CALL(glUseProgram(program));
auto location = glGetUniformLocation(program,"num");
__android_log_print(ANDROID_LOG_INFO,"Location %d",location);
解决方法
除 @Rabbid76's answer 之外,我想特别解决您标题中的问题:
为什么GL函数调用返回的位置-1 如果没有错误?
因为没有错误,并且位置 -1 不是错误条件。
只有活跃制服有位置。查询非活动制服的位置被定义为返回 -1
。还要注意以下几点:
glUniform1f(-1,someValue)
在 GL 中完全有效,也不会根据规范产生任何错误。它只会被默默地忽略。
因为对于一个非活动的统一变量,它不可能影响你的着色器程序的输出,它的值无论如何都是无关紧要的,GL 不必打扰。
请注意,API 中的这种设计选择非常合理。在客户端,您可以使用一组要提供给着色器的制服。但是对于这些着色器,您可以有不同的选择,每个都访问这些制服的特定子集。客户端代码可以相同地对待每个变体,它不必知道(或查询)每个变体使用哪种制服。它只是不能将位置 -1 视为错误,因为它不是一个错误。至少如果您的客户端代码不能绝对确定此变量必须处于活动状态,则不会。
警告:查询非活动制服的值实际上是一个错误!
如果您使用 glGetUniformfv(program,location,params)
之类的函数并将 location
设置为 -1
,这实际上是一个错误条件。调用只会返回 GL_INVALID_OPERATION
并且没有其他效果(这也意味着 params
指向的内存内容不会被修改 - 它不会为这些东西返回任何默认值)。这种行为也很合理,因为非活动的统一变量不能有值,你不能查询它们,试图这样做是一个错误。
警告:顶点属性的情况略有不同
对于顶点属性,有glGetAttribLocation
,这也会返回GLint
,对于不存在或不活跃的属性,使用-1
。查询这些也没有错误。但是采用这些属性位置的 GL 函数(如 glVertexAttribPointer
、glEnableVertexAttribPointer
)通常使用 GLuint
类型,并且
glVertexAttribPointer(-1,...);
将生成 GL_INALID_VALUE
GL 错误,因为 (GLuint)-1
最有可能大于您实现的 GL_MAX_VERTEX_ATTRIBS
值(即使它不是您没有得到你想要的结果。
因此对于属性位置,您的客户端代码必须检查 -1
...
uniform 变量 num
不是活动的程序资源,因为它没有在着色器程序中使用。编译器和链接器优化代码并确定不需要该变量。因此,您将无法获得有效的统一位置。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。