Comment faire un cube dans OpenGL (avec des images)

Table des matières:

Comment faire un cube dans OpenGL (avec des images)
Comment faire un cube dans OpenGL (avec des images)

Vidéo: Comment faire un cube dans OpenGL (avec des images)

Vidéo: Comment faire un cube dans OpenGL (avec des images)
Vidéo: Comment installer Windows XP sur VirtualBox 2024, Avril
Anonim

OpenGL est un puissant outil de programmation 3D utilisé pour dessiner des scènes tridimensionnelles complexes à partir de primitives simples. Cet article va vous apprendre à dessiner un cube simple que vous pouvez faire tourner pour le visualiser en trois dimensions !

Pour ce projet, vous aurez besoin d'un éditeur de code et de connaissances en programmation C.

Pas

Partie 1 sur 3: Configuration initiale

1994315 1 1
1994315 1 1

Étape 1. Installer OpenGL Pour commencer, suivez ces étapes pour installer OpenGL sur votre système

Si vous avez déjà installé OpenGL, ainsi qu'un compilateur C compatible, vous pouvez ignorer cette étape et passer à la suivante.

1994315 2 1
1994315 2 1

Étape 2. Créez le document

Créez un nouveau fichier dans votre éditeur de code préféré et enregistrez-le sous mycube.c

1994315 3 1
1994315 3 1

Étape 3. Ajoutez #includes

Ce sont les éléments de base dont vous aurez besoin pour votre programme. Il est important de réaliser qu'il existe en fait différentes inclusions requises pour les différents systèmes d'exploitation. Assurez-vous d'inclure tous ces éléments pour vous assurer que votre programme est polyvalent et peut s'exécuter pour n'importe quel utilisateur.

    // Comprend #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif

1994315 4 1
1994315 4 1

Étape 4. Ajoutez des prototypes de fonction et des variables globales

Votre prochaine étape consiste à déclarer des prototypes de fonctions.

    // Fonction Prototypes void display(); void specialKeys(); // Variables globales double rotate_y=0; double rotation_x=0;

1994315 5 1
1994315 5 1

Étape 5. Configurez la fonction main()

    int main(int argc, char* argv){ // Initialise GLUT et traite les paramètres utilisateur glutInit(&argc, argv); // Demande une fenêtre de couleurs vraies à double tampon avec le tampon Z glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

  • Cette instruction configure votre environnement. Une chose importante à retenir lors de l'écriture de programmes OpenGL est que vous devez tout demander. Cela nécessite que vous ayez une meilleure compréhension du fonctionnement de votre programme et de ce que vous devez inclure pour obtenir les fonctionnalités que vous souhaitez. Dans cette ligne, vous configurerez l'affichage avec un double tampon, une couleur RVB et un tampon Z.
  • Double mise en mémoire tampon est une technique utilisée dans les programmes graphiques pour éliminer un problème qui survient en raison de la façon dont les images sont dessinées à l'écran. Chaque fois que vous redessinez la scène, l'affichage doit d'abord être effacé puis les nouvelles informations seront dessinées. Sans double mise en mémoire tampon, vous observerez un effet de scintillement lorsque l'écran est effacé et redessiné à plusieurs reprises.
  • Ce problème est résolu en ajoutant un deuxième tampon vers lequel dessiner. Avec cette méthode, une image est dessinée dans le premier tampon et ce tampon vous est montré. L'image suivante sera dessinée dans le deuxième tampon et lorsque cela sera fait, les deux tampons changeront de place. Vous verrez immédiatement le deuxième tampon, mais, caché de nous, le premier tampon est effacé et redessiné avec la troisième image qui sera échangée une fois terminée.
  • Vous souhaitez également activer le Couleur RVB système dans votre fenêtre.
  • Tampon Z c'est ainsi que vous obtenez les effets 3D que vous voulez. OpenGL utilise un système de coordonnées tridimensionnel avec les axes x, y et z. Pour donner l'impression qu'un objet est plus proche de vous, sa position sur l'axe z est augmentée, cependant, pour le faire apparaître plus loin, sa position sur l'axe z est diminuée.
1994315 6 1
1994315 6 1

Étape 6. Créez la fenêtre

La prochaine étape consiste à créer la fenêtre dans lequel vous dessinerez le cube. Dans ce tutoriel, la fenêtre s'appelle "Awesome Cube".

    // Créer une fenêtre glutCreateWindow("Super Cube");

1994315 7 1
1994315 7 1

Étape 7. Activez le test de profondeur

OpenGL est un langage strict dans la mesure où il ne suppose pas que des fonctionnalités spéciales sont activées. Pour que votre programme s'affiche correctement en 3 dimensions à l'aide du tampon Z que vous avez consulté précédemment, vous devez activer le test de profondeur. Au fur et à mesure que vous continuez à explorer OpenGL, vous découvrirez de nombreuses fonctionnalités que vous devrez activer, notamment l'éclairage, les textures, l'abattage et bien plus encore.

    // Activer le test de profondeur du tampon Z glEnable(GL_DEPTH_TEST);

1994315 8 1
1994315 8 1

Étape 8. Ajoutez des fonctions de rappel

Voici les fonctions de rappel pour lesquelles vous avez écrit les prototypes plus tôt. A chaque passage dans la boucle principale, ces fonctions seront appelées. La fonction d'affichage redessine la scène en fonction des modifications apportées aux variables depuis l'appel précédent. La fonction specialKeys nous permet d'interagir avec le programme.

    // Fonctions de rappel glutDisplayFunc(display); glutSpecialFunc(specialKeys);

1994315 9 1
1994315 9 1

Étape 9. Démarrez la boucle principale

Cela rappellera la fonction principale jusqu'à ce que vous fermiez le programme pour permettre les animations et l'interaction de l'utilisateur.

    // Passer le contrôle à GLUT pour les événements glutMainLoop(); // Retour au système d'exploitation return 0; }

Partie 2 sur 3: La fonction display()

1994315 10 1
1994315 10 1

Étape 1. Comprenez le but de cette fonction

Tout le travail de dessin de votre cube se fera dans cette fonction. L'idée générale derrière votre cube est de dessiner les six côtés individuellement et de les placer dans la position appropriée.

Conceptuellement, chaque côté va être dessiné en définissant les quatre coins et en laissant OpenGL connecter les lignes et les remplir avec une couleur que vous définissez. Vous trouverez ci-dessous les étapes pour le faire

1994315 11 1
1994315 11 1

Étape 2. Ajoutez glClear()

La première étape que vous devez faire dans cette fonction est de effacer la couleur et le tampon Z. Sans ces étapes, les anciens dessins peuvent toujours être visibles sous les nouveaux dessins et les objets dessinés ne seraient pas au bon emplacement sur l'écran.

    void display(){ // Effacer l'écran et le tampon Z glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

1994315 12 1
1994315 12 1

Étape 3. Ajoutez glBegin() et glEnd()

OpenGL définit les objets comme des combinaisons de différents polygones. En utilisant le glDébut() commande, vous posez effectivement un crayon qui dessinera une forme. Pour lever le crayon et commencer une nouvelle forme, vous devez utiliser le glFin() commander. Dans ce didacticiel, vous utiliserez GL_POLYGON pour dessiner chaque côté du cube, mais il est possible d'utiliser d'autres options de paramètres telles que GL_LINE, GL_QUAD ou GL_TRIANGLE pour créer d'autres formes.

  • Ici, vous commencerez par le devant de votre cube. Plus tard, vous ajouterez de la couleur sur les 6 côtés.
  • // Côté multicolore - FRONT glBegin(GL_POLYGON); // Les sommets seront ajoutés à l'étape suivante glEnd();

1994315 13 1
1994315 13 1

Étape 4. Ajoutez glVertex3f()

Une fois que vous avez déclaré que vous voulez commencer votre polygone, vous devez définir les sommets de l'objet. glVertex a plusieurs formes selon ce que vous voulez faire avec votre objet.

  • Le premier est le nombre de dimensions dans lesquelles vous travaillez. Les 3 ci-dessus dans glVertex3f indiquent que vous dessinez en 3 dimensions. Il est également possible de travailler en 2 ou 4 dimensions. Le f ci-dessus dans glVertex3f indique que vous travaillez avec des nombres à virgule flottante. Vous pouvez également utiliser des courts, des entiers ou des doubles.
  • Notez que ces points sont définis dans un dans le sens inverse des aiguilles d'une montre manière. Ce n'est pas très important pour le moment, mais lorsque vous commencerez à travailler avec l'éclairage, les textures et l'abattage, cela deviendra incroyablement important, alors prenez l'habitude de définir vos points dans le sens inverse des aiguilles d'une montre maintenant.
  • Add ajoute les sommets entre les lignes glBegin() et glEnd().
  • // Côté multicolore - FRONT glBegin(GL_POLYGON); glVertex3f(-0,5, -0,5, -0,5); // P1 glVertex3f(-0,5, 0,5, -0,5); // P2 glVertex3f(0,5, 0,5, -0,5); // P3 glVertex3f(0,5, -0,5, -0,5); // P4 glFin();

1994315 14 1
1994315 14 1

Étape 5. Ajoutez glColor3f()

glColor fonctionne de la même manière que glVertex. Vous pouvez définir des points en tant que courts, entiers, doubles ou flottants. Chaque couleur a une valeur de 0 à 1. Tous les 0 rendent le point noir et tous les 1 le rendront blanc. Le 3 dans glColor3f() fait référence au système de couleurs RVB sans canal alpha. L'alpha d'une couleur définit sa transparence. Pour changer le niveau alpha, utilisez glColor4f() avec le dernier paramètre étant une valeur de 0 à 1 pour opaque à transparent.

  • Lorsque vous appelez glColor3f(), chaque sommet dessiné à partir de ce point sera de cette couleur. Par conséquent, si vous voulez que les quatre sommets soient rouges, définissez simplement la couleur une fois avant les commandes glVertex3f() et tous les sommets seront rouges.
  • La face avant définie ci-dessous montre comment définir une nouvelle couleur pour chaque sommet. Lorsque vous faites cela, vous pouvez voir une propriété intéressante des couleurs OpenGL. Puisque chaque sommet du polygone a sa propre couleur, OpenGL mélangera automatiquement les couleurs ! L'étape suivante montrera comment affecter quatre sommets avec la même couleur.
  • //Côté multicolore - FRONT glBegin(GL_POLYGON); glCouleur3f(1,0, 0,0, 0,0); glVertex3f(0,5, -0,5, -0,5); // P1 est rouge glColor3f(0.0, 1.0, 0.0); glVertex3f(0,5, 0,5, -0,5); // P2 est vert glColor3f(0.0, 0.0, 1.0); glVertex3f(-0,5, 0,5, -0,5); // P3 est bleu glColor3f(1.0, 0.0, 1.0); glVertex3f(-0,5, -0,5, -0,5); // P4 est violet glEnd();

1994315 15 1
1994315 15 1

Étape 6. Manipulez les autres côtés

Déterminez l'emplacement de chaque sommet pour les cinq autres côtés du cube, mais pour des raisons de simplicité, ceux-ci ont été calculés pour vous et sont inclus dans le fonction display() finale au dessous de.

    // Côté blanc - BACK glBegin(GL_POLYGON); glCouleur3f(1.0, 1.0, 1.0); glVertex3f(0,5, -0,5, 0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); glFin(); // Côté violet - DROITE glBegin(GL_POLYGON); glCouleur3f(1.0, 0.0, 1.0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, -0,5, 0,5); glFin(); // Côté vert - GAUCHE glBegin(GL_POLYGON); glCouleur3f(0.0, 1.0, 0.0); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, -0,5, -0,5); glFin(); // Côté bleu - TOP glBegin(GL_POLYGON); glCouleur3f(0.0, 0.0, 1.0); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, 0,5); glFin(); // Côté rouge - BOTTOM glBegin(GL_POLYGON); glCouleur3f(1,0, 0,0, 0,0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, -0,5); glFin(); glRincer(); glutSwapBuffers(); }

  • Nous souhaitons également ajouter deux dernières lignes de code pour cette fonction. Ceux-ci sont glRincer();

    et glutSwapBuffers();

    ce qui nous donne l'effet de double tampon dont vous avez entendu parler plus tôt.

Partie 3 sur 3: Interactivité utilisateur

1994315 16 1
1994315 16 1

Étape 1. Ajoutez specialKeys()

Vous avez presque terminé mais pour le moment, vous pouvez dessiner un cube mais n'avez aucun moyen de le faire pivoter. Pour ce faire, vous allez créer un specialKeys() fonction pour nous permettre d'appuyer sur les touches fléchées et de faire pivoter le cube !

  • Cette fonction est la raison pour laquelle vous avez déclaré les variables globales rotate_x et rotate_y. Lorsque vous appuyez sur les touches fléchées droite et gauche, rotate_y sera incrémenté ou décrémenté de 5 degrés. De même, lorsque vous appuyez sur les touches fléchées haut et bas, rotate_x changera en conséquence.
  • void specialKeys(int key, int x, int y) { // Flèche droite - augmente la rotation de 5 degrés si (touche == GLUT_KEY_RIGHT) rotate_y += 5; // Flèche gauche - diminue la rotation de 5 degrés else if (key == GLUT_KEY_LEFT) rotate_y -= 5; sinon si (clé == GLUT_KEY_UP) rotate_x += 5; sinon si (clé == GLUT_KEY_DOWN) rotate_x -= 5; // Demande de mise à jour de l'affichage glutPostRedisplay(); }

1994315 17 1
1994315 17 1

Étape 2. Ajoutez glRotate()

Votre dernière déclaration consiste à ajouter la déclaration qui fera pivoter votre objet. Revenez à la fonction display() et avant le côté FRONT, ajoutez ces lignes:

    // Réinitialiser les transformations glLoadIdentity(); // Rotation lorsque l'utilisateur modifie rotate_x et rotate_y glRotatef(rotate_x, 1.0, 0.0, 0.0); glRotatef(rotation_y, 0.0, 1.0, 0.0); // Face multicolore - FRONT ….

  • Remarquons d'abord que la syntaxe de glRotatef() est similaire à celui de glColor3f() et glVertex3f() mais nécessite toujours 4 paramètres. Le premier paramètre est le degré de rotation à appliquer. Les trois paramètres suivants définissent l'axe autour duquel tourner, le premier étant l'axe x, le deuxième étant l'axe y et le troisième étant l'axe z. Pour le moment, vous n'avez qu'à effectuer une rotation autour des axes x et y.
  • Toutes les transformations que vous écrivez dans votre programme ont besoin de lignes similaires à celles-ci. Conceptuellement, vous pouvez considérer cela comme une rotation de votre objet autour de l'axe x de la quantité définie par rotate_x, puis une rotation autour de l'axe y par rotate_y. Cependant, OpenGL combine toutes ces instructions en une seule transformation matricielle. Chaque fois que vous appelez la fonction d'affichage, vous construisez une matrice de transformation et glLoadIdentity() garantit que vous commencerez avec une nouvelle matrice à chaque passage.
  • Les autres fonctions de transformation que vous pouvez appliquer sont glTranslatef() et glScalef(). Ces fonctions sont similaires à glRotatef() à l'exception du fait qu'elles ne prennent que 3 paramètres, les montants x, y et z pour traduire ou mettre à l'échelle l'objet.
  • Afin d'obtenir le bon effet lors de l'application des trois transformations à un seul objet, vous devez les appliquer dans le bon ordre. Écrivez-les toujours dans l'ordre glTranslate, glRotate, puis glScale. OpenGL applique essentiellement les transformations de manière ascendante. Pour comprendre cela, essayez d'imaginer à quoi ressemblerait un simple cube 1x1x1 avec les transformations si OpenGL les appliquait de haut en bas et si OpenGL les appliquait de bas en haut.
1994315 18 1
1994315 18 1

Étape 3. Ajoutez les commandes suivantes pour mettre le cube à l'échelle de 2 le long de l'axe des x, 2 le long de l'axe des y, faire pivoter le cube de 180 degrés autour de l'axe des y et translater le cube de 0,1 le long de l'axe des x

Assurez-vous de les organiser ainsi que les commandes glRotate() précédentes dans le bon ordre, comme décrit ci-dessus. (Si vous n'êtes pas sûr, cela est fait dans le code final à la fin du didacticiel.)

    // Autres transformations glTranslatef(0.1, 0.0, 0.0); glRotatef(180, 0,0, 1,0, 0,0); glScalef(2.0, 2.0, 0.0);

1994315 19 1
1994315 19 1

Étape 4. Compilez et exécutez votre code

En supposant que vous utilisiez gcc comme compilateur, exécutez ces commandes depuis votre terminal pour compiler et tester votre programme.

    Sous Linux: gcc cube.c -o cube -lglut -lGL./ mycube Sur Mac: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Sous Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube

1994315 20 1
1994315 20 1

Étape 5. Vérifiez votre code complet

Ça devrait être comme ça:

    // // Fichier: mycube.c // Auteur: Matt Daisley // Création: 2012-04-25 // Projet: Code source pour Make a Cube en OpenGL // Description: Crée une fenêtre OpenGL et dessine un cube 3D / / Que l'utilisateur peut faire pivoter à l'aide des touches fléchées // // Contrôles: Flèche gauche - Rotation gauche // Flèche droite - Rotation droite // Flèche haut - Rotation haut // Flèche bas - Rotation bas // ------ -------------------------------------------------- -- // Comprend // --------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- -------------------------------------------- // Prototypes de fonctions / / ------------------------------------------------- --------- affichage vide(); void specialKeys(); // ------------------------------------------------ ---------- // Variables globales // ---------------------------------- ------------------------ double rotation_y=0; double rotation_x=0; // ------------------------------------------------ ---------- // display() Fonction de rappel // ------------------------------- --------------------------- void display(){ // Effacer l'écran et le tampon Z glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Réinitialiser les transformations glLoadIdentity(); // Autres transformations // glTranslatef(0.1, 0.0, 0.0); // Non inclus // glRotatef(180, 0.0, 1.0, 0.0); // Non inclus // Rotation lorsque l'utilisateur modifie rotate_x et rotate_y glRotatef(rotate_x, 1.0, 0.0, 0.0); glRotatef(rotation_y, 0.0, 1.0, 0.0); // Autres transformations // glScalef(2.0, 2.0, 0.0); // Non inclus //Côté multicolore - FRONT glBegin(GL_POLYGON); glCouleur3f(1,0, 0,0, 0,0); glVertex3f(0,5, -0,5, -0,5); // P1 est rouge glColor3f(0.0, 1.0, 0.0); glVertex3f(0,5, 0,5, -0,5); // P2 est vert glColor3f(0.0, 0.0, 1.0); glVertex3f(-0,5, 0,5, -0,5); // P3 est bleu glColor3f(1.0, 0.0, 1.0); glVertex3f(-0,5, -0,5, -0,5); // P4 est violet glEnd(); // Côté blanc - BACK glBegin(GL_POLYGON); glCouleur3f(1.0, 1.0, 1.0); glVertex3f(0,5, -0,5, 0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); glFin(); // Côté violet - DROIT glBegin(GL_POLYGON); glCouleur3f(1.0, 0.0, 1.0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, -0,5, 0,5); glFin(); // Côté vert - GAUCHE glBegin(GL_POLYGON); glCouleur3f(0.0, 1.0, 0.0); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, -0,5, -0,5); glFin(); // Côté bleu - TOP glBegin(GL_POLYGON); glCouleur3f(0.0, 0.0, 1.0); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, 0,5); glFin(); // Côté rouge - BOTTOM glBegin(GL_POLYGON); glCouleur3f(1,0, 0,0, 0,0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, -0,5); glFin(); glRincer(); glutSwapBuffers(); } // ------------------------------------------------ ----------- // SpecialKeys() Fonction de rappel // ------------------------------ ---------------------------- void specialKeys(int key, int x, int y) { // Flèche droite - augmente la rotation de 5 degré si (clé == GLUT_KEY_RIGHT) rotate_y += 5; // Flèche gauche - diminue la rotation de 5 degrés else if (key == GLUT_KEY_LEFT) rotate_y -= 5; sinon si (clé == GLUT_KEY_UP) rotate_x += 5; sinon si (clé == GLUT_KEY_DOWN) rotate_x -= 5; // Demande de mise à jour de l'affichage glutPostRedisplay(); } // ----------------------------------------------- ----------- // fonction principale // ------------------------------- --------------------------- int main(int argc, char* argv){ // Initialise GLUT et traite les paramètres utilisateur glutInit(&argc, argv); // Demande une fenêtre de couleurs vraies à double tampon avec le tampon Z glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Créer une fenêtre glutCreateWindow("Awesome Cube"); // Activer le test de profondeur du tampon Z glEnable(GL_DEPTH_TEST); // Fonctions de rappel glutDisplayFunc(display); glutSpecialFunc(specialKeys); // Passer le contrôle à GLUT pour les événements glutMainLoop(); // Retour au système d'exploitation return 0; }

Conseillé: