14

ご存知のように、openGL は左/下が 0/0 のピクセル データ方向を使用しますが、その他の世界 (事実上すべての画像形式を含む) は左/上を使用します。これは何年もの間 (少なくとも私にとっては) 終わりのない心配事の源であり、私はまだ良い解決策を思い付くことができていません.

私のアプリケーションでは、次の画像データをテクスチャとしてサポートしたいと考えています:

  1. さまざまな画像ソースからの画像データ (静止画像、ビデオ ファイル、ライブ ビデオを含む)
  2. フレームバッファをメインメモリにコピーして取得した画像データ ( glReadPixels)
  3. フレームバッファをテクスチャにグラブして取得した画像データ ( glCopyTexImage)

(ケース #1 はトップダウンの向きで画像を提供します (ケースの約 98% で、簡単にするために、すべての「外部画像」がトップダウンの向きであると仮定しましょう); #2 と #3 はボトムアップの向きです。 )

これらすべてのテクスチャをさまざまな任意の複雑なオブジェクト (たとえば、テクスチャ座標情報が格納されているディスクから読み取った 3D モデル) に適用できるようにしたいと考えています。

したがって、オブジェクトの texture_coords の単一表現が必要です。オブジェクトをレンダリングするとき、画像ソースの向きに悩まされたくありません。(今までtopdown、テクスチャ座標が実際に設定されているときに使用されるテクスチャ ID の横に常にフラグを付けていました。この不器用なハックを取り除きたいです!

基本的に、問題を解決する方法は 3 つあります。

  1. すべての画像データが「正しい」(openGL の用語では上下が逆になっている) 向きであることを確認し、openGL に渡す前にすべての「正しくない」データを変換します。
  2. 画像の向きに応じて異なるテクスチャ座標を提供します (ボトムアップ画像の場合は 0..1、トップダウン画像の場合は 1..0)。
  3. gfx カードの画像を反転する

昔は #1 をやっていましたが、遅すぎることがわかりました。ピクセルバッファのコピーは絶対に避けたいです。

だから私は数年前に#2に切り替えましたが、維持するのが複雑です。画像をgfxカードに転送し、素敵な小さな抽象的な「テクスチャ」オブジェクトを作成したら、元の画像のメタデータを持ち歩く必要がある理由がよくわかりません。私は最終的にコードを VBO に変換する過程にあり、同じサイズの画像を使用しているが向きが異なるという理由だけで、texcoord 配列を更新する必要がないようにしたいと考えています!

それは私がうまくいかなかった#3を残します(しかし、それは非常に単純でなければならないと思います)。直感的に、次のようなものを使用することについて考えglPixelZoom()ました。これはうまく機能しますglDrawPixels()(しかし、実際にそれを使用しているのは誰ですか?)glReadPixels()後者は、メインメモリ内のすべての画像に対して、少なくとも合理的に高速で均一なピクセル方向 (トップダウン) を強制できるため、優れています。

ただし、 は言うまでもなく、経由でglPixelZoom()転送されるデータには影響しないようです。そのため、メイン メモリ ピクセルから生成されたテクスチャはすべて逆さまになります (これは、すべての着信 texcoords をそれらをロードするときはトップダウン)。残りの問題は、これらのトップダウン texcoords で使用できるテクスチャにフレーム バッファをコピーする方法 ( を使用) をまだ見つけていないことです (つまり、 を使用するときに画像を反転する方法) 。glTexImage2DglCopyTex2D()glCopyTex(Sub)ImageglCopyTexImage()

この単純な問題の解決策はありますか? 高速で、保守が容易で、openGL-1.1 から 4.x で実行できるものはありますか?

ああ、理想的には、2 の累乗と 2 の累乗でない (または長方形) テクスチャの両方で機能します。(出来る限り…)

4

2 に答える 2

11

この単純な問題の解決策はありますか? 高速で保守が容易で、openGL-1.1 から 4.x で実行できるものはありますか?

いいえ。

ピクセルのアップロード時にピクセル データの向きを変更する方法はありません。テクスチャの向きをその場で変更する方法はありません。テクスチャの方向を変更する唯一の方法 (ダウンロード、反転、再アップロード以外) は、ソース テクスチャを含むフレームバッファから宛先テクスチャを含むフレームバッファへの逆さまのフレームバッファ ブリットを使用することです。また、glFramebufferBlitGL 2.x をサポートしていない古いハードウェアでは使用できません。

そのため、他の人が行うことを行う必要があります。アップロードする前に、テクスチャを反転します。または、ディスク上のテクスチャを反転してから、反転せずにロードします。

ただし、本当にデータを反転させたくない場合は、すべてのシェーダーに、テクスチャ座標データの Y を反転するかどうかを指示するユニフォームを取得させることができます。反転は、乗算/加算操作以上のものであってはなりません。これを頂点シェーダーで実行して、処理時間を最小限に抑えることができます。

または、固定関数の暗黒時代にコーディングしている場合は、Y を反転するテクスチャ マトリックスを適用できます。

于 2013-06-01T18:22:10.647 に答える