在我在iPad模拟器上运行的iOS项目中,我有3个着色器程序,每个程序使用相似但不完全相同的属性和制服集。这两个着色器中的前两个完美地编译和协同工作,在编译或绘图过程中的任何一点都没有gl错误。我现在需要添加第三个着色器,这引起了一个问题:现在,两个其他着色器都没有绘制任何东西,当我尝试使用glUniform传递制服时,glGetError返回1282(GL_INVALID_OPERATION)。 glGetError在调用glUniform之前返回0行。
我相信我在尝试调用glUniform之前将程序设置为正确的程序,因为当我在传递制服之前用GL_CURRENT_PROGRAM调用glGetIntegerv时,它匹配我尝试使用的程序的gl名称(我调用glUseProgram与我想在glUniform调用问题的方法的开头使用的程序)。 glGetError在编译问题着色器之前和之后返回0。编译代码稍微从Apple的一个示例项目中修改,我在其中看不到任何会影响其他着色器状态的内容。
- (BOOL)loadGLProgramWithVertexShader: (NSString*) vertexShaderName fragmentShader: (NSString*) fragementShaderName
{
GLuint vertShader, normFragShader;
NSString *vertShaderPathname, *normFragShaderPathName;
// Create shader program.
shaderProgram = glCreateProgram();
// Create and compile vertex shader.
vertShaderPathname = [[NSBundle mainBundle] pathForResource: vertexShaderName ofType:@"vsh"];
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
NSLog(@"Failed to compile vertex shader");
return NO;
}
// Create and compile normal mapping fragment shader.
normFragShaderPathName = [[NSBundle mainBundle] pathForResource: fragementShaderName ofType:@"fsh"];
if (![self compileShader:&normFragShader type:GL_FRAGMENT_SHADER file:normFragShaderPathName]) {
NSLog(@"Failed to compile fragment shader");
return NO;
}
// Attach vertex shader to program.
glAttachShader(shaderProgram, vertShader);
// Attach fragment shader to program.
glAttachShader(shaderProgram, normFragShader);
// Bind attribute locations.
// This needs to be done prior to linking.
glBindAttribLocation(shaderProgram, ATTRIB_VERTEX, "position");
glBindAttribLocation(shaderProgram, ATTRIB_TEXTURECOORD, "texCoord");
// Link program.
if (![self linkProgram:shaderProgram]) {
NSLog(@"Failed to link program: %d", shaderProgram);
if (vertShader) {
glDeleteShader(vertShader);
vertShader = 0;
}
if (normFragShader) {
glDeleteShader(normFragShader);
normFragShader = 0;
}
if (shaderProgram) {
glDeleteProgram(shaderProgram);
shaderProgram = 0;
}
return NO;
}
// Get uniform locations.
uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(shaderProgram, "modelViewProjectionMatrix");
uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(shaderProgram, "texture");
// Release vertex and fragment shaders.
if (vertShader) {
glDetachShader(shaderProgram, vertShader);
glDeleteShader(vertShader);
}
if (normFragShader) {
glDetachShader(shaderProgram, normFragShader);
glDeleteShader(normFragShader);
}
return YES;
}
答案 0 :(得分:1)
我找到了答案。在我的第三个着色器中,我有一个名为“texture”的sampler2D。在Shaders中更改此名称并调用glGetUniformLocation修复了问题。我不明白为什么,因为“纹理”不是GLSL中的保留字,并且在任何其他制服中没有其他用词(有“texcoord”属性,但我怀疑这导致了问题) ,但它奏效了。
编辑:我实际上找到了这个问题的具体原因 - 我曾经使用过一些Apple的GLKit示例项目,该项目将着色器属性绑定到我使用的样本中的枚举。 View Controller的实现,意味着它的范围超出了类的特定实例。有这个问题的类实际上有两个着色器,当第二个被编译时,它擦除了以前的绑定。真正的谜团就是为什么我给出的第一个解决方案首先起作用了......