回答:
あなたの質問は特定の概念を混乱させるようですので、上から物事を取り上げましょう。これは関数の定義ですglTexImage2D
:
void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );
「テクスチャフォーマット」と呼ばれるものは2つあります。最初はinternalformat
パラメータです。これは、OpenGLが保存する画像の実際の 形式です。format
パラメータは、ピクセルデータのフォーマットの一部を説明し、あなたがして提供しているdata
パラメータを。
別の言い方format
をtype
すると、データがどのように見えるかを定義します。internalformat
OpenGLにデータを保存するように指示する方法です。「ピクセル転送フォーマット」format
と呼びましょう。「画像フォーマット」になります。type
internalformat
テクスチャの画像フォーマットは、「bgr8」であってはなりません。GL_BGR8画像形式の列挙子はありません。GL_BGR列挙型がありますが、それはピクセル転送フォーマット用であり、画像フォーマット用ではありません。
別の言い方をすると、OpenGLに与えるピクセルデータをBGR順に保存できます。しかし、OpenGL実装は、そのピクセルデータを実際に格納する方法を独自に決定します。多分それはリトル・エンディアン順でそれを保存します。多分それはそれをビッグエンディアンに格納します。多分それは単にバイトを任意に再配置します。あなたは知りません、そしてOpenGLはそれを見つける方法を提供しません。
特定のピクセル転送形式パラメーターのセットが、画像形式でOpenGL実装がそれらを格納する方法と一致するかどうかを判断する方法はありません。
今言う方法があります。「今」とは、OpenGL 4.3やARB_internalformat_query2を意味します。お近くのグラフィックカードに来る:
GLenum format, type;
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &format);
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1, &type);
format
そしてtype
今持っている実装の優先format
およびtype
使用のためglTex(Sub)Image
の呼び出しGL_RGBA8
の画像を。別のありformat
とtype
の照会glReadPixels
ダウンロード。
これらにアクセスできない場合は、ほとんどのハードウェアが準拠する一般的な経験則を使用できます。
GL_BGRA
ためformat
、およびGL_UNSIGNED_INT_8888
またはGL_UNSIGNED_BYTE
のためにtype
。GL_BGRA
format
してGL_RGB8
ください。通常、ほとんどのハードウェアは3コンポーネントテクスチャフォーマットをサポートしていません。このため、この特定の例では、変換されたというかなり安全な仮定を行うことができます。3コンポーネントのOpenGLテクスチャは、実際にはハードウェアでは4コンポーネントですが、アルファコンポーネントは無視されるか、255に設定されます。
https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads (この「よくある間違い」ページは金鉱です-今すぐブックマークしてください!)
より一般的なケースでは、glTexSubImage2Dのパフォーマンスは、アップロードがソフトウェア変換パスを経由する必要があるかどうかを示す良い指標となります。これはプログラムの起動時に行います-空のテクスチャを(NULLデータを含むglTexImage2Dを介して)作成し、次に一連のglTexSubImage2D呼び出しを発行し、その後にglFinishを続けて完了します。caches / states / etcがセットアップされているので、最初のものを無視し、残りの時間を計ります。いくつかの異なるフォーマットについてこれを繰り返し、最速のものを選びます。
別の代替方法-この質問に「Windows」のタグを付けた場合、起動時にD3Dデバイスを作成して(ウィンドウを作成した直後、ただしOpenGLを初期化する前に)、D3Dを使用してフォーマットのサポートを確認します。OpenGLではソフトウェアを有効な内部形式に変換できますが、D3Dではできません。ハードウェアでサポートされていない場合は実行できません。次に、D3Dを破棄してOpenGLを起動します。(この手法は、OpenGLでは直接クエリできない他の要素のクエリにも使用できます)。
OpenGLで何をしているかをD3Dのドキュメントとクロスチェックすることは、実際には便利な経験則です。D3Dが何かを実行できない場合は、問題のあるものがハードウェアでサポートされていないことを示している可能性があります。常に正しいとは限りませんが、便利な出発点です。