systeme solaire 3D

Voilà un grand classique lorsque l’on se lance dans la programmation openGl. Pourquoi ? Car simuler le mouvement des planètes dans le système solaire ne nécessite que l’utilisation des fonctions de base de changement de repère openGL, c'est-à-dire : glRotate() et glTranslate(). Je vais donc expliquer dans cet article comment manipuler ces 2 fonctions afin d’obtenir un système solaire !

Je tiens tous de suite à préciser que le but de cet article n’est pas d’expliquer le fonctionnement des transformations de repère en openGL, il y a pour cela le tutoriel de Kayl: Transformation openGL. Et pour les débutants, il y a ce tutoriel plutôt facile d’accès: cours d'introduction à openGL.

Stack technique

openGL + SDL en C++ sous codeBlock

Etape 1 : Des planètes et un Soleil

De manière simplifiée, notre système solaire se compose de boules qui tournent autour d’une boule centrale : le soleil ! Il faut donc, pour chaque planète, enregistrer toutes les informations relatives à son mouvement et à sa forme.

Damien Leroux Solar System explication1

C'est-à-dire :

  • La vitesse de rotation sur elle-même
  • La vitesse de rotation autour du Soleil
  • La distance qui la sépare du Soleil
  • Le rayon de la planète
  • L’inclinaison équatoriale de la planète par rapport au Soleil
  • L’inclinaison orbitale de la planète par rapport au Soleil

On utilise donc le rayon de la planète pour créer une sphère de la bonne taille (avec glutSolidSphere() ou gluSphere()) au centre de l’espace openGL. On déplace avec glTranslatef()  notre sphère, sur un axe choisi ( x par exemple), de la distance qui la sépare du Soleil normalement (attention de prendre en compte le rayon du Soleil) . L’opération est à répéter autant de fois que l’on a de planètes.

Il est important de se souvenir qu’en openGL, toutes les  modifications de la matrice MODELVIEW avec glTranslatef(), etc.….  sont exécutées dans l’ordre inverse de lecture du programme : c'est-à-dire du bas vers le haut. Avant d’avoir fini l’ensemble des déplacements qui ont affectés la planète, il faut utiliser glPushMatrix() qui permet de sauvegarder l’état de notre matrice MODELVIEW. Puis, après avoir créer la planète, il faut utiliser glPopMatrix() afin de restaurer l’état de la matrice MODELVIEW. Ce procédé est à garder en tête afin d’appliquer seulement aux éléments que l’on a choisi, les déplacements correspondants. Sans cela, n’importe quelle rotation ou déplacement affectera tous les éléments créés par la suite.

Damien Leroux Solar System explication2

Une fois que toute les planètes sont affichées, on affiche une dernière boule au centre de l’espace openGL afin d’obtenir notre joli Soleil. Pour ce qui est du dessin de satellite (comme la Lune), il est nécessaire d’afficher d’abord le satellite, de le déplacer puis de dessiner la planète. En ne faisant pas de glPopMatrix() après l’affichage du satellite, il est possible de déplacer l’ensemble ( planète + satellite). Le principe est exactement le même pour l’anneau qui se trouve autour de saturne. Vous trouverez sur le site de Jerome Jouvie les différents quadriques que l’on peut dessiner en openGL

Etape 2 : les planètes tournent, et tournent

Damien Leroux Solar System explication 5

Afin de faire tourner une planète sur elle-même, on ajoute entre glPushMatrix() et glPopMatrix(), mais après le glTranslatef(), un glRotatef() pour faire tourner de X degrés celle-ci.Pour déplacer notre planète (la faire tourner autour du Soleil), on ajoute entre glPushMatrix() et glPopMatrix(), mais après le glTranslatef(),un glRotatef() pour déplacer de Y degrés celle-ci.Ces angles X et Y s’incrémentent en fonction de la vitesse de rotation que l’on a choisie pour la planète.Deux rotations permettent de faire varier l’inclinaison d’une planète par rapport au soleil.

Etape 3 : les textures

Damien Leroux Solar System explication3

Afin de pouvoir appliquer sur chaque planète comme au Soleil une texture, il faut avoir utiliser gluSphere() plutôt que glutSolidSphere() pour créer vos planètes. En effet, l’utilisation de glutSolidSphere() ne permet pas de fixer la texture voulue sur la planète ce qui a pour effet d’afficher la texture correctement sur la planète mais de l’orienter toujours dans le même sens, même si on tourne de 180 degrés la planète. Pour choisir la texture que l’on applique sur une planète, on utilise glBindTexture(). Afin de charger une texture, je me suis aidé du tutoriel de Kayl: les textures OpenGL. Pour ce qui est de trouver la texture correspondante à chaque planète, j’ai navigué sur le net pour dénicher ce qui me plaisait le plus. Pour certaines textures trouvées, j’ai utilisé Photoshop afin d’en améliorer la qualité.

Etape 4 : les lumières

Damien Leroux Solar System explication4

Rien de plus simple à mettre en place : il faut d’abord activer le mode lumière avec :    glEnable(GL_LIGHTING) et glEnable(GL_LIGHT1) puis orienter la lumière dans le sens que l’on souhaite avec glLightiv(). Si vous souhaitez plus d’informations : le tutoriel sur les lumières OpenGL permet d’avoir une bonne approche du fonctionnement de la lumière sous openGL.

Voici comment doit se présenter votre fonction qui gère l’affichage d’une planète :

void affiche_planete(.){
    //activation des textures
    glEnable(GL_TEXTURE_2D);

    //activation de la lumière
    glEnable(GL_LIGHTING); 

    //sauvegarde de l’état de la matrice MODELVIEW
    glPushMatrix();

    //rotation sur l’inclinaison orbital de la planete
    glRotatef(inclinaison_orbital,1,0,0);

    //rotation de la planete autour du soleil

    glRotatef(angle_rotation_planete_soleil,0,1,0);

    //deplacement de la planete sur un axe

    glTranslatef(-distance_planete_soleil,0,0);

    //activation de la lumière 1

    glEnable(GL_LIGHT1);

    //application de la lumière venant d’un direction en particulier

    glLightiv(GL_LIGHT1,GL_POSITION,lumiere_position1);

    //application de la texture sur la planete

    glBindTexture(GL_TEXTURE_2D,text_planete);

    //inclinaison de la planete par rapport au soleil

    glRotatef(inclinaison_planete_soleil,0,0,1);

    //rotation de la planète sur elle-même

    glRotatef(angle_rotation_planete_planete,0,1,0);

    //dessin d’un planete

    gluSphere(params,rayon_planete,QUALITE_RENDU,QUALITE_RENDU);

    glDisable(GL_LIGHT1);

    glPopMatrix();
    //désactivation de la lumière
    glDisable(GL_LIGHTING);
    //désactivation des textures
    glDisable(GL_TEXTURE_2D);
}

Etape 5 : trackball

Afin de pouvoir facilement juger de la qualité du système solaire que l’on vient de créer, on utilise un trackball (comme dans google Earth). Pour mettre en place un trackball, le tutoriel de  Kayl sur les caméras OpenGL est très bien expliqué.

J’ai modifié légèrement l’algorithme fourni afin de le faire cadrer avec mon repère et pouvoir faire autant de rotations verticales que l’on souhaite.

Etape 6 : skybox

Damien Leroux Solar System explication 6

Pour pouvoir représenter l’espace autour du système solaire, j’ai opté pour une skybox : un moyen simple et efficace d’avoir un fond sous openGL. Pour cette skybox, j’ai suivi le tutoriel sur les skybox/ réalisé par Cyril: très bien expliqué!

J’ai remodelé quelque peu l’algorithme (le code en l’occurrence) qui était fourni, notamment afin de le mettre en adéquation avec la position de ma caméra qui évolue grâce au trackball.

Je l’ai aussi modifié afin de remplacer la prise en charge de bitmap, par la prise en charge de jpeg (bien plus léger ^^). J’ai créé moi-même les images qui représentent l’espace (les tutoriels pour cela ne manquent pas sur internet).

Etape 7 : les finitions

Damien Leroux Solar System explication 7

Afficher le nom d’une planète : pour ce faire, j’affiche un quad sur lequel je plaque une texture avec le nom de la planète. J’affiche ensuite ce quad à coté de la planète en suivant le même chemin que celui utilisé pour placer la planète. J’ai fais en sorte de pouvoir récupérer les angles avec lesquels ma caméra est inclinée afin de pouvoir orienter le nom des planètes dans le sens de la caméra, quelle que soit sa position.

Damien Leroux Solar System 2

Afficher les orbites des planètes : Je dessine simplement un cercle. Ce cercle est composé de lignes qui font un tour complet : de 0 à 360 degrés. En fonction de cela ; la position de ces lignes est calculée avec le cosinus et le sinus (comme dans un cercle trigonométrique). Cela donne:

glBegin(GL_LINE_LOOP);
for(float k=0;k<(M_PI*2);k+=M_PI/180){
x=sin(k)*rayon;
z=cos(k)*rayon;
glVertex3f(x,0,z);
}
glEnd();

Obtenir dans notre système un aspect elliptique plutôt que circulaire : Cela est assez simple. Il suffit de multiplier x ou y par la valeur de son choix.

Résultat final

Damien Leroux Solar System rendu1

Damien Leroux Solar System rendu2

Damien Leroux Solar System rendu3

Damien Leroux Solar System rendu4