どのOpenGLテクスチャフォーマットがネイティブでサポートされているかをどのように検出しますか?


10

たとえば、ビデオカードが「bgr8」をサポートしていないかどうかを検出し、ソフトウェアモードで「rgba8」などの別の形式に変換する方法。

更新:混乱してすみません。状況の詳細この質問私は設定internalFormatglTexImage2Dを「bgra8」のようなものではなくvideodriver内部で「RGBA8」のように、別の形式にデータを変換します。

回答:


11

あなたの質問は特定の概念を混乱させるようですので、上から物事を取り上げましょう。これは関数の定義です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パラメータを。

別の言い方formattypeするとデータがどのように見えるかを定義しますinternalformatOpenGLにデータを保存するように指示する方法です。「ピクセル転送フォーマット」formatと呼びましょう。「画像フォーマット」になります。typeinternalformat

テクスチャの画像フォーマットは、「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の画像を。別のありformattypeの照会glReadPixelsダウンロード。

あなたが作ることができる他のクエリがあります

これらにアクセスできない場合は、ほとんどのハードウェアが準拠する一般的な経験則を使用できます。

  • 8ビット/チャネルデータのピクセルデータをBGRA順に格納します。あなたはより迅速にそうするように、あなたのピクセルデータとの形式と一致したテクスチャデータをアップロードしたいのであれば、あなたが使用したいGL_BGRAためformat、およびGL_UNSIGNED_INT_8888またはGL_UNSIGNED_BYTEのためにtype
  • 実際には、24ビットカラーを24ビットとして保存しません。常に32ビットにパディングします。データを読み取るとき、アルファは無視されます。したがって、フォーマットを一致させたい場合は、アルファコンポーネントにダミーデータを配置する必要がある場合でも、常に画像フォーマットを使用GL_BGRA formatしてGL_RGB8ください。

4
また、internalFormat GL_RGBAhttp.download.nvidia.com/developer/Papers/2005/…でフォーマットGL_BGRAを使用する方が良いことがわかりました
KindDragon

internalFormatパラメータの名称を「画像フォーマット」に変更することは控えます。これも同様に混乱を招くためです。おそらく、「internalFormat」を「テクスチャピクセルフォーマット」と考えることは理にかなっています。「フォーマット」と「タイプ」パラメータの組み合わせは「ソースピクセルフォーマット」です(これは多くの場合、画像なので、私のコメントです)。そしてもちろん、GPU形式もあります。これは整数型形式のBGRAです。
StarShine

6

通常、ほとんどのハードウェアは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が何かを実行できない場合は、問題のあるものがハードウェアでサポートされていないことを示している可能性があります。常に正しいとは限りませんが、便利な出発点です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.