Questo proviene da un vecchio motore di gioco basato su OpenGL che stavo cercando di scrivere circa sette anni fa, scritto in C ++, così nudo con me mentre provo a spiegare come ho gestito il mondo 3D e le operazioni di rendering della GUI 2D al suo interno. Ho usato quattro metodi principali all'interno della mia classe di rendering OpenGL (OGLRender) di cui sono:
- ready3D () per preparare OpenGL per il rendering della scena mondiale 3D.
- ready2D () per preparare OpenGL per il rendering della GUI 2D.
- render3D () per il disegno reale della scena del mondo 3D.
render2D () per l'effettivo disegno della GUI 2D.
void OGLRender::ready3D()
{
glViewport(0, 0, m_Setup.width, m_Setup.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (float) m_Setup.width / m_Setup.height, 0.1, 5000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
}
void OGLRender::ready2D()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f, m_Setup.width, m_Setup.height, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375, 0.375, 0.0);
glDisable(GL_DEPTH_TEST);
}
void OGLRender::render3D()
{
this->ready3D();
// ... draw 3D world scene here ...
}
void OGLRender::render2D()
{
this->ready2D();
// ... draw GUI here ...
}
E poi nel loop del thread principale, chiamerei semplicemente i metodi nel seguente ordine:
while(m_drawFrame)
{
gm_Render->render3D(); // draw 3D scene
gm_Render->render2D(); // draw GUI
SDL_GL_SwapBuffers(); // make drawn frame visible
}
Quindi, quello che sto facendo è disegnare prima la mia scena mondiale 3D e poi disegnare la mia GUI in quel modo la GUI è sempre in cima alla scena mondiale. Il metodo ready3D () prepara la proiezione del mondo 3D per il disegno della scena mondiale e il metodo ready2D () prepara la scena orto 2D per il disegno della GUI. m_Setup.width
e m_Setup.height
sono solo le dimensioni dello schermo della porta di visualizzazione.
La particolarità del metodo ready2D () è che la gluOrtho2D()
funzione viene chiamata con argomenti che lo dicono quando disegniamo le primitive della GUI le disegniamo nelle coordinate dello schermo specificate per abbinare Windows, Mac e altri sistemi di coordinate dello schermo del desktop. Come in alto a sinistra è (0,0) in formato (X, Y) mentre in basso a destra è (ViewportWidth-1, ViewportHeight-1)
. E glTranslatef()
viene utilizzato per correggere il posizionamento accurato per pixel. In modo che quando tracciamo una linea da (0,0) a (0,9), allora la linea verrà effettivamente tracciata dalla parte superiore sinistra e verso il basso di dieci pixel in totale lunghezza e una larghezza di pixel.
Nel complesso, molto probabilmente sei solo interessato a ciò che sta facendo il metodo ready2D () . Ho fornito esempi di codice sorgente degli altri metodi per darti un'idea di come generalmente la maggior parte dei giochi fa la scena del mondo 3D e l'ordine di disegno della GUI.
([0...1], [0...1], 0, 1)
senza proiezione, vista o matrice mondiale, finiranno sempre nello spazio dello schermo.