【问题标题】:OpenGL ES 1.1 iOS not sizing properly on retina versus non retinaOpenGL ES 1.1 iOS 在视网膜与非视网膜上的尺寸不正确
【发布时间】:2013-03-07 01:48:38
【问题描述】:

所以,我遇到了一个很奇怪的问题,我不知道为什么。在视网膜屏幕上显示以下 opengl 代码时,我收到以下图像:

虽然我在非视网膜上得到的图像如下:

应该正常设置坐标系。我还注意到它似乎通常不会缩放到视网膜大小。从 [UIScreen 主屏幕] 获取框架时,我得到的视网膜和非的值相同,如下所示。我想有什么特殊的方法来调整这个大小吗?

frame: Origin: x:0.000000 y:0.000000, Size: width:768.000000 height:1024.000000

*编辑:原因是 OpenGL ES 1.1 不能自行缩放到 Retina 大小。创建 ViewPort 时,您必须手动缩放大小,例如 glViewport(0, 0, width * [[UIScreen mainScreen] scale], height * [[UIScreen mainScreen] scale]); 这是我能想到的最简单的方法。*

【问题讨论】:

    标签: xcode opengl-es drawing coordinates


    【解决方案1】:

    OpenGL 本身对视图或屏幕特性一无所知;它只知道像素。

    默认情况下,与其他 UIView 不同,GL 支持的视图不会自动使用非 1.0 比例,而是以 1x 操作。因此,正如您所发现的,您应该设置屏幕比例以选择视网膜像素分辨率(两个维度的大小都是 2 倍)。

    但是,增加像素数只会增加像素数。 GL 并不神奇地知道它应该缩放所有几何体(或者实际上这就是你真正想要的)。如果您想对两个比例视图使用相同的几何图形(您通常会这样做),那么是的,您还需要负责应用比例。

    在 ES 1.1 中(您似乎正在使用,这只是:

    glScalef([UIScreen mainScreen] scale], [UIScreen mainScreen] scale], 1.0);
    

    在 ES 2.0 中,您可以将其应用于模型视图或投影矩阵,然后在顶点着色器中使用它来转换输入几何体。

    【讨论】:

    • 好吧,我并不是特别需要这种方式(它肯定会缩放它。我使用 glViewport(0, 0, width * [[UIScreen mainScreen] scale], height * [[UIScreen mainScreen] ] scale]); 编辑视口以缩放。我不喜欢我必须手动乘以比例的想法,但是该怎么办。我只是在查看 OpenGL ES 1.1 以获得更深入的知识。我知道我'在 ES 2.0 中从来不用担心这个问题。所以不再担心了。
    【解决方案2】:

    我发现视图的“缩放”方法显然需要设置为正确调整视图的大小(因为视图是基于位置而不是像素的,并且由于某些奇怪的原因,位置不会随着分辨率的增加而调整大小和这样的)。这是我唯一能真正找到的东西。我注意到在 GLView 的 init 方法中包含以下调用检查和设置...但我仍然想知道是否有更好的方法。我不是必须通过将高度和宽度乘以 scale 属性来手动调整所有内容的大小吗?

    - (id)initWithFrame:(CGRect)frame
    {
    
        NSLog(@"frame: Origin: x:%f y:%f, Size: width:%f height:%f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
    
        self = [super initWithFrame:frame];
        if (self) {
    
            **if([[UIScreen mainScreen] respondsToSelector: NSSelectorFromString(@"scale")])
            {
                if([self respondsToSelector: NSSelectorFromString(@"contentScaleFactor")])
                {
                    [self setContentScaleFactor:[[UIScreen mainScreen] scale]];
                    NSLog(@"Scale factor: %f", [[UIScreen mainScreen] scale]);
                }
            }**
    
            NSLog(@"frame: Origin: x:%f y:%f, Size: width:%f height:%f Scale factor: %f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height, self.contentScaleFactor);
            CAEAGLLayer *eaglLayer = (CAEAGLLayer *)super.layer;
            eaglLayer.opaque = YES; // set to indicate that you do not need Quartz to handle transparency. This is a performance benefit.
    
            context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
    
            if (!context || ![EAGLContext setCurrentContext:context]) {
                return nil;
            }
    

    【讨论】:

      【解决方案3】:

      这就是我使用 setContentScaleFactor 的方式——如果您使用的是视网膜设备,并且您只想渲染到缩放为 1 的旧非视网膜分辨率设置,iOS 会为您加倍大小。

      否则,如果您编写代码来检测 Retina 设备并创建相应更大的视口,请将 ContentScaleFactor 设置为 2 以由 iOS 单独保留。

      【讨论】:

        猜你喜欢
        • 2014-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 1970-01-01
        • 2018-12-09
        • 2013-02-10
        相关资源
        最近更新 更多