5

OpenGL を使用して Mac OS で描画しています。コードを Retina ディスプレイで実行すると、テキスト描画以外はすべて正常に動作します。Retinal ディスプレイでは、テキストが本来の 2 倍の大きさになります。これは、フォント サイズがポイント単位であり、Retina では各ポイントが 2 ピクセルであるために発生しますが、OpenGL はピクセル ベースです。

標準表示での正しいテキスト描画は次のとおりです。
標準表示での文字描画の修正

以下は、Retina ディスプレイでの誤ったテキスト描画です。
Retina ディスプレイでのテキスト描画が正しくない

これが私が通常どのように文字列を描くかです。OpenGL にはテキスト描画機能がないため、テキストを描画するには次のようにします。

  1. フォントを取得します。

    NSFontManager fontManager = [NSFontManager sharedFontManager];
    NSString
    font_name = [NSString stringWithCString: "Helvetica" エンコーディング: NSMacOSRomanStringEncoding];
    font = [fontManager fontWithFamily: font_name traits:fontStyle weight:5 size:9];
    attribs = [[NSMutableDictionary dictionaryWithCapacity: 3] 保持];
    [attribs setObject:font forKey:NSFontAttributeName];

  2. 文字列を作成して測定します。

    NSString* aString = [NSString stringWithCString: "何とか何とか" エンコーディング: NSMacOSRomanStringEncoding];
    NSSize frameSize = [aString sizeWithAttributes: m_attribs];

  3. 次のサイズで NSImage を割り当てます。

    NSImage* image = [[NSImage alloc] initWithSize:frameSize];
    [画像ロックフォーカス];

  4. 文字列を画像に描画します。

    [aString drawAtPoint:NSMakePoint (0, 0) withAttributes:m_attribs];

  5. ビットを取得します。

    NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect (0.0f, 0.0f, frameSize.width, frameSize.height)];
    [画像ロック解除フォーカス];

  6. OpenGL テクスチャを作成します。

    Gluint テクスチャ = 0;
    glGenTextures(1, &テクスチャー);
    glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, GLsizei(frameSize.width), GLsizei(frameSize.height), 0, GL_RGBA, [ビットマップ ビットマップデータ]);

  7. テクスチャを描く:

    glBindTexture ….
    その他の OpenGL 描画コード

私の質問は、ポイントではなくピクセル解像度で NSString を描画する方法です。

私は次のことを試しました:

  1. 9 ではなく 4.5 の半分のポイント サイズで描画します。これにより正しいサイズが得られますが、テキストがぼやけて描画されます。
  2. ポイント サイズで描画し、テクスチャを OpenGL の半分のサイズに縮小します。これも見栄えの良い結果にはなりません。
    テクスチャ縮小
4

3 に答える 3

1

OpenGL の座標系は、実際にはピクセル ベースではなくポイント ベースですが、それらのポイントを決定するのはあなたです。コンテキストは、画面上に最小および最大の x、y 座標を設定する glOrtho 関数 (または手動でオルソ行列を構築することもできます) によって 2D の座標系を定義します。たとえば、レンダリング先のフレームバッファのサイズに関係なく、0 が画面の左側にあり、100 が右側にあるように正射投影を設定できます。

フォント テクスチャは問題なく作成されているように見えます。問題は、必要なサイズの 2 倍のジオメトリでレンダリングしていることです。OpenGL では、テクスチャ サイズは画面にレンダリングされるオブジェクトのサイズには影響しません。画面上のサイズは、テクスチャではなく、glDrawArraysまたはその他に渡されるジオメトリによって定義されます。glBegin

問題は、フォント テクスチャのピクセル サイズを使用して、画面にレンダリングするために使用されるクワッド サイズを定義していることだと思います。これにより、問題が「他の OpenGL 描画コード」セクションに表示されます。これを修正するには、何らかの倍率を図面に適用できます。Retina モードでは倍率は 0.5 になり、通常の画面では 1.0 になります (UIKit は同様の考え方を使用して UIView コンテンツをレンダリングします)。

クワッド計算は次のようになります。

quad.width = texture.width * scaleFactor 
quad.height = texture.height * scaleFactor

もう 1 つのオプションは、クアッド レンダリング サイズをテクスチャから完全に分離することです。テキストを描画するための関数またはクラスがある場合、テクスチャ サイズを使用する代わりに、実際のクワッド サイズとして使用するフォント サイズ パラメータを持つことができます。

于 2012-10-10T14:14:04.257 に答える