2009-11-04 6 views
4

Je travaille sur un moteur de jeu depuis un certain temps. J'ai commencé avec 2D Graphics avec SDL seulement, mais j'ai lentement évolué vers les capacités 3D en utilisant OpenGL. La plupart des documents que j'ai vus sur «comment faire avancer les choses» utilisent GLUT, que je n'utilise pas. La question est comment créer une "caméra" dans OpenGL que je pourrais déplacer dans un environnement 3D et afficher correctement des modèles 3D ainsi que des sprites (par exemple, un sprite qui a une position et une rotation fixes). Quelles fonctions devrais-je prendre en compte pour configurer une caméra dans une caméra OpenGL et dans quel ordre doivent-elles être appelées?Configuration d'une caméra en OpenGL

Voici quelques informations sur les raisons pour lesquelles je veux une caméra réelle.

Pour dessiner un sprite simple, je crée une texture GL à partir d'une surface SDL et je la dessine sur l'écran aux coordonnées de (SpriteX-CameraX) et (SpriteY-CameraY). Cela fonctionne bien, mais lorsque vous vous déplacez vers des modèles 3D réels, cela ne fonctionne pas correctement. L'emplacement des caméras est une classe de vecteurs personnalisés (c'est-à-dire n'utilisant pas les bibliothèques standard pour cela) avec des composants entiers X, Y, Z. J'ai un cube en 3D composé de triangles et par lui-même, je peux le dessiner et le faire pivoter et je peux effectivement déplacer le cube (bien que de manière maladroite) en passant à l'emplacement de la caméra quand je dessine le modèle et en utilisant ces composants du vecteur de localisation pour calculer la position des modèles. Les problèmes deviennent évidents avec cette approche quand je vais tourner le modèle cependant. L'origine du modèle n'est pas le modèle lui-même mais semble être l'origine de l'écran. Certains googling me dit que je dois enregistrer l'emplacement du modèle, le faire pivoter autour de l'origine, puis restaurer le modèle à son emplacement d'origine. Au lieu de passer à l'emplacement de ma caméra et de calculer où les choses devraient être dessinées dans le Viewport en calculant de nouveaux sommets, je me suis dit que je créerais un "appareil photo" OpenGL pour le faire pour moi. faire est passer dans les coordonnées de mon objet Camera dans la caméra OpenGL et il traduirait la vue automatiquement. Cette tâche semble être extrêmement facile si vous utilisez GLUT mais je ne suis pas sûr de savoir comment configurer une caméra en utilisant simplement OpenGL.

EDIT # 1 (après quelques commentaires): Suite à une suggestion, voici la méthode de mise à jour qui est appelée dans mon programme. Il a été mis à jour pour créer des perspectives et voir des matrices. Tout le dessin arrive avant que cela ne soit appelé. Et un ensemble similaire de méthodes est exécuté lorsque OpenGL s'exécute (moins l'échange de tampon). Les coordonnées x, y, z sont droites une instance de Camera et son vecteur de localisation. Si la caméra était à (256, 32, 0) alors 256, 32 et 0 seraient passés dans la méthode Update. Actuellement, z est mis à 0 car il n'y a aucun moyen de changer cette valeur pour le moment. Le modèle 3D en cours de dessin est un ensemble de sommets/triangles + normales à l'emplacement X = 320, Y = 240, Z = -128. Lorsque le programme est exécuté, c'est ce qui est dessiné en mode FILL puis en mode LINE et un autre en FILL after movement, lorsque je déplace légèrement la caméra vers la droite. Il aime bien que les normales puissent être la cause, mais je pense qu'il a plus à faire avec moi en manquant quelque chose d'extrêmement important ou en ne comprenant pas complètement ce que font les paramètres NEAR et FAR pour glFrustum. Avant d'implémenter ces changements, j'utilisais glOrtho et le cube était rendu correctement. Maintenant, si je retourne à GlOrtho, une face devient verte et la rotation est assez bizarre, probablement à cause de la traduction. Le cube a 6 couleurs différentes, une pour chaque côté. Rouge, bleu, vert, cyan, blanc et violet.

int VideoWindow::Update(double x, double y, double z) 
{ 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    glFrustum(0.0f, GetWidth(), GetHeight(), 0.0f, 32.0f, 192.0f); 


    glMatrixMode(GL_MODELVIEW); 

    SDL_GL_SwapBuffers(); 
    glLoadIdentity(); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glRotatef(0, 1.0f, 0.0f, 0.0f); 
    glRotatef(0, 0.0f, 1.0f, 0.0f); 
    glRotatef(0, 0.0f, 0.0f, 1.0f); 
    glTranslated(-x, -y, 0); 

    return 0; 
} 

EDIT FINAL: Le problème est avéré être un problème avec les arguments de près et de loin glFrustum et la valeur Z de glTranslated.Bien que les valeurs aient été corrigées, je vais probablement devoir en apprendre davantage sur la relation entre les deux fonctions.

Répondre

4

Vous avez besoin d'une matrice de vue et d'une matrice de projection. Vous pouvez le faire de deux façons:

  1. charge la matrice vous, en utilisant glMatrixMode() et glLoadMatrixf(), après avoir utilisé votre propre bibliothèque pour calculer les matrices.

  2. Utilisez des combinaisons de glMatrixMode(GL_MODELVIEW) et glTranslate()/glRotate() pour créer votre matrice de vue et glMatrixMode(GL_PROJECTION) avec glFrustum() pour créer votre matrice de projection. Rappelez-vous - votre matrice de vue est la traduction négative de la position de votre caméra (Comme c'est le monde par rapport à l'origine de la caméra), ainsi que toutes les rotations appliquées (tangage/lacet).

J'espère que cela aide, si j'avais plus de temps je vous écrirais un exemple approprié!

+0

Merci pour la poussée dans la bonne direction. J'ai fait un montage dans le post si vous pouviez jeter un oeil à mon code et mes captures d'écran. Quelque chose ne va pas tout à fait :) –

+0

En fait le problème est vraiment avec les valeurs que je choisis pour les arguments Near et Far de glFrustum ainsi que la valeur Z passée dans glTranslated. Merci. –

2

Vous devez le faire en utilisant la pile de la matrice comme pour hiérarchie d'objets,

mais la caméra est à l'intérieur de la hiérarchie de sorte que vous devez mettre la transformation inverse sur la pile avant de dessiner les objets que openGL utilise uniquement la matrice de la 3D à la caméra.

1

Si vous n'avez pas vérifié alors peut-être regarder projet suivant expliquerait en détail ce que "tsalter" a écrit dans son message.

Camera du SDK OGL (CodeColony)

Regardez aussi Livre rouge des explications sur l'affichage et comment modèle-vue et de la matrice de projection vous aidera à créer la caméra. Cela commence par une bonne comparaison entre la caméra réelle et ce qui correspond à l'API OpenGL. Chapter 3 - Viewing

Questions connexes