{
Dans cette leçon, je vais vous apprendre à utiliser trois méthodes différentes de filtrage de texture.
Apprenez à utiliser le clavier pour déplacer des objets dans la scène et apprenez également à appliquer un éclairage simple dans une scène OpenGL.
Cette leçon contient beaucoup de contenu. Si vous avez des questions sur les leçons précédentes, revenez en arrière et révisez-les d'abord.
Avant d'entrer dans le code qui se cache derrière, il est important d'avoir une bonne compréhension des bases.
Nous modifions toujours le code de la première leçon.
La différence par rapport à avant est que chaque fois qu'il y a un changement important, j'écris l'intégralité du code.
Nous devons d’abord ajouter l’unité SysUtils et l’unité Glaux.
}
Utilisations
SysUtils,
ouvert,
les fenêtres,
Messages,
Glaux Dans '../../GLAUX/Glaux.pas';
//Les lignes suivantes ajoutent de nouvelles variables.
//Nous ajoutons trois variables booléennes.
// La variable light indique si la lumière est allumée.
//Les variables lp et fp sont utilisées pour stocker si les touches 'L' et 'F' sont enfoncées.
//J'expliquerai l'importance de ces variables plus tard. Pour l’instant, mettons cela de côté.
light : Booléen ; // source lumineuse activée/désactivée
lp : Boolean; // La touche L est-elle enfoncée ?
fp : Boolean; // La touche F est-elle enfoncée ?
//Définissez maintenant 5 variables pour contrôler la taille du pas de l'angle de rotation autour de l'axe x et de l'axe y,
//Et la vitesse de rotation autour des axes x et y.
//De plus, une variable z est créée pour contrôler la distance dans la profondeur de l'écran.
xrot : GLfloat; // Rotation X
yrot : GLfloat; // rotation Y
xspeed : GLfloat; // Vitesse de rotation X
yspeed : GLfloat; // Vitesse de rotation Y
z : GLfloat = -5.0 f; // Distance en profondeur dans l'écran
//Définissez ensuite le tableau utilisé pour créer la source de lumière.
//Nous utiliserons deux lumières différentes.
//La première est appelée lumière ambiante. La lumière ambiante vient de toutes les directions.
//Tous les objets de la scène sont éclairés par la lumière ambiante.
//Le deuxième type de source lumineuse est appelé lumière diffuse.
//La lumière diffuse est générée par une source de lumière spécifique et crée des reflets sur les surfaces des objets de votre scène.
//Toute surface d'objet directement éclairée par une lumière diffuse devient très lumineuse,
//Les zones à peine éclairées apparaissent plus sombres.
//Cela produira un très bon effet d'ombre sur les bords de la caisse en bois que nous avons créée.
//Le processus de création d'une source de lumière est exactement le même que celui de création d'une couleur.
//Les trois premiers paramètres sont les composants RVB tricolores et le dernier est le paramètre du canal alpha.
//Par conséquent, dans le code suivant, nous obtenons une lumière ambiante blanche semi-lumineuse (0,5f).
//S'il n'y a pas de lumière ambiante, les zones non touchées par la lumière diffuse deviendront très sombres.
LightAmbient : Array[0..3] Of GLfloat = (0.5, 0.5, 0.5, 1.0 //Paramètres de lumière ambiante (nouveau) ;
//La ligne de code suivante nous générons la lumière diffuse la plus brillante.
//Toutes les valeurs des paramètres sont prises à la valeur maximale de 1.0f.
//Il brillera sur le devant de notre caisse en bois et aura fière allure.
LightDiffuse : Array[0..3] Of GLfloat = (1.0, 1.0, 1.0, 1.0) // Paramètres de lumière diffuse (nouveau) ;
//Enfin, nous sauvegardons la position de la source lumineuse.
//Les trois premiers paramètres sont les mêmes que dans glTranslate.
//Les déplacements sur l'axe XYZ sont respectivement.
//Puisque nous voulons que la lumière brille directement sur le devant de la boîte en bois, les déplacements sur l'axe XY sont tous deux de 0,0.
//La troisième valeur est le déplacement sur l'axe Z.
//Afin de garantir que la lumière soit toujours devant la caisse en bois,
//Nous éloignons donc la source de lumière de l'écran vers l'observateur (qui est vous.).
//Nous appelons généralement la position de l'écran, c'est-à-dire la vitre de l'écran du moniteur, le point 0,0 de l'axe Z.
//Le déplacement sur l'axe Z est donc finalement fixé à 2,0.
//Si vous pouvez voir la source de lumière, elle flotte devant votre moniteur.
//Bien sûr, vous ne pouvez pas voir la boîte en bois si elle n'est pas derrière la vitre de l'écran du moniteur.
//『Note du traducteur : j’apprécie la patience de NeHe.
//Pour être honnête, parfois je suis ennuyé. Pourquoi dit-il autant de bêtises sur une chose aussi simple ?
//Mais si tout était clair, feuilleteriez-vous encore des pages comme celle-ci sans fin ? 』
//Le dernier paramètre est pris comme 1.0f.
//Cela indiquera à OpenGL que les coordonnées spécifiées ici sont les positions des sources lumineuses que j'expliquerai davantage dans les prochains tutoriels.
LightPosition : Array[0..3] Of GLfloat = (0.0, 0.0, 2.0, 1.0) // Position de la source lumineuse (nouveau) ;
//La variable de filtre garde une trace du type de texture utilisé lors de l'affichage.
//La première texture (texture 0) est construite à l'aide de la méthode de filtrage gl_nearest (non lisse).
//La deuxième texture (texture 1) utilise la méthode gl_linear (filtrage linéaire),
//L'image plus proche de l'écran semble plus lisse.
//La troisième texture (texture 2) utilise la méthode de filtrage mipmapped,
// Cela créera une très belle texture.
//Selon notre type d'utilisation, la valeur de la variable filtre est égale à 0, 1 ou 2 respectivement.
//Commençons par la première texture.
//texture alloue un espace de stockage pour trois textures différentes.
//Ils sont situés respectivement dans texture[0], texture[1] et texture[2].
filtre : GLuint; // Type de filtre
texture : Array[0..2] Of Gluint; // Espace de stockage pour 3 textures
PRocédure glGenTextures(n : GLsizei ; Var textures : GLuint stdcall );
opengl32;
Procédure glBindTexture(cible : GLenum ; texture : GLuint externe) ;
opengl32;
Fonction gluBuild2DMipmaps(cible : GLenum ; composants, largeur, hauteur : GLint ;
format, type : GLenum ; données : Pointeur : Entier ; nom glu32 externe ;
'gluBuild2DMipmaps';
{
Chargez maintenant un bitmap et utilisez-le pour créer trois textures différentes.
Cette leçon utilise la bibliothèque auxiliaire Glaux pour charger des bitmaps.
Vous devez donc confirmer si la bibliothèque Glaux est incluse lors de la compilation.
Je sais que Delphi et VC++ incluent la bibliothèque glaux, mais il n'est pas garanti que d'autres langages l'aient.
"Note du traducteur : glaux est une bibliothèque auxiliaire OpenGL. Selon les caractéristiques multiplateformes d'OpenGL,
Le code doit être commun sur toutes les plateformes. Mais la bibliothèque auxiliaire n'est pas la bibliothèque standard officielle d'OpenGL.
Non disponible sur toutes les plateformes. Mais il se trouve qu'il est disponible sur la plateforme Win32.
Haha, bien sûr, BCB ne pose pas non plus de problème. 』Ici, j'annote uniquement le code nouvellement ajouté.
Si vous avez des questions sur une certaine ligne de code, veuillez consulter le didacticiel 6.
Cette leçon explique le chargement et la création de textures de manière très détaillée.
Après le morceau de code précédent et avant glResizeWnd(),
Nous avons ajouté le code suivant. Ceci est presque identique au code utilisé dans la leçon 6 pour charger le bitmap.
}
Fonction LoadBmp (nom de fichier : pchar) : PTAUX_RGBImageRec ;
Var
BitmapFile : Thandle ; // descripteur de fichier
Commencer
Si Filename = '' Then // Assurez-vous que le nom de fichier est fourni.
result := Nil; // S'il n'est pas fourni, renvoie NULL
BitmapFile := FileOpen(Filename, fmOpenWrite); //Essayez d'ouvrir le fichier
Si BitmapFile > 0 Alors // Le fichier existe-t-il ?
Commencer
FileClose(BitmapFile); //Fermer le handle
result := auxDIBImageLoadA(filename); //Charge le bitmap et renvoie le pointeur
Fin
Autre
result := Nil; // Si le chargement échoue, renvoie NiL.
Fin;
Function LoadTexture: boolean; //Charge le bitmap et convertit-le en texture
Var
Statut : booléen; // Indicateur d'état
TextureImage : Array[0..1] Of PTAUX_RGBImageRec; // Créer un espace de stockage de texture
Commencer
Statut := faux ;
ZeroMemory (@TextureImage, sizeof(TextureImage)); // Place le pointeur sur NULL
TextureImage[0] := LoadBMP('Walls.bmp');
Si TextureImage[0] <> Nil Alors
Commencer
Statut := VRAI ; // Définir le statut sur VRAI
glGenTextures(1, texture[0]); // Créer une texture
//Dans la leçon 6, nous avons utilisé un mappage de texture filtré linéaire.
//Cela nécessite une quantité assez élevée de puissance de traitement de la part de la machine, mais ils ont l'air plutôt bien.
//Dans cette leçon, la première texture que nous allons créer utilise la méthode GL_NEAREST.
//En principe, cette méthode n'effectue pas réellement de filtrage.
//Il consomme très peu de puissance de traitement et semble médiocre.
//Le seul avantage est que notre projet peut s'exécuter normalement sur des machines rapides et lentes.
//Vous remarquerez que nous utilisons GL_NEAREST pour MIN et MAG,
//Vous pouvez mélanger GL_NEAREST et GL_LINEAR.
//La texture sera meilleure, mais nous nous soucions davantage de la vitesse, nous utilisons donc toutes les cartes de mauvaise qualité.
//MIN_FILTER est utilisé lorsque l'image est dessinée plus petite que la taille originale de la texture.
//MAG_FILTER est utilisé lorsque l'image est dessinée plus grande que la taille originale de la texture.
// Créer une carte de filtre la plus proche
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Générer une texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST // (nouveau) ;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST // (nouveau) ;
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data);
//La texture suivante est la même que celle de la leçon 6, filtrage linéaire. La seule différence est que cette fois il est placé
//texture[1]. Parce que c'est la deuxième texture. Si placé
//texture[0], cela écrasera la texture GL_NEAREST précédemment créée.
glBindTexture(GL_TEXTURE_2D, texture[1]); //Utiliser une texture typique générée à partir de données bitmap
// Générer une texture
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Filtrage linéaire
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Filtrage linéaire
//Ce qui suit est une nouvelle façon de créer des textures. Mipmapping !
//『Note du traducteur : je ne peux pas traduire ce mot en chinois, mais cela n'a pas d'importance. Après avoir lu ce paragraphe, vous saurez que le sens est le plus important. 』
//Vous remarquerez peut-être que lorsque l'image devient plus petite à l'écran, de nombreux détails sont perdus.
//Le modèle qui avait l'air bien tout à l'heure est devenu moche. Lorsque vous dites à OpenGL de créer une texture mipmappée,
//OpenGL essaiera de créer des textures de haute qualité de différentes tailles. Lorsque vous dessinez une texture mipmappée sur l'écran,
//OpenGL choisira la texture la plus belle (avec plus de détails) qu'il a créée sur laquelle s'appuyer,
//Plutôt que de simplement redimensionner l'image originale (ce qui entraînera une perte de détails).
// J'ai dit un jour qu'il existait des moyens de contourner les limitations qu'OpenGL impose sur la largeur et la hauteur des textures - 64, 128, 256, etc.
//La solution est gluBuild2DMipmaps. D'après ce que j'ai trouvé, vous pouvez utiliser des bitmaps arbitraires pour créer des textures.
//OpenGL le redimensionnera automatiquement à sa taille normale.
//Comme il s'agit de la troisième texture, nous la sauvegardons dans texture[2]. De cette manière, les trois textures de cette leçon ont été créées.
//Créer une texture MipMappée
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST); // (nouveau)
//La ligne suivante génère une texture mipmappée.
//Nous utilisons trois couleurs (rouge, vert, bleu) pour générer une texture 2D.
//TextureImage[0].sizeX est la largeur du bitmap,
//TextureImage[0].sizeY est la hauteur du bitmap,
//(====Pour une raison quelconque, cette fonction sous Delphi n'a pas le paramètre height,
//Mais il y a ça dans l'aide. Je ne sais plus ce que Delphi va faire, ce qui me déprime...
//Enfin, j'ai moi-même écrit un gluBuild2DMipmaps plus tôt,
//Pour charger la fonction gluBuild2DMipmaps dans glu32.dll =====)
//GL_RGB signifie que nous utilisons les couleurs RVB à tour de rôle.
//GL_UNSIGNED_BYTE signifie que l'unité des données de texture est l'octet.
//TextureImage[0].data pointe vers le bitmap que nous utilisons pour créer la texture.
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0].sizeX,
TextureImage[0].sizey, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data); //(nouveau) }
Fin;
Si assigné(TextureImage[0]) Alors // Si la texture existe
Si attribué(TextureImage[0].data) Then // Si l'image de texture existe
TextureImage[0].data := Nil; // Libère la mémoire occupée par l'image de texture
TextureImage[0] := Nil; // Libère la structure de l'image
résultat := Statut ; // Retourne le statut
Fin;
//Ensuite, il est temps de charger la texture et d'initialiser les paramètres OpenGL.
//La première ligne de la fonction GLInit utilise le code ci-dessus pour charger la texture.
//Après avoir créé la texture, nous appelons glEnable(GL_TEXTURE_2D) pour activer le mappage de texture 2D.
//Le mode ombre est défini sur un ombrage lisse (ombrage lisse).
//La couleur d'arrière-plan est définie sur noir, nous activons les tests de profondeur, puis nous activons les calculs de perspective optimisés.
Procédure glInit(); // Démarrez tous les paramètres pour OpenGL ici
Commencer
If (Not LoadTexture) Then // Appel du sous-programme de chargement de texture
exit; // Si le chargement échoue, quittez
glEnable(GL_TEXTURE_2D); // Activer le mappage de texture
glShadeModel(GL_SMOOTH); // Activer le lissage des ombres
glClearColor(0.0, 0.0, 0.0, 0.0); // fond noir
glClearDepth(1.0); //Définit le tampon de profondeur
glEnable(GL_DEPTH_TEST); // Activer les tests de profondeur
glDepthFunc(GL_LESS); // Type de test de profondeur effectué
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Calcul de projection en perspective hautement optimisé
// Commencez maintenant à configurer la source de lumière. La ligne suivante ci-dessous définit la quantité de lumière ambiante émise,
//La source lumineuse light1 commence à émettre de la lumière.
//Au début de cette leçon, nous stockons la quantité de lumière ambiante dans le tableau LightAmbient.
//Nous allons maintenant utiliser ce tableau (lumière ambiante à demi-luminosité).
glLightfv(GL_LIGHT1, GL_AMBIENT, @LightAmbient[0]); // Définir la lumière ambiante
// Ensuite, nous définissons la quantité de lumière diffuse. Il est stocké dans le tableau LightDiffuse (lumière blanche à pleine luminosité).
glLightfv(GL_LIGHT1, GL_DIFFUSE, @LightDiffuse[0]); // Définir la lumière diffuse
//Puis définissez la position de la source lumineuse.
//La position est stockée dans le tableau LightPosition
//(Exactement au centre du devant de la boîte en bois, X-0.0, Y-0.0, déplacés de 2 unités vers l'observateur dans la direction Z <à l'extérieur de l'écran>).
glLightfv(GL_LIGHT1, GL_POSITION, @LightPosition); // Position de la source lumineuse
//Enfin, nous activons la source de lumière numéro un. Nous n'avons pas encore activé GL_LIGHTING,
//Donc tu ne peux voir aucune lumière.
//Rappelez-vous : le simple fait de configurer, de positionner ou même d'activer la source de lumière ne fonctionnera pas.
//Sauf si nous activons GL_LIGHTING.
glEnable(GL_LIGHT1); // Activer la source lumineuse n°1
Fin;
//Le morceau de code suivant dessine le cube texturé. J'annote uniquement le nouveau code.
//Si vous avez des questions sur le code sans annotations, revenez à la leçon 6.
Procédure glDraw(); // Tous les dessins commencent à partir d'ici
Commencer
glClear(GL_COLOR_BUFFER_BIT Ou GL_DEPTH_BUFFER_BIT); // Efface l'écran et le tampon de profondeur
glLoadIdentity(); //Réinitialiser la matrice d'observation du modèle actuel
//Les trois lignes de code suivantes placent et font pivoter le cube de texture.
//glTranslatef(0.0,0.0,z) déplace les unités Z du cube le long de l'axe Z.
//glRotatef(xrot,1.0f,0.0f,0.0f) fait pivoter le cube autour de l'axe X xrot.
//glRotatef(yrot,0.0f,1.0f,0.0f) fait pivoter le cube yrot autour de l'axe Y.
glTranslatef(0.0, 0.0, z); // Entrer/sortir de l'écran en unités z
glRotatef(xrot, 1.0, 0.0, 0.0); // Rotation autour de l'axe X
glRotatef(yrot, 0.0, 1.0, 0.0); // Rotation autour de l'axe Y
//La ligne suivante est similaire à ce que nous avons fait dans la leçon 6.
//La différence est que cette fois la texture que nous lions est texture[filter],
//Au lieu de texture[0] dans la leçon précédente.
//Chaque fois que nous appuyons sur la touche F, la valeur du filtre augmente.
//Si cette valeur est supérieure à 2, le filtre variable sera remis à 0.
//Lorsque le programme est initialisé, la valeur de la variable filtre sera également définie sur 0.
//En utilisant le filtre variable, nous pouvons sélectionner l'une des trois textures.
glBindTexture(GL_TEXTURE_2D, texture[filter]); //Sélectionnez la texture déterminée par le filtre
glBegin(GL_QUADS); // Commencer à dessiner des quadrilatères
//glNormal3f est nouveau dans cette leçon. Normal signifie normal.
//La dite normale fait référence à une ligne droite qui passe par un point sur une surface (polygone) et est perpendiculaire à cette surface (polygone).
//Lors de l'utilisation d'une source lumineuse, une normale doit être spécifiée. La normale indique à OpenGL l'orientation du polygone et indique les côtés avant et arrière du polygone.
//Si les normales ne sont pas spécifiées, des choses étranges peuvent se produire : les surfaces qui ne doivent pas être éclairées sont éclairées, et la face arrière du polygone est également éclairée....
//Au fait, la normale doit pointer vers l'extérieur du polygone. En regardant le devant de la boîte, vous remarquerez que la normale est dans la même direction que l’axe Z positif.
// Cela signifie que la normale pointe vers l'observateur - vous-même. C'est exactement ce que nous espérons.
//Pour le dos de la boîte en bois, comme nous le souhaitons, la normale est tournée vers le spectateur.
//Si le cube pivote de 180 degrés le long de l'axe X ou Y, la normale sur la face avant est toujours face à l'observateur et la normale sur la face arrière est toujours tournée vers l'opposé de l'observateur.
//En d'autres termes, quelle que soit la surface dont il s'agit, tant qu'elle fait face à l'observateur, la normale de cette surface pointe vers l'observateur.
//Puisque la source de lumière est immédiatement adjacente à l'observateur, chaque fois que la normale fait face à l'observateur, cette surface sera éclairée.
//Et plus la normale est proche de la source lumineuse, plus elle apparaîtra lumineuse.
//Si vous placez le point d'observation à l'intérieur du cube, vous obtiendrez l'obscurité à l'intérieur de la normale.
// Parce que la normale pointe vers l'extérieur. S’il n’y a pas de source de lumière à l’intérieur du cube, il fera bien sûr noir.
// Devant
glNormal3f(0.0, 0.0, 1.0); // pointe normale vers l'observateur
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // Texture et coin inférieur gauche du quad
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // Texture et coin inférieur droit du quad
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0); //Texture et coin supérieur droit du quad
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0); //Texture et coin supérieur gauche du quad
// plus tard
glNormal3f(0.0, 0.0, -1.0); // Visages normaux éloignés du spectateur
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0); // Texture et coin inférieur droit du quad
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); //Texture et coin supérieur droit du quad
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); //Texture et coin supérieur gauche du quad
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, -1.0); // Texture et coin inférieur gauche du quad
// surface supérieure
glNormal3f(0.0, 1.0, 0.0); // normal vers le haut
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); //Texture et coin supérieur gauche du quad
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0); // Texture et coin inférieur gauche du quad
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 1.0, 1.0); // Texture et coin inférieur droit du quad
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); //Texture et coin supérieur droit du quad
// Bas
glNormal3f(0.0, -1.0, 0.0); // normal face vers le bas
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, -1.0, -1.0); // Texture et coin supérieur droit du quad
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, -1.0, -1.0); //Texture et coin supérieur gauche du quad
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // Texture et coin inférieur gauche du quad
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // Texture et coin inférieur droit du quad
// droite
glNormal3f(1.0, 0.0, 0.0); // normal à droite
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, -1.0); // Texture et coin inférieur droit du quad
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); //Texture et coin supérieur droit du quad
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, 1.0, 1.0); //Texture et coin supérieur gauche du quad
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // Texture et coin inférieur gauche du quad
// gauche
glNormal3f(-1.0, 0.0, 0.0); // normal à gauche
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0); // Texture et coin inférieur gauche du quad
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // Texture et coin inférieur droit du quad
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0); //Texture et coin supérieur droit du quad
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); //Texture et coin supérieur gauche du quad
glFin();
xrot := xrot + xspeed; // xrot augmente les unités xspeed
yrot := Yrot + yspeed; // yrot augmente les unités yspeed
Fin;
// Accédez maintenant à la fonction principale WinMain().
//Nous ajouterons ici un code de contrôle pour allumer et éteindre la source de lumière, faire pivoter la boîte en bois, changer de méthode de filtrage et rapprocher et éloigner la boîte en bois.
// Vers la fin de la fonction WinMain(), vous verrez la ligne de code SwapBuffers(hDC).
// Ajoutez ensuite le code suivant après cette ligne.
//Le code vérifiera si la touche L a été enfoncée.
//Si la touche L a été enfoncée, mais que la valeur de lp n'est pas fausse, cela signifie que la touche L n'a pas été relâchée et rien ne se passera pour le moment.
SwapBuffers(h_DC); // Tampon d'échange (double tampon)
Si (keys[ord('L')] Et Pas lp) Alors
Commencer
//Si la valeur de lp est fausse,
// Cela signifie que la touche L n'a pas encore été enfoncée ou a été relâchée, alors lp sera défini sur TRUE.
//La raison de vérifier ces deux conditions en même temps est d'empêcher l'appui sur la touche L.
//Ce code est exécuté à plusieurs reprises et fait clignoter le formulaire en continu.
//Une fois que lp est défini sur true, l'ordinateur saura que la touche L a été enfoncée.
//Nous pouvons allumer/éteindre la source lumineuse en conséquence : la lumière variable booléenne contrôle l'allumage/extinction de la source lumineuse.
lp := true; // lp est défini sur TRUE
light := Pas de lumière ; // Basculez la source de lumière sur TRUE/FALSE
Si Pas de lumière Alors // S'il n'y a pas de source de lumière
glDisable(GL_LIGHTING) //Désactiver la source de lumière
Autre // Autres
glEnable(GL_LIGHTING); //Activer la source de lumière
Fin;
If Not keys[ord('L')] Then //La touche L est-elle relâchée ?
lp := FALSE; // Si oui, définissez lp sur FALSE
//Ensuite, effectuez une vérification similaire pour la touche "F".
//Si la touche "F" est enfoncée et que la touche "F" n'est pas enfoncée ou n'a jamais été enfoncée,
//Définit la variable fp sur true. Cela signifie que la touche est enfoncée.
//Puis ajoutez-en un à la variable de filtre. Si la variable du filtre est supérieure à 2
//(Comme le tableau que nous utilisons ici est texture[3], les textures supérieures à 2 n'existent pas),
//Nous réinitialisons la variable de filtre à 0.
If (keys[ord('F')] And Not fp) Then // La touche F est-elle enfoncée ?
Commencer
fp := VRAI ; // fp est défini sur VRAI
inc(filter); // Ajoute un à la valeur du filtre
Si filtre > 2 Alors // Est-il supérieur à 2 ?
filtre := 0; // Si réinitialisé à 0
Fin;
If Not keys[ord('F')] Then //La touche F a-t-elle été relâchée ?
fp := FALSE; // Si fp est défini sur FALSE
//Ces quatre lignes vérifient si la touche PageUp est enfoncée. Si tel est le cas, diminuez la valeur de la variable z. De cette façon, l'appel à glTranslatef(0.0f,0.0f,z) inclus dans la fonction DrawGLScene éloignera la boîte en bois du spectateur.
Si les touches [VK_PRIOR] Alors //PageUp est enfoncé ?
z := z - 0.02; // Si vous appuyez dessus, déplacez la boîte en bois vers l'intérieur de l'écran.
//Les quatre lignes suivantes vérifient si la touche PageDown est enfoncée. Si c'est le cas, augmentez la valeur de la variable z. De cette façon, l'appel glTranslatef(0.0f,0.0f,z) inclus dans la fonction DrawGLScene rapprochera la boîte en bois de l'observateur.
Si touches[VK_NEXT] Alors // Est-ce que PageDown est enfoncé ?
z := z + 0.02; //Si vous appuyez dessus, déplacez la boîte en bois vers l'observateur.
// Vérifiez maintenant les touches fléchées. Appuyez sur les touches de direction gauche et droite pour diminuer ou augmenter xspeed en conséquence.
//Appuyez sur les touches de direction haut et bas pour diminuer ou augmenter la vitesse en conséquence.
//N'oubliez pas que dans les prochains tutoriels, si les valeurs de xspeed et yspeed sont augmentées, le cube tournera plus rapidement.
//Si vous continuez à appuyer sur une certaine touche de direction, le cube tournera plus rapidement dans cette direction.
Si touches[VK_UP] Alors // La touche de direction Haut est-elle enfoncée ?
xspeed := xspeed - 0.01; //Si oui, réduisez xspeed
Si touches[VK_DOWN] Alors //La touche de direction Bas a-t-elle été enfoncée ?
xspeed := xspeed + 0.01; //Si oui, augmentez xspeed
Si les touches [VK_RIGHT] Alors //La touche de direction droite est-elle enfoncée ?
yspeed := yspeed + 0.01; //Si oui, augmentez yspeed
Si touches[VK_LEFT] Alors //La touche de direction gauche est-elle enfoncée ?
yspeed := yspeed - 0.01; //Si oui, réduisez yspeed
If (keys[VK_ESCAPE]) Then // Si la touche ESC est enfoncée
terminé := Vrai
Exécutez-le et voyez l'effet