【问题标题】:Actual landscape OpenGL View on iOSiOS 上的实际景观 OpenGL 视图
【发布时间】:2011-09-24 13:35:31
【问题描述】:

我正在将基于 C++ 的引擎从 Android 移植到 iOS,我对 iOS 设备上的横向模式如何工作有一些疑问。

我可以在横向模式下成功启动我的设备,但无论我如何旋转它(或强制它旋转),我的帧缓冲区都保持在纵向模式。例如,我希望分辨率为 960x640,而不是默认的 320x480。

我一直在研究它,我看到有人这样做,但使用 OpenGL 显式旋转场景,这意味着实际轴不在横向模式下,这对我来说是一个丑陋的解决方法。

【问题讨论】:

    标签: ios opengl-es screen landscape


    【解决方案1】:

    确保您的 OpenGL UIView 已附加到 UIViewController 而不是直接插入 UIWindow。为此,请创建一个自定义视图控制器:

    @interface MyViewController : UIViewController
    @end
    
    @implementation MyViewController
    - (void)loadView {
        // Create your EAGL view
        MyEAGLView *eaglView = [[MyEAGLView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
        self.view = eaglView;
        [eaglView release];
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        return YES;
    }
    @end
    

    然后通过 AppDelegate 将其添加到您应用的窗口中:

    - (void)applicationDidFinishLaunching:(UIApplication *)application {
        MyViewController *viewController = [[MyViewController alloc] init];
        [self.window setRootViewController:viewController];
        [viewController release];
        [self.window makeKeyAndVisible];
    }    
    

    self.window 只是应用程序的 UIWindow,如果您将窗口存储在其他位置,您可能需要更改它。

    之后,UIViewController 会在设备转动时负责旋转和调整视图大小,您可以覆盖 MyEAGLView 对象中的 layoutSubviews 方法来处理 OpenGL 上下文的大小调整。您可能还想查看 Apple 的 OpenGL 应用示例代码,因为它可以正确处理这些内容。

    【讨论】:

    • 效果很好,但是如果我像您的示例中那样设置一个零矩形,屏幕仍然是黑色的。当我将其设置为 [[UIScreen mainScreen] bounds] 时,它会创建一个 320x480 帧缓冲区,并按预期将其沿设备的横向框架拉伸。如果我手动将侧轴反转为 480x320,效果很好,但有没有更安全的方法?请注意,我不需要在运行时执行帧缓冲区调整大小,仅在启动时执行。
    • 我不确定是否有更安全的方式本身——这实际上也是 Apple 自己的示例代码的做法。我不确定为什么零矩形会导致问题,因为视图控制器应该在您在其控制器上调用 setRootViewController 后立即调整它的大小。也许零矩形搞砸了 OpenGL 上下文的初始化。
    • 我应该提一下,检查您应用的 info.plist 并确保在“支持的设备方向”部分中启用了所有方向。
    【解决方案2】:

    您可以按如下方式在顶点着色器中旋转 OpenGL 输出:

    #version 300 es
    
    
    in vec4 position;
    in mediump vec4 texturecoordinate;
    
    in vec4 color;
    
    uniform float preferredRotation;
    
    out mediump vec2 coordinate;
    
    void main()
    {
        //const float pi = 4.0 * atan(1.0);
        //float radians  = (( -90.0 ) / 180.0 * pi );
    
        // Preferred rotation of video acquired, for example, by:
        // AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
        // CGAffineTransform preferredTransform = [videoTrack preferredTransform];
        // self.glKitView.preferredRotation = -1 * atan2(preferredTransform.b, preferredTransform.a);
    
        // Preferred rotation for both portrait and landscape           
        mat4 rotationMatrix = mat4( cos(preferredRotation), -sin(preferredRotation), 0.0, 0.0,
                                    sin(preferredRotation),  cos(preferredRotation), 0.0, 0.0,
                                    0.0,                     0.0,                    1.0, 0.0,
                                    0.0,                     0.0,                    0.0, 1.0);
    
        // Mirror vertical (portrait only)
        mat4 rotationMatrix = mat4( cos(preferredRotation),  sin(preferredRotation), 0.0, 0.0,
                                   -sin(preferredRotation),  cos(preferredRotation), 0.0, 0.0,
                                    0.0,           0.0,          1.0, 0.0,
                                    0.0,           0.0,          0.0, 1.0);
    
        // Mirror horizontal (landscape only)
        mat4 rotationMatrix = mat4( 1.0, 0.0,                     0.0,                    0.0,
                                    0.0, cos(preferredRotation), -sin(preferredRotation), 0.0,
                                    0.0, sin(preferredRotation),  cos(preferredRotation), 0.0,
                                    0.0, 0.0,                     0.0,                    1.0);
    
        // Mirror vertical (landscape only)
        mat4 rotationMatrix = mat4( cos(preferredRotation), 0.0, sin(preferredRotation), 0.0,
                                    0.0,                    1.0, 0.0,                    0.0,
                                   -sin(preferredRotation), 0.0, cos(preferredRotation), 0.0,
                                    0.0,                    0.0, 0.0,                    1.0);
    
        gl_Position = position * rotationMatrix;
        coordinate = texturecoordinate.xy;
    }
    

    显然,您只选择一个矩阵4,具体取决于方向 视频,然后旋转。每个matrix4翻转视频 窗口 - 不旋转它。对于旋转,您必须首先选择 matrix4 基于方向,然后代入 带有度数的首选旋转变量(以弧度为单位, 还提供了公式)。

    有很多方法可以旋转视图、图层、对象等;但是,如果 您正在通过 OpenGL 渲染图像,那么您应该选择这个 方法,而且只有这个方法。

    【讨论】:

      猜你喜欢
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 2015-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多