Cela provient d'un ancien moteur de jeu basé sur OpenGL que j'essayais d'écrire il y a environ sept ans écrit en C ++ si nu avec moi alors que j'essaie d'expliquer comment je gérais le monde 3D et les opérations de rendu GUI 2D en son sein. J'ai utilisé quatre méthodes principales dans ma classe de rendu OpenGL (OGLRender), dont:
- ready3D () pour préparer OpenGL au rendu de la scène mondiale 3D.
- ready2D () pour préparer OpenGL au rendu de l'interface graphique 2D.
- render3D () pour le dessin de la scène mondiale 3D réelle.
render2D () pour le dessin GUI 2D réel.
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 ...
}
Et puis dans la boucle de thread principale, j'appellerais simplement les méthodes dans l'ordre suivant:
while(m_drawFrame)
{
gm_Render->render3D(); // draw 3D scene
gm_Render->render2D(); // draw GUI
SDL_GL_SwapBuffers(); // make drawn frame visible
}
Donc, ce que je fais, c'est que je dessine d'abord ma scène mondiale 3D, puis je dessine mon interface graphique en dernier de cette façon, l'interface graphique est toujours au sommet de la scène mondiale. La méthode ready3D () prépare la projection du monde 3D pour le dessin de la scène mondiale et la méthode ready2D () prépare la scène ortho 2D pour le dessin de l'interface graphique. m_Setup.width
et ne m_Setup.height
sont que les dimensions de l'écran du port de vue.
La particularité de la méthode ready2D () est que la gluOrtho2D()
fonction est appelée avec des arguments qui lui indiquent que lorsque nous dessinons les primitives GUI, nous les dessinons dans les coordonnées d'écran spécifiées pour correspondre à Windows, Mac et autres systèmes de coordonnées d'écran de bureau. Tels que le coin supérieur gauche est (0,0) au format (X, Y) tandis que le coin inférieur droit l'est (ViewportWidth-1, ViewportHeight-1)
. Et glTranslatef()
est utilisé pour corriger le positionnement précis par pixel. De sorte que lorsque nous dessinons une ligne de (0,0) à (0,9), la ligne sera en fait dessinée en haut à gauche et en bas de dix pixels de longueur et d'une largeur de pixel.
Dans l'ensemble, vous êtes probablement intéressé par ce que fait la méthode ready2D () . J'ai fourni les exemples de code source des autres méthodes pour vous donner une idée de la façon dont la plupart des jeux font la scène mondiale 3D et l'ordre de dessin de l'interface graphique.
([0...1], [0...1], 0, 1)
avec AUCUNE projection, vue ou matrice mondiale, elles atterriront toujours dans l'espace de l'écran.