iPad シミュレーターで実行している私の iOS プロジェクトには、3 つのシェーダー プログラムがあり、それぞれが似ているが同一ではない属性とユニフォームのセットを使用しています。これらのシェーダーの最初の 2 つは、コンパイルまたは描画プロセスのどの時点でも gl エラーなしで、完全にコンパイルおよび連携します。3 番目のシェーダーを追加する必要があり、これが問題を引き起こしました。現在、他のシェーダーは両方とも何も描画せず、glUniform を使用してユニフォームを渡そうとすると、glGetError が 1282 (GL_INVALID_OPERATION) を返します。glGetError は、glUniform が呼び出される前の行で 0 を返します。
ユニフォームを渡す前にGL_CURRENT_PROGRAMでglGetIntegervを呼び出すと、使用しようとしているプログラムのgl名と一致するため、glUniformを呼び出す前にプログラムを正しいものに設定していると思います(glUseProgramを問題の glUniform 呼び出しが行われるメソッドの先頭で使用したいプログラム)。glGetError は、問題のシェーダーをコンパイルする前後で 0 を返します。コンパイル コードは、Apple のサンプル プロジェクトの 1 つからわずかに変更されていますが、他のシェーダーの状態に影響を与えるようなコードは見当たりません。
- (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;
}