0

这是我编写的示例“GLKView Subview”应用程序,基于 Xcode 4.5 中的 OpenGL 游戏示例项目。它创建一个 GLKView 子视图,其委托设置为文件所有者的 GLKViewController,以便两个 OpenGL ES 2 视图都由一个控制器控制:

http://dh.st/7R1

这是一个屏幕截图,我将子视图的背景染成红色以进行对比:

http://dh.st/om4

我很高兴我有一种直接的方法可以在一个 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”。提前感谢任何设法让它工作的人。如果没有,也许这个错误功能的一个例子会对某人有所帮助。

4

1 回答 1

0

我找到了解决方法。只需使用示例项目,但关闭 GLKView 及其黑色父 UIView 的 Autosizing 调整中最右侧的红色条。

说明:由于从 3.5 英寸到 4 英寸 iPhone 显示屏的纵横比不同,自动调整大小会尝试满足右边距约束,从而水平拉伸视图。通过告诉它保持左边距和宽度,而不是右边距,它可以在主视图中正确定位和调整视图的大小。

尽管如此,还是会发生一些奇怪的事情,因为如果您在黑色 UIView 中嵌入另一个白色 UIView 并设置其所有大小和边距约束,它会在其黑色父 UIView 内正确自动调整大小,而如果您检查所有其约束。GLKView 似乎仍在针对根 UIView 自动调整大小,目前这似乎是一个错误。它可能与将 GLKView 委托设置为文件所有者有关。我已经提交了Apple Bug ID# 13777142,如果你想提交自己的错误报告,可以参考它。

PS 如果我将每个 GLKView 嵌入到它自己的 GLKViewController 中,我看不到这些问题,就像Stack Overflow 上的其他帖子所说的那样

于 2013-04-30T22:18:13.030 回答