Apple Developer Connection
Advanced Search
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page >

OpenGL

OpenGL画像またはテクスチャを定義するときは、テクスチャのフォーマットをOpenGLに指定するために、タイプを渡す必要があります。これらの関数の大部分(たとえばglTexImage2Dは、テクスチャをディスクまたはメモリに配置する方法を指定するformatパラメータとtype_パラメータを取ります。OpenGLはいくつかの画像タイプをサポートしています。その中にはエンディアン中立なものもあれば、そうでないものもあります。

たとえば、一般的な画像フォーマットの1つはGL_RGBAで、タイプがGL_UNSIGNED_BYTEです。これは、画像には赤のデータを指定するバイトに続いて緑のデータを指定するバイトがあり、以下同様に続くという意味です。このフォーマットはエンディアンに固有ではなく、バイト順序はすべてのアーキテクチャで同じです。もう1つの一般的な画像フォーマットはGL_BGRAで、多くの場合はタイプGL_UNSIGNED_INT_8_8_8_8_REVによって指定されます。このタイプは、画像データが4バイトごとにunsigned intと解釈され、最上位の8ビットがアルファデータを示し、次に上位にある8ビットが赤色データを示すというようになっています。このフォーマットはホストの整数フォーマットに依存するので、ビッグエンディアンのシステムとリトルエンディアンのシステムでは、フォーマットが異なって解釈されます。GL_UNSIGNED_INT_8_8_8_8_REVを使用すると、OpenGLの実装は、データのバイト順序がビッグエンディアンのシステムではARGB、リトルエンディアンのシステムではBGRAであるとみなします。

OpenGLでは32ビットまたは16ビットパックピクセル(Macintosh PowerPCコンピュータで一般的な画像フォーマット)がARGBのバイト順序であること明示的に指定する方法はないので、多くのアプリケーションではGL_BGRAとともにGL_UNSIGNED_INT_8_8_8_8_REVを指定します。この手法はPowerPCなどのビッグエンディアンのシステムでは有効ですが、リトルエンディアンのシステムではこのフォーマットは異なって解釈され、画像が間違った色でレンダリングされます。

この問題のあるアプリケーションは、OpenGLのホストの順序のフォーマットタイプを使用していて、参照対象データが常にビッグエンディアンであると想定しているアプリケーションです。これらのタイプとしては以下のものがありますが、これだけではありません。

GL_SHORT
GL_UNSIGNED_SHORT
GL_INT
GL_UNSIGNED_INT
GL_FLOAT
GL_DOUBLE
GL_UNSIGNED_BYTE_3_3_2
GL_UNSIGNED_SHORT_4_4_4_4
GL_UNSIGNED_SHORT_5_5_5_1
GL_UNSIGNED_INT_8_8_8_8
GL_UNSIGNED_INT_10_10_10_2
GL_UNSIGNED_SHORT_5_6_5
GL_UNSIGNED_BYTE_2_3_3_REV
GL_UNSIGNED_SHORT_5_6_5_REV
GL_UNSIGNED_SHORT_4_4_4_4_REV
GL_UNSIGNED_SHORT_1_5_5_5_REV
GL_UNSIGNED_INT_8_8_8_8_REV
GL_UNSIGNED_INT_2_10_10_10_REV

アプリケーションがこれらのタイプを使用していなければ、OpenGLに関する問題はおそらくありません。アプリケーションがこれらのタイプのいずれかを使用するのは必ずしも間違いではありません。多くのアプリケーション、特に既存のクロスプラットフォームコードでは、Mac OS Xの実装がWindowsの実装と同じように動作するので、ホストのバイト順序のデータに、これらのフォーマットのいずれかをタグ付けして提示している可能性があります。

アプリケーションがこれらのタイプのいずれかを間違って使用していると、OpenGLのテクスチャと画像は間違った色でレンダリングされます。たとえば、赤が緑になったり、画像が薄い紫がかった色で表示される可能性があります。

このような問題は、次のいずれかの方法で修正できます。

  1. 画像をアルゴリズムで生成またはロードする場合は、OpenGLが期待しているものと一致するホストのバイト順序のフォーマットでテクスチャを生成するようにコードを変更します。たとえば、JPEGデコーダならば、その出力を4つの8ビットバイトではなく、32ビットの整数に格納するように変更できます。ビッグエンディアンのシステムでは、結果のデータは同じですが、リトルエンディアンのシステムではバイトは異なる順序になります。これはOpenGLの期待と一致しており、既存のOpenGLコードはどちらのアーキテクチャでも正しく機能し続けます。これが推奨されるアプローチです。

    多くの場合、アルゴリズムを書き換えると、実装とデバッグはかなりの作業になります。そのような場合は、OpenGLにテクスチャデータを異なるものとして解釈させるアプローチを取ったほうがよいかもしれません。

  2. アプリケーションがGL_UNSIGNED_INT_8_8_8_8_REVまたはGL_UNSIGNED_INT_8_8_8_8を使用している場合は、アーキテクチャに基づいてそれらを切り替えることができます。この2つのタイプは同じフォーマットを正確にバイトスワップしたものなので、ビッグエンディアンのシステムでGL_UNSIGNED_INT_8_8_8_8_REVを使用することは、リトルエンディアンのシステムでGL_UNSIGNED_INT_8_8_8_8を使用するのと同じであり、逆もまた同様です。コードを次のようにします。

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGRA_EXT,
    #if __BIG_ENDIAN__
                        GL_UNSIGNED_INT_8_8_8_8_REV,
    #else
                        GL_UNSIGNED_INT_8_8_8_8,
    #endif
                        data);

    これがよく使用する表現であれば、何度も使用できるマクロとして定義するのが最も簡単かもしれません。

    #if __BIG_ENDIAN__
    #define ARGB_IMAGE_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
    #else
    #define ARGB_IMAGE_TYPE GL_UNSIGNED_INT_8_8_8_8
    #endif
    /* 後で、これを次のように使用する */
    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
                    width, height, 0, GL_BGRA_EXT,
                    ARGB_IMAGE_TYPE, data);

    GL_UNSIGNED_INT_8_8_8_8_REVGL_UNSIGNED_INT_8_8_8_8の切り替えが有効なのは、このような32ビットパックピクセルデータタイプの場合だけです。GL_UNSIGNED_SHORT_1_5_5_5_REVを使用して格納された16ビットARGBデータは、バイトがスワップされた対応するタイプはありません。インテルベースのMacintoshコンピュータでは、GL_UNSIGNED_SHORT_5_5_5_1GL_UNSIGNED_SHORT_1_5_5_5_REVの代替ではないことに留意してください。このフォーマットは、ビッグエンディアンのシステムではビット順序arrrrrbbbbbgggggとして解釈され、リトルエンディアンのシステムではビット順序ggrrrrrabbbbbgggとして解釈されます。

  3. 前述の方法を適用できない場合、システムのネイティブなエンディアンフォーマットのデータを生成/ロードし、どちらのアーキテクチャにも同じピクセルタイプを使用するか、GL_UNPACK_SWAP_BYTESピクセルストア設定を使用して、リトルエンディアンのシステムにロードされたテクスチャをすべてバイトスワップするようにOpenGLに指示する必要があります。この設定は現在のOpenGLコンテキストで作成したすべてのテクスチャまたは画像に適用されるため、OpenGLコンテキストごとに一度だけ設定すれば済みます。

    #if __LITTLE_ENDIAN__
                glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
    #endif

    この方法は、問題のあるフォーマットを使用している画像をPowerPC上と同じようにロードします。このオプションは、他のオプションが利用できない場合にのみ検討してください。このオプションを有効にすると、OpenGLが通常よりも遅いレンダリングパスを使用します。パフォーマンスに敏感なOpenGLアプリケーションでは、このオプションを有効にすると、オフの場合よりも大幅に遅くなる可能性があります。この方法ではOpenGLベースのプログラムを考えられる最短の時間で動くようにできますが、他の2つの方法のいずれかを使用することを強くお勧めします。

注: GL_BGRAデータにGL_UNSIGNED_INT_8_8_8_8フォーマットを使用しても、GL_UNPACK_SWAP_BYTESを使用した場合に比べても必ずしも高速になりません。場合によっては、GL_UNSIGNED_INT_8_8_8_8_REVなどのデータタイプを使用する場合と比較して、これら2つの方法のいずれかを使用するテクスチャレンダリングはパフォーマンスが低下します。Sharkなどのツールを使用して、OpenGLコードのパフォーマンスを分析し、特にひどいケースに遭遇しないことを確認することをお勧めします。



< Previous PageNext Page >


Last updated: 2006-03-08




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice