gl コンテキストで CAEAGLLayer サブクラスをセットアップしようとしています。つまり、CAEAGLLayer を返す UIView サブクラスを作成し、UIView サブクラス内から gl コンテキストをこのレイヤーにバインドする代わりに、レイヤーを直接サブクラス化し、レイヤーの init でコンテキストをセットアップしようとしています。
- (id)init
{
self = [super init];
if (self) {
self.opaque = YES;
_glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
NSAssert([EAGLContext setCurrentContext:_glContext], @"");
glGenRenderbuffers(1, &_colorRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
[_glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:self];
glGenFramebuffers(1, &_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);
/// . . .
その時点まではすべて問題ないようです。ただし、「パススルー」頂点/フラグメント シェーダー ペアを使用してシェーダー プログラムを作成しようとすると、プログラムをリンクしてもエラーは返されませんが、「現在の描画フレーム バッファーが無効です」というメッセージが表示されて検証に失敗します。
シェーダー プログラムをリンクして検証するコード (シェーダーをアタッチした後) は、次のようになります。
- (BOOL)linkAndValidateProgram
{
GLint status;
glLinkProgram(_shaderProgram);
#ifdef DEBUG
GLint infoLogLength;
GLchar *infoLog = NULL;
glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
infoLog = (GLchar *)malloc(infoLogLength);
glGetProgramInfoLog(_shaderProgram, infoLogLength, &infoLogLength, infoLog);
NSLog(@"Program link log:\n%s", infoLog);
free(infoLog);
}
#endif
glGetProgramiv(_shaderProgram, GL_LINK_STATUS, &status);
if (!status) {
return NO;
}
glValidateProgram(_shaderProgram);
#ifdef DEBUG
glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
infoLog = (GLchar *)malloc(infoLogLength);
glGetProgramInfoLog(_shaderProgram, infoLogLength, &infoLogLength, infoLog);
NSLog(@"Program validation log:\n%s", infoLog);
free(infoLog);
}
#endif
glGetProgramiv(_shaderProgram, GL_VALIDATE_STATUS, &status);
if (!status) {
return NO;
}
glUseProgram(_shaderProgram);
return YES;
}
CAEAGLLayer のライフサイクルのある時点で、気づいていないかもしれない追加のセットアップがあり、init で GL をセットアップしようとしてスキップしている可能性があるのではないかと思っています。