OpenGL est un puissant outil de programmation 3D utilisé pour dessiner des scènes complexes en trois dimensions à partir de primitives simples. Cet article vous apprendra à dessiner un cube simple que vous pourrez tourner en trois dimensions!
Pour ce projet, vous aurez besoin d'un éditeur de code et de connaissances en programmation C.
Première partie de quatre:
Configuration initiale et main ()
1) Installez OpenGL
- Pour commencer, suivez ces étapes pour installer OpenGL sur votre système. Si vous avez déjà OpenGL et un compilateur c installé, vous pouvez ignorer cette étape et passer à la suivante.
2) Créer le document
- Créez un nouveau fichier dans votre éditeur de code préféré et enregistrez-le sous mycube.c
3) #include
- Ce sont les éléments de base dont nous aurons besoin pour notre programme. Il est important de comprendre que les différents systèmes d’exploitation requièrent des composants différents. Assurez-vous d'inclure tous ces éléments pour vous assurer que votre programme est polyvalent et peut être exécuté par n'importe quel utilisateur.
// comprend #comprendre
#comprendre #comprendre #define GL_GLEXT_PROTOTYPES #ifdef __APPLE__ #comprendre #autre #comprendre #fin si
4) Prototypes de fonctions et variables globales
- Notre prochaine étape consiste à déclarer certains prototypes de fonctions.
// Prototypes de fonctions vide afficher(); vide specialKeys(); // Variables globales double tourner_y=0; double rotate_x=0;
- Je vais vous expliquer chacune de ces fonctions et les variables globales en détail lorsque nous les implémenterons plus tard dans ce tutoriel. Pour l'instant, il est important que vous les déclariez.
5) Configuration de la fonction main ()
-
int principale(int argc, carboniser* argv[]) // Initialise GLUT et traite les paramètres utilisateur glutInit(&argc,argv); // Demande une fenêtre de couleur vraie à double tampon avec Z-buffer glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- Cette déclaration met en place notre environnement. Une chose importante à retenir lorsque vous écrivez des programmes OpenGL est que vous devez tout demander. Cela nécessite que vous compreniez mieux le fonctionnement de votre programme et ce que vous devez inclure pour obtenir les fonctionnalités souhaitées. Dans cette ligne, nous allons configurer 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 lié à la manière dont les images sont dessinées à l'écran. Chaque fois que nous redessinons 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 à mesure que l'écran est effacé et redessiné de manière répétée.
Ce problème est résolu en ajoutant un deuxième tampon à dessiner. Avec cette méthode, une image est dessinée sur le premier tampon et ce tampon vous est présenté. Le prochain cadre sera dessiné dans le second tampon et lorsque cela sera fait, les deux tampons changeront de place. Nous verrons immédiatement le deuxième tampon, mais, caché de nous, le premier tampon est effacé et redessiné avec la troisième image qui sera intervertie une fois terminée. - Nous voulons également permettre le Couleur RVB système dans notre fenêtre. J'expliquerai plus en détail comment la couleur est utilisée dans OpenGL lorsque nous travaillons sur la fonction d'affichage.
- Z-buffering c'est comment nous obtenons les effets 3D que nous voulons. OpenGL utilise un système de coordonnées tridimensionnel avec les axes x, y et z. Pour donner l'effet 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. Je vais en parler un peu plus lorsque nous dessinerons nos sommets pour le cube.
6) Création de la fenêtre
- L'étape suivante consiste à créer la fenêtre dans lequel nous allons dessiner le cube. Dans ce tutoriel, j'appelle notre fenêtre "Awesome Cube".
// Créer une fenêtre glutCreateWindow("Awesome Cube");
7) Activer 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 notre programme s'affiche correctement en 3 dimensions en utilisant le Z-buffer que nous avons examiné plus tôt, nous devons activer le test de profondeur. Au fur et à mesure que vous continuez à explorer OpenGL, vous découvrirez de nombreuses fonctionnalités dont vous aurez besoin, notamment l’éclairage, les textures, l’élimination de la réforme et bien plus encore.
// Activer le test de profondeur du tampon Z glEnable(GL_DEPTH_TEST);
8) Fonctions de rappel
- Voici les fonctions de rappel que nous avons écrites pour les prototypes plus tôt. A chaque fois 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(afficher); glutSpecialFunc(specialKeys);
9) Fonctions de rappel
- La dernière étape de notre configuration initiale est de démarrer le MainLoop. Cela rappellera la fonction principale jusqu'à ce que nous fermions le programme pour permettre des animations et une interaction avec l'utilisateur.
// Passer le contrôle à GLUT pour les événements glutmainloop(); // Retour à l'OS revenir 0;
Deuxième partie de quatre:
La fonction display ()
- Tout le travail de dessin de notre cube se fera dans cette fonction. L'idée générale derrière notre cube est de dessiner les six côtés individuellement et de les placer dans la position appropriée.
- D'un point de vue conceptuel, chaque côté va être dessiné en définissant les quatre coins et en laissant OpenGL connecter les lignes et le remplir avec une couleur que nous définissons. Voici les étapes à suivre pour y parvenir.
1) glClear ()
- La première étape à franchir dans cette fonction est de efface la couleur et le tampon Z. Sans ces étapes, les anciens dessins pourraient toujours être visibles sous les nouveaux dessins et les objets dessinés ne seraient pas au bon endroit sur l'écran.
vide afficher() // Effacer l'écran et le Z-buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
2) glBegin () et glEnd ()
- OpenGL définit les objets comme des combinaisons de différents polygones. En utilisant le glBegin () commande, nous posons efficacement un crayon qui va dessiner une forme.Pour soulever le crayon et commencer une nouvelle forme, il faut utiliser le glEnd () commander. Dans ce tutoriel, nous utiliserons 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.
- Nous commencerons ici par le devant de notre cube. Plus tard, nous ajouterons de la couleur aux 6 côtés.
// côté multicolore - AVANT glBegin(GL_POLYGON); // Les sommets seront ajoutés à l'étape suivante glEnd();
3) glVertex3f ()
- Une fois que nous avons déclaré vouloir commencer notre polygone, nous devons définir les sommets de l'objet. glVertex a plusieurs formes en fonction de ce que vous voulez faire avec votre objet.
- Le premier est le nombre de dimensions dans lesquelles vous travaillez. Le 3 ci-dessus dans glVertex3f indique que nous dessinons en 3 dimensions. Il est également possible de travailler en 2 ou 4 dimensions. Le f ci-dessus dans glVertex3f indique que nous travaillons avec des nombres à virgule flottante. Vous pouvez également utiliser des shorts, des entiers ou des doubles.
- Notez que ces points sont définis dans un dans le sens antihoraire manière. Ce n'est pas très important pour le moment, mais lorsque nous commencerons à travailler avec l'éclairage, les textures et les opérations d'abattage, cela deviendra extrêmement important. Prenez alors l'habitude de définir vos points dans le sens inverse des aiguilles d'une montre.
- Maintenant, nous ajoutons les sommets entre les lignes glBegin () et glEnd ().
// côté multicolore - AVANT 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 glEnd();
4) glColor3f ()
- glColor fonctionne de manière similaire à glVertex. Nous pouvons définir des points comme des shorts, des entiers, des doubles ou des flottants. Chaque couleur a une valeur de 0 à 1. Tous les 0 rendent le point noir et tous les 1 rendent le point 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 modifier le niveau alpha, utilisez glColor4f (), le dernier paramètre étant une valeur de 0 à 1 pour opaque à transparent.
- Lorsque nous appelons glColor3f (), chaque sommet dessiné à partir de ce point sera de cette couleur. Par conséquent, si nous voulons que les quatre sommets soient rouges, il suffit de définir la couleur à tout moment avant que les commandes glVertex3f () et tous les sommets ne soient rouges.
- La face avant définie ci-dessous montre comment définir une nouvelle couleur pour chaque sommet. Lorsque nous faisons cela, nous pouvons voir une propriété intéressante des couleurs OpenGL. Puisque chaque sommet du polygone a sa propre couleur, OpenGL mélange automatiquement les couleurs! L'étape suivante montrera comment affecter quatre sommets de la même couleur.
// côté multicolore - AVANT glBegin(GL_POLYGON); glColor3f( 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();
5) Les autres côtés
- Je vous encourage à déterminer l’emplacement de chaque sommet pour les cinq autres côtés du cube, mais pour des raisons de simplicité, je les ai calculées pour vous et les ai incluses dans notre fonction finale display () au dessous de.
// Côté blanc - RETOUR glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // côté violet - DROIT glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // côté vert - GAUCHE glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // Côté bleu - TOP glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // côté rouge - BAS glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); glFlush(); glutSwapBuffers();
- Nous voulons également ajouter deux dernières lignes de code pour cette fonction. Ceux-ci sont glFlush (); et glutSwapBuffers (); ce qui nous donne l'effet de double tampon que nous avons appris plus tôt.
Troisième partie de quatre:
Interactivité avec l'utilisateur
1) specialKeys ()
- Nous avons presque terminé, mais pour le moment, nous pouvons dessiner un cube mais nous ne pouvons pas le faire tourner. Pour ce faire, nous allons créer un specialKeys () fonction pour nous permettre d'appuyer sur les touches fléchées et faire pivoter le cube!
- Cette fonction est la raison pour laquelle nous avons 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 change en conséquence.
vide specialKeys( int clé, int X, int y ) // flèche droite - augmente la rotation de 5 degrés si (clé == GLUT_KEY_RIGHT) tourner_y += 5; // flèche gauche - diminuer la rotation de 5 degrés autre si (clé == GLUT_KEY_LEFT) tourner_y -= 5; autre si (clé == GLUT_KEY_UP) rotate_x += 5; autre si (clé == GLUT_KEY_DOWN) rotate_x -= 5; // Demande de mise à jour d'affichage GlutPostRedisplay();
2) glRotate ()
- Notre dernière déclaration consiste à ajouter l'instruction qui fera pivoter notre objet. Retournez à la afficher() fonction et avant le côté avant, 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( tourner_y, 0.0, 1.0, 0.0 ); // côté multicolore - AVANT…
- Notez d'abord que la syntaxe de glRotatef () est similaire à celle 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 quel axe doit tourner, le premier étant l’axe x, le second étant l’axe y et le troisième étant l’axe z. À l'heure actuelle, il suffit de tourner autour des axes x et y.
- Toutes les transformations que nous écrivons dans notre programme ont besoin de lignes similaires. D'un point de vue conceptuel, nous considérons cela comme une rotation de notre objet autour de l'axe x par la quantité définie par rotate_x, puis une rotation autour de l'axe y par rotate_y. Cependant, OpenGL combine toutes ces instructions dans une transformation de matrice. Chaque fois que nous appelons la fonction d'affichage, nous construisons une matrice de transformation et glLoadIdentity () assure que nous allons commencer avec une nouvelle matrice dans chaque passe.
- Les autres fonctions de transformation que nous pourrions appliquer sont glTranslatef () et glScalef (). Ces fonctions sont similaires à glRotatef () à l'exception de ce qu'elles ne prennent que 3 paramètres, les valeurs x, y et z pour traduire ou mettre à l'échelle l'objet.
- Afin d'obtenir l'effet correct lors de l'application des trois transformations à un objet, nous devons les appliquer dans le bon ordre. Toujours les écrire 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.
- Ajoutez les commandes suivantes pour redimensionner le cube de 2 le long de l'axe x, 2 le long de l'axe y, faites pivoter le cube de 180 degrés autour de l'axe y et traduisez le cube par 0,1 le long de l'axe x. Assurez-vous d’organiser ces commandes ainsi que les précédentes commandes glRotate () dans le bon ordre, comme décrit ci-dessus. (Si vous n'êtes pas sûr, je l'ai fait dans le code final à la fin du tutoriel.)
// autres transformations glTranslatef( 0.1, 0.0, 0.0 ); glRotatef( 180, 0.0, 1.0, 0.0 ); glScalef( 2.0, 2.0, 0.0 );
Compiler
- La toute dernière étape pour terminer votre premier projet OpenGL consiste à: compiler et exécuter votre code. En supposant que vous utilisez gcc comme compilateur, exécutez ces commandes à partir de 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 -cadre SURABONDANCE -cadre OpenGL/ mycube sous Windows: gcc -Mur -fou foo.c -lglut32cu -lglu32 -lopengl32 ./ mycube
Partie quatre de quatre:
Code final
- Voilà. Votre premier programme OpenGL! Je vous ai fourni mon code source ci-dessous comme point de référence.
// // Fichier: mycube.c // Auteur: Matt Daisley // Créé: 25/04/2012 // Projet: Code source pour Créer un cube dans 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 // Right Arrow - Rotate Right // Flèche vers le haut - Rotation vers le haut // Flèche vers le bas - Rotation vers le bas // ---------------------------------------------------------- // comprend // ---------------------------------------------------------- #comprendre
#comprendre #comprendre #define GL_GLEXT_PROTOTYPES #ifdef __APPLE__ #comprendre #autre #comprendre #fin si // ---------------------------------------------------------- // Prototypes de fonctions // ---------------------------------------------------------- vide afficher(); vide specialKeys(); // ---------------------------------------------------------- // Variables globales // ---------------------------------------------------------- double tourner_y=0; double rotate_x=0; // ---------------------------------------------------------- // display () Fonction de rappel // ---------------------------------------------------------- vide afficher() // Effacer l'écran et le Z-buffer 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( tourner_y, 0.0, 1.0, 0.0 ); // Autres transformations // glScalef (2.0, 2.0, 0.0); // Non inclus // côté multicolore - AVANT glBegin(GL_POLYGON); glColor3f( 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 - RETOUR glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // côté violet - DROIT glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // côté vert - GAUCHE glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // Côté bleu - TOP glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); // côté rouge - BAS glBegin(GL_POLYGON); glColor3f( 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 ); glEnd(); glFlush(); glutSwapBuffers(); // ---------------------------------------------------------- // fonction de rappel specialKeys () // ---------------------------------------------------------- vide specialKeys( int clé, int X, int y ) // flèche droite - augmente la rotation de 5 degrés si (clé == GLUT_KEY_RIGHT) tourner_y += 5; // flèche gauche - diminuer la rotation de 5 degrés autre si (clé == GLUT_KEY_LEFT) tourner_y -= 5; autre si (clé == GLUT_KEY_UP) rotate_x += 5; autre si (clé == GLUT_KEY_DOWN) rotate_x -= 5; // Demande de mise à jour d'affichage GlutPostRedisplay(); // ---------------------------------------------------------- // fonction principale // ---------------------------------------------------------- int principale(int argc, carboniser* argv[]) // Initialise GLUT et traite les paramètres utilisateur glutInit(&argc,argv); // Demande une fenêtre de couleur vraie à double tampon avec Z-buffer 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(afficher); glutSpecialFunc(specialKeys); // Passer le contrôle à GLUT pour les événements glutmainloop(); // Retour à l'OS revenir 0;
Facebook
Twitter
Google+