这是我编写的示例“GLKView Subview”应用程序,基于 Xcode 4.5 中的 OpenGL 游戏示例项目。它创建一个 GLKView 子视图,其委托设置为文件所有者的 GLKViewController,以便两个 OpenGL ES 2 视图都由一个控制器控制:
这是一个屏幕截图,我将子视图的背景染成红色以进行对比:
我很高兴我有一种直接的方法可以在一个 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}。我已经尝试了我能想到的一切,甚至将它嵌入到 UIView 中,认为如果主 GLKView 是它的父级,它的自动调整大小约束可能设置错误。如您所见,UIView 的大小是正确的,但子 GLKView 的大小是不正确的。
作为开发人员,这似乎是首先要尝试的事情,但苹果通常有其他想法。如果没有自动调整大小,GLKView 对适用于任何设备尺寸的自由格式布局毫无用处。
我设法让多个 GLKViewControllers 共享一个 EAGLContext 作为不同项目中的子控制器。但我不明白为什么每次我们想向屏幕添加 GLKView 时,我们都必须背负创建 GLKViewController 的包袱。我的猜测是,当 GLKViewController 是不是它自己的视图的 GLKView 的委托时,它会感到困惑。
我还设法通过使用 glViewport() 手动使我的视图工作,并且在因 GLKView 问题而失去两天后,我可能会建议任何阅读这篇文章的人走这条路(也获得跨平台优势)。
我希望有一个简单的解释/修复,即使它只是“你必须为每个 GLKView 制作一个 GLKViewController”。提前感谢任何设法让它工作的人。如果没有,也许这个错误功能的一个例子会对某人有所帮助。