これは、Xcode 4.5 の OpenGL Game サンプル プロジェクトに基づいて、私が作成した "GLKView Subview" アプリの例です。両方の OpenGL ES 2 ビューが 1 つのコントローラーによって制御されるように、デリゲートをファイル所有者の GLKViewController に設定して GLKView サブビューを作成します。
これがスクリーンショットです。コントラストのためにサブビューの背景を赤くしています。
フレームサイズが壊れていることに気付くまで、(テクスチャなどを共有するために)1つのGLKViewControllerとEAGLContextの下に複数のGLKViewを追加する簡単な方法があることに興奮しました。
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
NSLog(@"My view frame: %@", NSStringFromCGRect(view.bounds));
float aspect = fabsf(view.bounds.size.width / view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
// Compute the model view matrix for the object rendered with GLKit
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Compute the model view matrix for the object rendered with ES2
modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
if(view == self.view)
{
glClearColor(0.65f, 0.65f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object with GLKit
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
// Render the object again with ES2
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 36);
[self.subview display];
}
else
{
glClearColor(1.0f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object with GLKit
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
// Render the object again with ES2
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
}
iPhone 4" Retina を使用した iOS シミュレーターでの出力:
2013-04-27 15:50:56.149 GLKView Subview[48136:11903] My view frame: {{0, 0}, {568, 320}}
2013-04-27 15:50:56.152 GLKView Subview[48136:11903] My view frame: {{0, 0}, {248, 100}}
サブビューのフレームは {100, 100} のはずですが、何らかの理由で {248, 100} になっています。メインのGLKViewがその親である場合、おそらくその自動サイズ変更の制約が間違って設定されていると考えて、UIViewに埋め込むことさえ、私が考えることができるすべてを試しました。ご覧のとおり、UIView のサイズは正しいのですが、子 GLKView のサイズが壊れています。
開発者としては、これが最初に試すことのように思えましたが、Apple には通常、他のアイデアがあります。自動サイズ変更なしでは、GLKView は、任意のデバイス サイズで動作するフリーフォーム レイアウトには役に立ちません。
別のプロジェクトで子コントローラーとして機能する単一の EAGLContext を共有する複数の GLKViewControllers を取得することができました。しかし、GLKView を画面に追加するたびに GLKViewController を作成するという荷物を背負わなければならない理由がわかりません。私の推測では、GLKViewController が独自のビューではない GLKView のデリゲートである場合、GLKViewController は混乱します。
glViewport() を使用するだけでビューを手動で機能させることもできました.GLKViewの問題で2日を失った後、これを読んでいる人にはそのルートに行くことをお勧めします(クロスプラットフォームの利点も得られます)。
「GLKViewごとにGLKViewControllerを作成する必要がある」だけであっても、簡単な説明/修正があることを願っています。それを機能させることができた人に前もって感謝します。そうでない場合は、このバグ機能の例が誰かを助けるかもしれません。