Ich suche einen Einblick in ein kleines Problem mit Einheitenübersetzungen in einem Raster.
Update und gelöst
Ich habe mein eigenes Problem gelöst. Siehe unten für Details. Alles in diesem Teil des Beitrags stellte sich als richtig heraus. Wenn überhaupt, kann es als Miniatur-Tutorial / Beispiel / Hilfe für die nächste Person dienen.
Installieren
- FBO, VAO, VBO
- 512x448 Fenster
- 64x64 Raster
gl_Position = projection * world * position;
projection
definiert durchortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);
Dies ist eine orthogonale Projektionsfunktion des Lehrbuchs.world
wird durch eine feste Kameraposition bei (0, 0) definiertposition
wird durch die Position des Sprites definiert.
Problem
In der Abbildung unten (1: 1-Skalierung) beträgt der Rasterabstand 64 x 64, und ich zeichne die Einheit mit (64, 64). Die Einheit zeichnet jedoch ungefähr ~ 10 Pixel in der falschen Position. Ich habe versucht, einheitliche Fensterabmessungen zu erzielen, um Verzerrungen der Pixelgröße zu vermeiden, aber jetzt bin ich ein bisschen verloren, wenn ich eine 1: 1-Projektion von Pixel-zu-Welt-Einheiten bereitstelle. Wie auch immer, hier sind einige kurze Bilder, die das Problem lösen sollen.
Ich habe mich entschlossen, ein paar Sprites mit 64-fachen Offsets auszustatten.
Als dies unangebracht schien, ging ich umher und machte den Basisfall von 1 Einheit. Welches schien wie erwartet in einer Reihe zu stehen. Das Gelb zeigt einen Unterschied von 1px in der Bewegung.
Was ich möchte
Wenn Sie sich im Idealfall in eine beliebige Richtung bewegen, werden mit 64 Einheiten die folgenden (überlagerten Einheiten) ausgegeben:
Eckpunkte
Es scheint, dass die Scheitelpunkte, die in den Scheitelpunkt-Shader gehen, korrekt sind. In Bezug auf das erste Bild sehen die Daten im VBO beispielsweise folgendermaßen aus:
x y x y
----------------------------
tl | 0.0 24.0 64.0 24.0
bl | 0.0 0.0 -> 64.0 0.0
tr | 16.0 0.0 80.0 0.0
br | 16.0 24.0 80.0 24.0
Der Vollständigkeit halber ist hier die tatsächliche Anordnung, die den obigen Bewegungen entspricht:
x y z w r g b a s t
-------------------------------------------------------------
tl | 0.0 23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.62650603
bl | 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.76506025
tr | 16.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.2263158 0.76506025
br | 16.0 23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.2263158 0.62650603
-------------------------------------------------------------
-------------------------------------------------------------
tl | 64.0 24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.21084337
bl | 64.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.3554217
tr | 80.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.3554217
br | 80.0 24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.21084337
// side bar: I know that I have unnecessary data with having a z-axis.
// The engine flips between perspective and orthogonal and I
// haven't selectively started pruning data.
Projektionsmatrix
Die Projektionsmatrix für das 512x448-Fenster sieht folgendermaßen aus:
0.00390625 0.0 0.0 0.0
0.0 0.004464286 0.0 0.0
0.0 0.0 -1.0 0.0
0.0 0.0 0.0 1.0
und ist mit einer orthogonalen Projektionsfunktion aufgebaut:
ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);
// explicitly: ortho(-512/2.0f, 512/2.0f, -448/2.0f, 448.0f
ortho(float left, float right, float bottom, float top)
{
projection.setIdentity();
projection.m00 = 2.0f / (right - left);
projection.m11 = 2.0f / (top - bottom);
projection.m22 = -1;
projection.m30 = -(right + left) / (right - left);
projection.m31 = -(top + bottom) / (top - bottom);
projection.m32 = 0;
}
Weltbild-Matrix
Die Position der Kamera ist nur eine Translationsmatrix, die ich in diesem Fall nur um -w / 2 und -h / 2 versetzt habe, um null in Bezug auf die Mitte zu sein.
1.0 0.0 0.0 -256.0
0.0 1.0 0.0 -224.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
Lösungen, die ich versucht habe
player.moveRight()
würde sich mit dem in die Gleichung einbezogenen Seitenverhältnis um eine Einheit bewegen. Also:gridWidth = 64 / 1.14f
. Die Bewegung passte nicht in das Raster.Erzwang ein 512x512 Fenster mit einer passenden orthogonalen Projektion.
Versuchte verschiedene magische Zahlen und versuchte, Korrelationen zwischen den beiden zu ziehen.
Trotzdem muss ich nur glauben, dass ich meine eigentliche Projektion vermassele. Daher suche ich nach Erkenntnissen zur Beibehaltung der 1: 1-Projektion von Pixel zu Welt.