3

(この質問で、私はこの他の質問を解決するために持っていたアイデアを調査しようとしています)

メモリ内に幅高さの標準的な 2D 配列がある場合、それを長さwidth * heightの 1D 配列に変換し、 index = x + y * widthでインデックスを付けることができます。このマッピングは、配列のメモリを割り当てて解放するときに非常に役立ちます。メモリ マネージャーは、構造体を 2D でパックすることを気にする必要はなく、1D で表現されている場合、割り当てられたすべての配列の全体の長さだけを気にする必要があるためです。

OpenGL テクスチャのイメージ メモリ管理にこの同じアプローチを使用できるかどうかを確認しようとしています。(上記のリンクされた質問で説明されているように) アイデアは、必要なテクスチャ全体を大きなテクスチャにビンパッキング(つまり、互いに並べて描画) することにより、1 つの大きなテクスチャに結合することです。これにより、レンダリング中のコストのかかるテクスチャ バインディング操作を最小限に抑えることができます。

私の大きなテクスチャが 8×8 ピクセル (合計 64 ピクセル) だとしましょう:

8x8 texture:                5x5 image:            4x5 image:

   | 0 1 2 3 4 5 6 7           | 0 1 2 3 4           | 0 1 2 3
---+-----------------       ---+-----------       ---+---------
 0 | . . . . . . . .         0 | A B C D E         0 | a b c d
 1 | . . . . . . . .         1 | F G H I J         1 | e f g h
 2 | . . . . . . . .         2 | K L M N O         2 | i j k l
 3 | . . . . . . . .         3 | P Q R S T         3 | m n o p
 4 | . . . . . . . .         4 | U V W X Y         4 | q r s t
 5 | . . . . . . . .
 6 | . . . . . . . .
 7 | . . . . . . . .

そして、5×5の画像と4×5の画像を保存したいと思います(つまり、合計25 + 20 = 45ピクセル)。技術的には、利用可能なピクセルはたくさんありますが、これらの画像を大きなテクスチャに並べて配置することはできません。これには、一方向に 9 個、他方向に 5 個の最小寸法が必要になるためです。

単純に 8×8 テクスチャを 64 連続ピクセルのメモリとして扱い、その中の 1D ブロックのメモリに 2 つの画像をマッピングできれば、次のように画像をテクスチャ内に配置できます: 8x8 テクスチャ:

   | 0 1 2 3 4 5 6 7
---+-----------------
 0 | A B C D E F G H
 1 | I J K L M N O P             
 2 | Q R S T U V W X
 3 | Y a b c d e f g             
 4 | h i j k l m n o             
 5 | p q r s t . . .
 6 | . . . . . . . .
 7 | . . . . . . . .

すべての画像を 1:1 の縮尺で描画する場合、つまり、分数ピクセル座標がどこにもなく、線形フィルタリングやその他のピクセル ブレンディングも必要ない場合、4 を描画するために使用できる変換マトリックスを考え出すことは可能ですか? ×5 このテクスチャを使った画像?

頂点シェーダーとフラグメント シェーダーを使用すると、これはかなり簡単なように見えます (何かを忘れていない限り、試したことはありません)。

  • 頂点シェーダーは、画像の 4 つのコーナーをマッピングして、64×1 の画像として表現されるテクスチャに描画します。

    • a: (0, 0) → (0 + 0*4 + 25, 0) = (25, 0) ここで、25 は 4×5 画像のオフセットです。
    • d: (3, 0) → (3 + 0*4 + 25, 0) = (28, 0)
    • q: (0, 4) → (0 + 4*4 + 25, 0) = (41, 0)
    • t: (3, 4) → (3 + 4*4 + 25, 0) = (44, 0)

    テクスチャ内の他の座標の補間は( ?) 整数座標のこの線に沿って右オフセットにもマップする必要があります。

  • フラグメント シェーダーは、この 64×1 座標を最終的な 8×8 座標に変換します。
    • a: (0, 25) → (25 % 8, 25 / 8) = (1, 3)
    • d: (0, 28) → (28 % 8, 28 / 8) = (4, 3)
    • k: (0, 35) → (35 % 8, 35 / 8) = (3, 4)
    • q: (0, 41) → (41 % 8, 41 / 8) = (1, 5)
    • t: (0, 44) → (44 % 8, 44 / 8) = (4, 5)

残念ながら、カスタム シェーダーには OpenGL ES v2.0 以降が必要ですが、これはすべてのデバイスで利用できるわけではありません。

OpenGL ES 1.1 が提供する行列変換だけでこのマッピングを達成することは何とか可能ですか?

4

1 に答える 1