0

だから、私はかなり奇妙な問題を抱えています。その理由はわかりません。次の opengl コードを Retina 画面に表示すると、次の画像が表示されます。 ここに画像の説明を入力

非網膜に表示される画像は次のとおりです。 ここに画像の説明を入力

座標系は正常に設定されているはずです..また、一般的に網膜のサイズに合わせてスケーリングされていないように見えることにも気付きました. [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]); のようにサイズを手動でスケーリングする必要があります。これは私が思いついた最も簡単な方法でした。*

4

3 に答える 3

2

OpenGL 自体は、ビューや画面の特性について何も知りません。ピクセルについてのみ知っています。

デフォルトでは、他の UIView とは異なり、GL ベースのビューは自動的に 1.0 以外のスケールを使用せず、代わりに 1x で動作します。あなたが発見したように、画面のスケールを網膜ピクセル解像度 (両方の寸法で 2 倍のサイズ) にオプトインするように設定する必要があります。

ただし、ピクセル数を増やすと、ピクセル数が増えるだけです。GL は、すべてのジオメトリをスケーリングする必要があることを魔法のように認識しません (または、実際にはそれが本当に必要なことです)。両方のスケール ビューに同じジオメトリを使用する場合 (通常はそうします)、はい、スケールを適用する責任もあります。

ES 1.1 (使用しているようですが、これは次のとおりです。

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

ES 2.0 では、これをモデル ビューまたは投影マトリックスに適用し、頂点シェーダーで使用して入力ジオメトリを変換します。

于 2013-03-06T02:46:07.740 に答える
0

ビューの「スケール」メソッドを見つけました。これは、ビューのサイズを適切に変更するために設定する必要があるようです(ビューはピクセルではなく位置ベースであり、奇妙な理由により、解像度を上げても位置のサイズは変更されません)。これは私が本当に見つけることができた唯一のものです。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;
        }
于 2013-03-06T00:55:50.073 に答える
0

これが私が setContentScaleFactor を使用する方法です。Retina デバイスを使用していて、古い非 Retina 解像度セットにレンダリングしたいだけで、1 にスケーリングすると iOS がそれを 2 倍にします。

それ以外の場合、Retina デバイスを検出するコードを作成し、それに応じてより大きなビューポートを作成する場合は、ContentScaleFactor を 2 に設定して、iOS によってそのまま残されます。

于 2013-03-06T02:30:00.350 に答える