在我在 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;
}