Ich stoße auf ein Problem, das versucht, das OpenGL-Verhalten in einer Umgebung ohne OpenGL zu replizieren.Doppeltes orthographisches OpenGL-Projektionsverhalten ohne OpenGL
Grundsätzlich muss ich eine SVG-Datei aus einer Liste von Zeilen erstellen, die mein Programm erstellt. Diese Linien werden mit einer othigrafischen Projektion erstellt.
Ich bin sicher, dass diese Zeilen korrekt berechnet werden, denn wenn ich versuche, sie mit einem OpenGL-Kontext mit orthographischer Projektion zu verwenden und das Ergebnis in ein Bild zu speichern, ist das Bild korrekt.
Das Problem entsteht, wenn ich genau die gleichen Zeilen ohne OpenGL verwende.
ich die OpenGL Projektion und Ansicht Matrizen repliziert haben und ich verarbeiten jede Zeile Punkt wie folgt aus:
3D_output_point = projection_matrix * view_matrix * 3D_input_point
und dann berechne ich es Bildschirm (SVG-Datei) Position wie folgt aus:
2D_point_x = (windowWidth/2) * 3D_point_x + (windowWidth/2)
2D_point_y = (windowHeight/2) * 3D_point_y + (windowHeight/2)
I berechnen die othographic Projektionsmatrix wie folgt aus:
float range = 700.0f;
float l, t, r, b, n, f;
l = -range;
r = range;
b = -range;
t = range;
n = -6000;
f = 8000;
matProj.SetValore(0, 0, 2.0f/(r - l));
matProj.SetValore(0, 1, 0.0f);
matProj.SetValore(0, 2, 0.0f);
matProj.SetValore(0, 3, 0.0f);
matProj.SetValore(1, 0, 0.0f);
matProj.SetValore(1, 1, 2.0f/(t - b));
matProj.SetValore(1, 2, 0.0f);
matProj.SetValore(1, 3, 0.0f);
matProj.SetValore(2, 0, 0.0f);
matProj.SetValore(2, 1, 0.0f);
matProj.SetValore(2, 2, (-1.0f)/(f - n));
matProj.SetValore(2, 3, 0.0f);
matProj.SetValore(3, 0, -(r + l)/(r - l));
matProj.SetValore(3, 1, -(t + b)/(t - b));
matProj.SetValore(3, 2, -n/(f - n));
matProj.SetValore(3, 3, 1.0f);
und die vie w-Matrix auf diese Weise:
CVettore position, lookAt, up;
position.AssegnaCoordinate(rtRay->m_pCam->Vp.x, rtRay->m_pCam->Vp.y, rtRay->m_pCam->Vp.z);
lookAt.AssegnaCoordinate(rtRay->m_pCam->Lp.x, rtRay->m_pCam->Lp.y, rtRay->m_pCam->Lp.z);
up.AssegnaCoordinate(rtRay->m_pCam->Up.x, rtRay->m_pCam->Up.y, rtRay->m_pCam->Up.z);
up[0] = -up[0];
up[1] = -up[1];
up[2] = -up[2];
CVettore zAxis, xAxis, yAxis;
float length, result1, result2, result3;
// zAxis = normal(lookAt - position)
zAxis[0] = lookAt[0] - position[0];
zAxis[1] = lookAt[1] - position[1];
zAxis[2] = lookAt[2] - position[2];
length = sqrt((zAxis[0] * zAxis[0]) + (zAxis[1] * zAxis[1]) + (zAxis[2] * zAxis[2]));
zAxis[0] = zAxis[0]/length;
zAxis[1] = zAxis[1]/length;
zAxis[2] = zAxis[2]/length;
// xAxis = normal(cross(up, zAxis))
xAxis[0] = (up[1] * zAxis[2]) - (up[2] * zAxis[1]);
xAxis[1] = (up[2] * zAxis[0]) - (up[0] * zAxis[2]);
xAxis[2] = (up[0] * zAxis[1]) - (up[1] * zAxis[0]);
length = sqrt((xAxis[0] * xAxis[0]) + (xAxis[1] * xAxis[1]) + (xAxis[2] * xAxis[2]));
xAxis[0] = xAxis[0]/length;
xAxis[1] = xAxis[1]/length;
xAxis[2] = xAxis[2]/length;
// yAxis = cross(zAxis, xAxis)
yAxis[0] = (zAxis[1] * xAxis[2]) - (zAxis[2] * xAxis[1]);
yAxis[1] = (zAxis[2] * xAxis[0]) - (zAxis[0] * xAxis[2]);
yAxis[2] = (zAxis[0] * xAxis[1]) - (zAxis[1] * xAxis[0]);
// -dot(xAxis, position)
result1 = ((xAxis[0] * position[0]) + (xAxis[1] * position[1]) + (xAxis[2] * position[2])) * -1.0f;
// -dot(yaxis, eye)
result2 = ((yAxis[0] * position[0]) + (yAxis[1] * position[1]) + (yAxis[2] * position[2])) * -1.0f;
// -dot(zaxis, eye)
result3 = ((zAxis[0] * position[0]) + (zAxis[1] * position[1]) + (zAxis[2] * position[2])) * -1.0f;
// Set the computed values in the view matrix.
matView.SetValore(0, 0, xAxis[0]);
matView.SetValore(0, 1, yAxis[0]);
matView.SetValore(0, 2, zAxis[0]);
matView.SetValore(0, 3, 0.0f);
matView.SetValore(1, 0, xAxis[1]);
matView.SetValore(1, 1, yAxis[1]);
matView.SetValore(1, 2, zAxis[1]);
matView.SetValore(1, 3, 0.0f);
matView.SetValore(2, 0, xAxis[2]);
matView.SetValore(2, 1, yAxis[2]);
matView.SetValore(2, 2, zAxis[2]);
matView.SetValore(2, 3, 0.0f);
matView.SetValore(3, 0, result1);
matView.SetValore(3, 1, result2);
matView.SetValore(3, 2, result3);
matView.SetValore(3, 3, 1.0f);
Die Ergebnisse, die ich von OpenGL und von der SVG-Ausgabe erhalten sind ganz anders, aber in zwei Tagen konnte ich nicht mit einer Lösung kommen.
Dies ist die OpenGL-Ausgabe
Und das ist meine SVG-Ausgabe
Wie Sie sehen, es ist eine Drehung nicht corrent ist.
Irgendeine Idee warum? Die Linienpunkte sind die gleichen und hoffentlich auch die Matrizen.
Die Erstellung der Matrizen, die ich erstellt habe, hat nicht funktioniert. Ich meine, die Matrizen waren falsch, denke ich, weil OpenGL nichts gezeigt hat. Also habe ich versucht, das Gegenteil zu tun, ich habe die Matrizen in OpenGL erstellt und sie mit meinem Code verwendet. Das Ergebnis ist besser, aber noch nicht perfekt.
Jetzt denke ich, dass ich etwas falsch mache, die 3D-Punkte in 2D-Bildschirmpunkte zu kartieren, weil die Punkte, die ich bekomme, in Y invertiert sind und ich immer noch einige Linien nicht perfekt übereinstimmend habe.
Dies ist, was ich die OpenGL-Matrizen und meine bisherigen Ansatz mit 3D-Punkte auf 2D-Platz auf dem Bildschirm abzubilden (dies ist die SVG, OpenGL nicht machen):
Ok das der Inhalt der Ansicht Matrix I aus OpenGL erhalten:
die Projektionsmatrix Dies ist I erhalten von OpenGL:
Und das ist das Ergebnis, das ich mit diesen Matrizen bekommen und meine 2D-Punkt durch Ändern Y Koordinatenberechnung wie bofjas sagte:
Es ist wie einige Umdrehungen sieht fehlen. Meine Kamera hat sowohl auf der X- als auch auf der Y-Achse eine Drehung von 30 °, und es sieht so aus, als wären sie nicht korrekt berechnet.
Jetzt verwende ich die gleichen Matrizen OpenGL tut. Also denke ich, dass ich einige falsche Berechnungen mache, wenn ich den 3D-Punkt in 2D-Bildschirmkoordinaten abbilde.
Nur zur Info: Ihre Methode fehlt die homogene Teilung nach der Projektion Transformation. Es ist für eine orthographische Projektion nicht wichtig, aber wichtig für eine perspektivische Projektion. Was die schlechte Rotation in deinem SVG-Fall anbelangt, muss ich das noch untersuchen. – datenwolf
BTW: Was passiert, wenn Sie die erstellten Matrizen in OpenGL laden und versuchen, das Bild mit diesen zu rendern? 'glMatrixMode (...); glLoadMatrix (...) 'falls Sie die feste Funktionspipeline verwenden. – datenwolf
und BTW könnten Sie den Inhalt der Matrizen drucken. – joojaa