2010-11-26 30 views
5

Je travaille sur un projet qui nécessite de créer une interface 2D rendue "sur top" ou un monde 3D. Sur certains autres forums, j'ai lu que vous pouviez utiliser "GluOrtho2D()" pour le travail, et revenir à GluPerspective() une fois que vous avez terminé. La seule chose est, mon code de test que j'ai écrit pour elle affiche seulement le monde 3D, pas le quad 2D. Lorsque je désactive le code de rendu 3D, cependant, le quad apparaît là où il était supposé être. J'ai réduit le code aux instructions openGL, que j'ai écrites ci-dessous. Le code est écrit en Python en utilisant la bibliothèque Pyglet.Problème avec la création d'une interface 2D dans un monde 3D openGL


Le code d'initialisation de la scène:

glViewport(0, 0, width, height) 
glMatrixMode(GL_PROJECTION) 
glLoadIdentity() 
gluPerspective(60.0, float(width)/height, .1, 10000.) 
glMatrixMode(GL_MODELVIEW) 
glClearDepth(1.0) 
glShadeModel(GL_FLAT) 
glEnable(GL_DEPTH_TEST) 
glDepthFunc(GL_LEQUAL) 
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) 

Le cadre du code de rendu. L'appel à builder.buildMap() crée la scène 3D, et la paire glBegin-glEnd dessine un quad 2D:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) 
stage.set3DMode(window.width, window.height) 
builder.buildMap() 
stage.set2DMode(window.width, window.height) 
glBegin (GL_QUADS) 
glVertex2i(0, 0) 
glVertex2i(0, 200) 
glVertex2i(200, 200) 
glVertex2i(200, 0) 
glEnd() 

la fonction stage.set3DMode:

glDisable(GL_DEPTH_TEST) 
glMatrixMode(GL_PROJECTION) 
glLoadIdentity() 
gluOrtho2D(0, width, 0, height) 
glMatrixMode(GL_MODELVIEW) 

et la fonction stage.set3DMode :

glEnable(GL_DEPTH_TEST) 
glMatrixMode(GL_PROJECTION) 
glLoadIdentity() 
gluPerspective(60.0, float(width)/float(height), .1, 10000.) 
glMatrixMode(GL_MODELVIEW) 

J'espère vraiment que quelqu'un peut signaler mon erreur! Et je vous remercie de me aider :)

Répondre

3

On dirait que vous n'appelez glLoadIdentity() après le passage à GL_MODELVIEW. Le moyen le plus simple de se rappeler est de l'appeler chaque fois que vous changez la matrice de projection, passez à GL_MODELVIEW et appelez le glLoadIdentity() (sauf si vous voulez vraiment conserver l'ancienne).

+0

Parfait! Cela l'a réparé. Merci beaucoup! – Bartvbl

1

J'utilise les matrices suivantes pour le rendu 2d:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0, w, h, 0, 0, 1); 
glViewport(0, 0, w, h); 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glTranslatef(0.375f, 0.375f, 0); 
2

Beaucoup de gens se trompent sur l'utilisation de glViewport et autres. Ils le placent toujours dans le rappel de remodelage qui est tout simplement faux.

Vous avez toujours la configuration complète dans votre fonction de rendu, juste avant d'avoir besoin de ces paramètres. Votre code doit donc être (pesudocode):

render_scene(): 
    // first clear the whole window 
    glViewport(0, 0, window.width, window.height) 
    glClearDepth(1.0) 
    glClearColor(1., 1., 1., 1.); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) 

    glViewport(3Dstuff.x, 3Dstuff.y, 3Dstuff.w, 3Dstuff.h) 
    // maybe also set scissor to clip 
    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    gluPerspective(60.0, float(width)/height, .1, 10000.) 
    glMatrixMode(GL_MODELVIEW) 
    setup3DstuffModelview() 
    glDepthFunc(...) 
    glEnable(GL_DEPTH_TEST) 
    // other state stuff 
    render3Dstuff() 

    // now the 2D stuff 
    glViewport(2Dstuff.x, 2Dstuff.y, 2Dstuff.w, 2Dstuff.h) 
    // clear depth and stencil -- if you need parts of the 3D depth/stencil 
    // for some algorithm retain it or save and restore by FBO renderbuffers or 
    // glReadPixels, glDrawPixels 
    glClearDepth(1.0) 
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) 

    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    glOrtho(...) 
    glMatrixMode(GL_MODELVIEW) 
    glLoadIdentity() 
    setup2DstuffModelview() 
    glDepthFunc(...) 
    glDisable(GL_DEPTH_TEST) 
    // other state stuff 
    render2Dstuff() 

    // repeat for all the layers you need 

Ceci est très important: OpenGL est une machine d'état. À moins que vous ne puissiez prouver qu'aucun changement d'état indéterminé ne se produit, vous devez toujours rétablir/définir tous les états dont vous avez besoin avant de rendre une certaine géométrie.