以下是我根据Xcode 4.5中的OpenGL Game示例项目编写的“GLKView Subview”应用程序示例。它创建了一个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在iOS模拟器中输出“Retina:
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是它的父级,它的autoresize约束可能会被设置错误。正如你所看到的,UIView的大小是正确的,但是孩子GLKView的大小是不正确的。
作为开发人员,这似乎是首先要尝试的,但Apple通常还有其他想法。如果没有自动调整大小,GLKView对于适用于任何设备大小的自由形式布局都是无用的。
我设法让多个GLKViewControllers共享一个EAGLContext作为不同项目中的子控制器。但是我不明白为什么每次我们想要在屏幕上添加GLKView时都要承担创建GLKViewController的责任。我的猜测是当GLKViewController是GLKView的委托而不是它自己的视图时会感到困惑。
我还设法通过使用glViewport()手动使我的视图工作,并且在失去两天GLKView问题后,我可能会建议将这条路线传递给任何阅读此内容的人(同时获得跨平台优势)。
我希望有一个简单的解释/修复,即使它只是“你必须为每个GLKView制作一个GLKViewController”。提前感谢任何能够让它工作的人。如果没有,也许这个 bug 功能的一个例子可以帮助某人。
答案 0 :(得分:0)
我找到了解决方法。只需使用示例项目,但关闭GLKView及其黑色父UIView的自动调整大小调整中最右边的红色条。
说明:由于纵横比不同于3.5"到4"在iPhone显示屏上,自动调整功能会尝试满足正确的边距约束,从而水平拉伸视图。通过告诉它保持左边距和宽度,但不是右边距,它可以在主视图中正确定位和调整视图。
仍然有一些不稳定的事情,因为如果你在黑色UIView中嵌入另一个白色UIView并设置其所有大小和边距限制,它会在其黑色父UIView中正确自动调整,而如果检查所有约束,GLKView将无法执行此操作。 GLKView似乎仍然针对根UIView进行自动调整,现在看来这是一个bug。它可能与将GLKView委托设置为File&#39的所有者有关。我已提交 Apple Bug ID#13777142 ,如果您想提交自己的错误报告,可以参考。
P.S。如果我将每个GLKView嵌入到自己的the other posts on Stack Overflow say to do GLKViewController中,我就不会看到这些问题。