Sto riscontrando un problema nel tentativo di replicare il comportamento OpenGL in un ambiente senza OpenGL.Comportamento ortografico di proiezione OpenGL duplicato senza OpenGL
Fondamentalmente ho bisogno di creare un file SVG da un elenco di linee che il mio programma crea. Queste linee sono create usando una proiezione othigraphic.
Sono sicuro che queste righe sono calcolate correttamente perché se provo ad usarle con un contesto OpenGL con proiezione ortografica e salvare il risultato in un'immagine, l'immagine è corretta.
Il problema si presenta quando utilizzo le stesse identiche linee senza OpenGL.
ho replicato la proiezione e visualizzare matrici OpenGL e io processo ogni punto della linea in questo modo:
3D_output_point = projection_matrix * view_matrix * 3D_input_point
e poi ho calcolato che è schermo (file in formato SVG) posizione come questa:
2D_point_x = (windowWidth/2) * 3D_point_x + (windowWidth/2)
2D_point_y = (windowHeight/2) * 3D_point_y + (windowHeight/2)
a calcolare la matrice othographic proiezione simili:
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);
e vie w matrice in questo modo:
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);
I risultati che si ottengono da OpenGL e dall'uscita SVG sono molto diverse, ma in due giorni non potrebbe trovare una soluzione.
Questa è l'uscita OpenGL
E questa è la mia uscita SVG
Come si può vedere, è la rotazione non è corrent.
Qualche idea del perché? I punti della linea sono uguali e anche le matrici, si spera.
Incollare le matrici che stavo creando non ha funzionato. Voglio dire, le matrici erano sbagliate, penso, perché OpenGL non mostrava nulla. Così ho provato a fare il contrario, ho creato le matrici in OpenGL e le ho usate con il mio codice. Il risultato è migliore, ma non ancora perfetto.
Ora penso che faccio qualcosa di sbagliato mappando i punti 3D in punti schermo 2D perché i punti che ottengo sono invertiti in Y e ho ancora alcune linee che non corrispondono perfettamente.
Questo è ciò che ottengo utilizzando le matrici di OpenGL e il mio approccio precedente per mappare i punti 3D a 2D spazio dello schermo (questo è il formato SVG, non OpenGL rendering):
Ok questo è il contenuto della matrice vista ottengo da OpenGL:
Questa è la matrice di proiezione I ottenere da OpenGL:
E questo è il risultato che ottengo con quelle matrici e cambiando il mio punto 2D coordinata Y di calcolo come bofjas detto:
Sembra che alcune rotazioni mancano La mia videocamera ha una rotazione di 30 ° su entrambi gli assi X e Y, e sembra che non siano stati calcolati correttamente.
Ora sto usando le stesse matrici di OpenGL. Quindi penso che sto facendo dei calcoli errati quando mappo il punto 3D in coordinate dello schermo 2D.
Solo FYI: il metodo non ha la divisione omogenea dopo la trasformazione di proiezione. Non ha importanza per una proiezione ortografica, ma è vitale per una proiezione prospettica. Per quanto riguarda la rotazione malata nel tuo caso SVG, dovrò esaminarlo ancora. – datenwolf
BTW: Cosa succede se carichi le matrici che hai creato in OpenGL e provi a renderizzare l'immagine usando quelle? 'GlMatrixMode (...); glLoadMatrix (...) 'nel caso si stia utilizzando la pipeline di funzioni fisse. – datenwolf
e btw potresti stampare il contenuto delle matrici. – joojaa