Mapping einer Textur von "1D" nach "2D" mit OpenGL-Matrixtransformationen

(Mit dieser Frage versuche ich, eine Idee zu untersuchen, die ich zur Lösung von @ hattdieses andere)

Wenn ich ein Standard-2D-Array von Dimensionen habeBreit undHöh im Speicher kann ich das in ein 1D-Array der Länge verwandelnBreit * Höh und dann über @ indizierInde = x + y * Breit. Diese Zuordnung ist beim Zuweisen und Freigeben von Speicher für das Array äußerst hilfreich, da sich der Speichermanager nicht um das Packen der Strukturen in 2D kümmern muss, sondern nur um die Gesamtlänge jedes zugewiesenen Arrays, wenn dies in 1D ausgedrückt wird.

Ich versuche herauszufinden, ob ich diesen Ansatz auch für die Verwaltung des Bildspeichers für OpenGL-Texturen verwenden kann. Die Idee (wie in der oben verlinkten Frage beschrieben) besteht darin, eine ganze Reihe benötigter Texturen durch @ zu einer einzigen größeren zu kombiniere bin-packing ihnen (d. h. sie nebeneinander zeichnen) in die große Textur. Dies hilft, kostspielige Texturbindevorgänge während des Renderns zu minimieren.

Angenommen, meine große Textur hat eine Größe von 8 × 8 Pixel (d. H. 64 Pixel insgesamt):

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 | . . . . . . . .

Und ich möchte ein 5 × 5-Bild und ein 4 × 5-Bild darin speichern (d. H. 25 + 20 = 45 Pixel insgesamt). Technisch gesehen habe ich viele Pixel zur Verfügung, aber ich kann diese Bilder nicht nebeneinander in der großen Textur platzieren, da dies eine Mindestabmessung von 9 in eine Richtung und 5 in die andere Richtung erfordern würde.

Wenn ich meine 8 × 8-Textur einfach so behandeln könnte, dass 64 Pixel des Speichers fortgesetzt werden und die beiden Bilder in 1D-Speicherblöcken darin abgebildet werden, könnte ich die Bilder innerhalb der Textur wie folgt anordnen: 8 x 8-Textur:

   | 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 | . . . . . . . .

Wenn ich alle meine Bilder im Maßstab 1: 1 zeichne, dh keine gebrochenen Pixelkoordinaten und keine Notwendigkeit für eine lineare Filterung oder andere Pixelüberblendung, ist es möglich, eine Transformationsmatrix zu erstellen, mit der ich die zeichnen kann 4 × 5 Bild mit dieser Textur?

Mit Vertex- und Fragment-Shadern scheint dies ziemlich einfach zu sein (es sei denn, ich vergesse etwas; ich habe es nicht ausprobiert):

Der Vertex-Shader ordnet die vier Ecken des Bildes der Textur zu, die als 64 × 1-Bild dargestellt wird:

a: (0, 0) → (0 + 0 * 4 + 25, 0) = (25, 0) wobei 25 der Versatz des 4 × 5-Bildes istd: (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)

ie Interpolation anderer Koordinaten innerhalb der Textsollt (?) wird dann für ganzzahlige Koordinaten @ auch auf den rechten Versatz entlang dieser Linie abgebild

Der Fragment-Shader wandelt diese 64 × 1-Koordinate in die endgültige 8 × 8-Koordinate um, indem er einfach den Quotienten und den Rest einer Division durch 8 nimmt, 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)

Unglücklicherweise erfordern benutzerdefinierte Shader OpenGL ES v2.0 oder höher, was nicht auf allen Geräten verfügbar ist.

Ist es irgendwie möglich, diese Zuordnung nur über die von OpenGL ES 1.1 angebotenen Matrixtransformationen zu erreichen?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage