Sign in Join
Wiki copytemporary

OpenGL Tutorial/fr: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11OpenGL est l'environnement idéal pour développer des applications graphiques portables , interactives en 2D et 3D. Depuis son introduction en 1992 , OpenGL est devenu l'interface de programmation d'applications (API) soutenant les graphiques 2D et 3D la plus largement utilisée de l'industrie, amenant plusieurs milliers d'applications à une grande variété de plateformes d'ordinateur. OpenGL stimule l'innovation et accélère le développement d'applications en incorporant un large ensemble de rendus, mappage de texture, effets spéciaux , et d'autres fonctions puissantes de visualisation . Les développeurs peuvent accroître la puissance de OpenGL à travers toutes les plate-formes de bureau communes et les plate-formes de poste de travail, assurant un large déploiement d'applications.
22
33Vous pouvez trouver plus d'information à propos d'OpenGL [ici](http://www.opengl.org/about/overview/).
44
55GLUT (prononcé comme the glut in gluttony) est une trousse à outils pour OpenGL, une trousse à outil indépendante du système window pour écrire des programmes OpenGL. Il implémente une simple interface de programmation d'application avec fenêtrage (API) pour OpenGL. GLUT rend considérablement plus facile l'apprentissage et l'exploration de la programmation OpenGL. GLUT fournit une API portable ainsi vous pouvez écrire un programme simple avec OpenGL qui travaille sur les plate-formes avec système d'exploitation à base de PC et de station de travail.
66
77Vous pouvez trouver plus d'information à propos de GLUT [ici](http://www.opengl.org/resources/libraries/glut/).
88
99Beaucoup d'OS viennent avec GLUT préinstallé, mais si le votre n'en a pas un, vous pouvez facilement le trouver en utilisant [Google](http://www.google.com/).
1010
1111Les fichiers binaires Windows peut être téléchargé depuis [www.xmission.com](http://www.xmission.com/~nate/glut.html).
1212
1313# Créer votre premier programme GLUT
1414
15-Afin d'utiliser GLUT, vous devez d'abord l'initialiser. C'est fait en utilisant la fonction <b>glutInit</b>. Cette fonction peut analyser la ligne de commande et fixer les paramètres de la fenêtre principale, mais il s'attend à une entrée dans le style C/C++ . Vous devrez écrire votre propre fonction pour faire la conversion à partir de ParamCount et ParamStr vers des paramètres en ligne de commande similaire à C/C++.
15+Afin d'utiliser GLUT, vous devez d'abord l'initialiser. C'est fait en utilisant la fonction glutInit. Cette fonction peut analyser la ligne de commande et fixer les paramètres de la fenêtre principale, mais il s'attend à une entrée dans le style C/C++ . Vous devrez écrire votre propre fonction pour faire la conversion à partir de ParamCount et ParamStr vers des paramètres en ligne de commande similaire à C/C++.
1616
1717``` pascal
1818 procedure glutInitPascal(ParseCmdLine: Boolean);
1919 var
2020 Cmd: array of PChar;
2121 CmdCount, I: Integer;
2222 begin
2323 if ParseCmdLine then
2424 CmdCount := ParamCount + 1
2525 else
2626 CmdCount := 1;
2727 SetLength(Cmd, CmdCount);
2828 for I := 0 to CmdCount - 1 do
2929 Cmd[I] := PChar(ParamStr(I));
3030 glutInit(@CmdCount, @Cmd);
3131 end;
3232```
3333
3434Essentiellement , vous créez un tableau et le remplissez avec les chaînes de caractères de ParamStr. Cette fonction prend également un paramètre qui peut contrôler ce qui est passé à glutInit -- ou bien la ligne de commande en entier ou juste le nom du fichier exécutable .
3535
3636Plus à propos de glutInit: [ici](http://www.opengl.org/resources/libraries/glut/spec3/node10.html)
3737
38-Après , vous devez créer une fenêtre principale . Fixer le mode d'affichage de la fenêtre principale en utilisant <b>glutInitDisplayMode</b>. Cela nécessite seulement un paramètre qui est une combinaison des drapeaux. Habituellement <b>GLUT_DOUBLE ou GLUT_RGB ou GLUT_DEPTH</b> est tout ce dont vous aurez besoin.
38+Après , vous devez créer une fenêtre principale . Fixer le mode d'affichage de la fenêtre principale en utilisant glutInitDisplayMode. Cela nécessite seulement un paramètre qui est une combinaison des drapeaux. Habituellement GLUT_DOUBLE ou GLUT_RGB ou GLUT_DEPTH est tout ce dont vous aurez besoin.
3939
4040Plus à propos de glutInitDisplayMode: [ici](http://www.opengl.org/resources/libraries/glut/spec3/node12.html)
4141
42-La position et la taille de la fenêtre est contrôlée en utilisant <b>glutInitWindowPosition</b> et <b>glutInitWindowSize</b>. Elles ont 2 paramètres . Les coordonnées X et Y dans le premier, et la largeur et la hauteur dans le dernier. Vous pouvez employer <b>glutGet</b> pour trouver la taille de l'écran et centrer la fenêtre.
42+La position et la taille de la fenêtre est contrôlée en utilisant glutInitWindowPosition et glutInitWindowSize. Elles ont 2 paramètres . Les coordonnées X et Y dans le premier, et la largeur et la hauteur dans le dernier. Vous pouvez employer glutGet pour trouver la taille de l'écran et centrer la fenêtre.
4343
4444Plus à propos de glutInitWindowPosition, glutInitWindowSize et glutGet: [ici](http://www.opengl.org/resources/libraries/glut/spec3/node11.html) et [là](http://www.opengl.org/documentation/specs/glut/spec3/node70.html)
4545
46-Enfin, la fenêtre devrait être créée en utilisant la fonction <b>glutCreateWindow</b>. Il créera la fenêtre et fixera son caption au moyen d'un paramètre. Comme résultat il renverra l'handle de la fenêtre . Ceci peut être employé avec d'autres fonctions qui l'exigent .
46+Enfin, la fenêtre devrait être créée en utilisant la fonction glutCreateWindow. Il créera la fenêtre et fixera son caption au moyen d'un paramètre. Comme résultat il renverra l'handle de la fenêtre . Ceci peut être employé avec d'autres fonctions qui l'exigent .
4747
4848Plus à propos de glutCreateWindow: [ici](http://www.opengl.org/resources/libraries/glut/spec3/node16.html)
4949
50-Avant que votre programme puisse entrer dans la boucle principale, vous devez paramétrer quelques procedures de rappel(callbacks). Vous aurez besoin de procédures de rappel pour dessiner la fenêtre , pour redimensionner et pour obtenir les entrées au clavier. Ces procédures de rappel sont paramétrées en utilisant <b>glutDisplayFunc</b>, <b>glutReshapeFunc</b> et <b>glutKeyboardFunc</b>.
50+Avant que votre programme puisse entrer dans la boucle principale, vous devez paramétrer quelques procedures de rappel(callbacks). Vous aurez besoin de procédures de rappel pour dessiner la fenêtre , pour redimensionner et pour obtenir les entrées au clavier. Ces procédures de rappel sont paramétrées en utilisant glutDisplayFunc, glutReshapeFunc et glutKeyboardFunc.
5151
5252Plus à propos du paramétrage des fonctions de rappel: [ici](http://www.opengl.org/resources/libraries/glut/spec3/node45.html#SECTION00080000000000000000)
5353
5454Votre fonction de dessin pourrait ressembler à ceci :
5555
5656``` pascal
5757 procedure DrawGLScene; cdecl;
5858 begin
5959 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
6060 glutSwapBuffers;
6161 end;
6262```
6363
6464Cela va seulement effacer la fenêtre à la couleur du fond et remettre à zéro le zbuffer (ne pas s'inquiéter pour zbuffer... vous en saurez plus à ce propos plus tard).
6565
6666Votre fonction de redimension pourrait ressembler à ceci :
6767
6868``` pascal
6969 procedure ReSizeGLScene(Width, Height: Integer); cdecl;
7070 begin
7171 if Height = 0 then
7272 Height := 1;
7373
7474 glViewport(0, 0, Width, Height);
7575 glMatrixMode(GL_PROJECTION);
7676 glLoadIdentity;
7777 gluPerspective(45, Width / Height, 0.1, 1000);
7878
7979 glMatrixMode(GL_MODELVIEW);
8080 glLoadIdentity;
8181 end;
8282```
8383
8484Avec ce code, vous dites à OpenGL où dans la fenêtre il devrait dessiner et fixer les matrices aux valeurs désirées (les fonctions de matrice seront expliquées plus tard ).
8585
8686L'entrée au clavier est évaluée avec la procedure de rappel suivante:
8787
8888``` pascal
8989 procedure GLKeyboard(Key: Byte; X, Y: Longint); cdecl;
9090 begin
9191 if Key = 27 then
9292 Halt(0);
9393 end;
9494```
9595
96-Cette fonction demandera à votre programme de quitter si vous appuyez sur la touche ESC. GLUT est conduit par des évènement et la seule manière de terminer votre programme est d'appeler <b>Halt</b> à l'intérieur d'une de vos fonctions de rappel. Si vous fermez la fenêtre d'une autre manière, elle disparaîtra , mais le programme continuera à faire une boucle au travers de la routine principale indéfiniment .
96+Cette fonction demandera à votre programme de quitter si vous appuyez sur la touche ESC. GLUT est conduit par des évènement et la seule manière de terminer votre programme est d'appeler Halt à l'intérieur d'une de vos fonctions de rappel. Si vous fermez la fenêtre d'une autre manière, elle disparaîtra , mais le programme continuera à faire une boucle au travers de la routine principale indéfiniment .
9797
98-Pour commencer la boucle principale , appellez <b>glutMainLoop</b>. Il écrira une boucle qui ne finit jamais , qui appelle toutes vos procedures de rappel.
98+Pour commencer la boucle principale , appellez glutMainLoop. Il écrira une boucle qui ne finit jamais , qui appelle toutes vos procedures de rappel.
9999
100100La partie principale de votre programme pourrait ressembler à ceci :
101101
102102``` pascal
103103 const
104104 AppWidth = 640;
105105 AppHeight = 480;
106106
107107 procedure InitializeGL;
108108 begin
109109 glClearColor(0.18, 0.20, 0.66, 0);
110110 end;
111111
112112 var
113113 ScreenWidth, ScreenHeight: Integer;
114114 begin
115115 glutInitPascal(True);
116116 glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
117117 glutInitWindowSize(AppWidth, AppHeight);
118118 ScreenWidth := glutGet(GLUT_SCREEN_WIDTH);
119119 ScreenHeight := glutGet(GLUT_SCREEN_HEIGHT);
120120 glutInitWindowPosition((ScreenWidth - AppWidth) div 2,
121121 (ScreenHeight - AppHeight) div 2);
122122 glutCreateWindow('OpenGL Tutorial 1');
123123
124124 InitializeGL;
125125
126126 glutDisplayFunc(@DrawGLScene);
127127 glutReshapeFunc(@ReSizeGLScene);
128128 glutKeyboardFunc(@GLKeyboard);
129129
130130 glutMainLoop;
131131 end.
132132```
133133
134134Le tutoriel suivant ajoutera un certain code qui dessinera une forme simple .
135135
136136Télécharger le code source ou un executable linux/windows depuis le site [SourceForge CCR de Lazarus](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
137137
138138# Dessiner une forme simple
139139
140140Cette fois nous ajouterons juste quelques lignes de code et nous nous focaliserons sur l'explication de certaines des fonctions OpenGL .
141141
142142Expliquons le code que vous avez déjà.
143143
144144``` pascal
145145
146146 .
147147 .
148148 .
149149 glMatrixMode(GL_PROJECTION);
150150 glLoadIdentity;
151151 gluPerspective(45, Width / Height, 0.1, 1000);
152152
153153 glMatrixMode(GL_MODELVIEW);
154154 glLoadIdentity;
155155 end;
156156```
157157
158-En employant la fonction <b>glMatrixMode</b> vous choisissez quelle matrice vous voulez changer . OpenGL travaille avec 3 matrices : <b>GL_MODELVIEW</b>: celle-ci est employée pour déplacer les sommets vers l'espace modèle . <b>GL_PROJECTION</b>: celle-ci est employée pour convertir les coordonnées 3d en coordonnées 2d pour la position finale des pixels. <b>GL_TEXTURE</b>: celle-ci est employée pour changer des coordonnées de texture .
158+En employant la fonction glMatrixMode vous choisissez quelle matrice vous voulez changer . OpenGL travaille avec 3 matrices : GL_MODELVIEW: celle-ci est employée pour déplacer les sommets vers l'espace modèle . GL_PROJECTION: celle-ci est employée pour convertir les coordonnées 3d en coordonnées 2d pour la position finale des pixels. GL_TEXTURE: celle-ci est employée pour changer des coordonnées de texture .
159159
160-Une fois que vous avez choisi la matrice vous voulez changer , vous pouvez appeler les fonctions qui affectent les valeurs de la matrice. <b>glLoadIdentity</b> remettra à zéro la matrice ainsi il n'affecte pas la position des sommets. Puisque la plupart des fonctions de matrice multiplient la matrice courante par celle générée , vous devez parfois effacer la matrice avec cette fonction .
160+Une fois que vous avez choisi la matrice vous voulez changer , vous pouvez appeler les fonctions qui affectent les valeurs de la matrice. glLoadIdentity remettra à zéro la matrice ainsi il n'affecte pas la position des sommets. Puisque la plupart des fonctions de matrice multiplient la matrice courante par celle générée , vous devez parfois effacer la matrice avec cette fonction .
161161
162-Afin de paramétrer la matrice de perspective, vous pouvez employer la fonction <b>gluPerspective</b>. Quatre paramètres montrent le champ visuel , l'allongement , la surface plane proche et lointaine. C'est aussi simple.
162+Afin de paramétrer la matrice de perspective, vous pouvez employer la fonction gluPerspective. Quatre paramètres montrent le champ visuel , l'allongement , la surface plane proche et lointaine. C'est aussi simple.
163163
164164Maintenant , vous changerez la matrice modèle ... pendant ce temps , vous l'avez juste paramétré à la matrice identité .
165165
166166OK ... et maintenant , le code pour dessiner la première forme :
167167
168168``` pascal
169169 procedure DrawGLScene; cdecl;
170170 begin
171171 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
172172
173173 glLoadIdentity;
174174 glTranslatef(0, 0, -5);
175175
176176 glBegin(GL_TRIANGLES);
177177 glColor3f(1, 0, 0);
178178 glVertex3f(-1, -1, 0);
179179
180180 glColor3f(0, 1, 0);
181181 glVertex3f(1, -1, 0);
182182
183183 glColor3f(0, 0, 1);
184184 glVertex3f(0, 1, 0);
185185 glEnd;
186186
187187 glutSwapBuffers;
188188 end;
189189```
190190
191191Nous avons déjà employé la fonction glClear. Elle remettra juste à zéro les mémoires tampons(buffers). Nous passerons les deux fonctions suivantes et nous nous dirigerons vers celles de dessin.
192192
193-<b>glBegin</b> marque le commencement du bloc de dessin . Après cette fonction vous pouvez commencer à entrer les sommets. Le paramètre(entre parenthèse) décrit comment sont utilisés les sommets en dessinant : GL_POINTS: Traite chaque sommet comme simple point. Le sommet n définit le point n . N points sont dessinés.
193+glBegin marque le commencement du bloc de dessin . Après cette fonction vous pouvez commencer à entrer les sommets. Le paramètre(entre parenthèse) décrit comment sont utilisés les sommets en dessinant : GL_POINTS: Traite chaque sommet comme simple point. Le sommet n définit le point n . N points sont dessinés.
194194
195195GL_LINES: Traite chaque paire de sommets comme segment de ligne indépendant. Les sommets 2n-1 et 2n définissent la ligne n . n/2 lignes sont tracées .
196196
197197GL_LINE_STRIP: Dessine un groupe relié de segments de ligne du premier sommet au dernier. n-1 lignes sont tracées.
198198
199199GL_LINE_LOOP: Dessine un groupe relié de segments de ligne du premier sommet au dernier, en revenant vers le premier. Les sommets n et n+1 définissent la ligne n . La dernière ligne , cependant , est défini par les sommets n et 1.n lignes sont tracées .
200200
201201GL_TRIANGLES: Traite chaque triplet des sommets comme un triangle indépendant . Les sommets 3n-2, 3n-1 et 3n définissent le triangle n. n/3 triangles sont tracées .
202202
203203GL_TRIANGLE_STRIP: Dessine un groupe relié de triangles . Un triangle est défini pour chaque sommet présenté après les deux premiers sommets. Pour n impair, les sommets n, n+1 et n+2 définissent le triangle n. Pour n pair, les sommets n+1, n et n+2 définissent le triangle n . n-2 triangles sont tracées .
204204
205205GL_TRIANGLE_FAN: Dessine un groupe relié de triangles . Une triangle est définie pour chaque sommet présenté après les deux premiers sommets . Les sommets 1, n+1 et n+2 définissent le triangle n. n-2 triangles sont dessinés .
206206
207207GL_QUADS: Traite chaque groupe de quatre sommets comme un quadrilatère indépendant. Les sommets 4n-3, 4n-2, 4n-1 et 4n définissent le quadrilatère n. n/4 quadrilatères sont dessinés.
208208
209209GL_QUAD_STRIP: Dessine un groupe relié de quadrilatères. Un quadrilatère est défini pour chaque paire de sommets présentés après la première paire.Les sommets 2n-1, 2n, 2n+2 et 2n+1 définissent le quadrilatère n. n/2-1 quadrilatères sont dessinés. Notez que l'ordre dans lequel des sommets sont employés pour construire un quadrilatère à partir des données reliées est différent de celui utilisé avec des données indépendantes.
210210
211211GL_POLYGON: Dessine un polygone simple et convexe . Les sommets 1 jusqu'à n définissent ce polygone .
212212
213-![](/wiki-images/f/f3/SimpleShapePic1.jpg) Vous tracerez un triangle simple et pour cela le drapeau GL_TRIANGLES accomplira cette astuce. La fonction <b>glVertex3f</b> définit la position d'un sommet que vous voulez dessiner. Il y a plus de fonctions glVertex* . La seule différence est le nombre et le type de paramètres que ces fonctions prennent. Par exemple ... glVertex2i prend deux paramètres (x et y) du type nombre entier. glVertex3f sera presque toujours juste ce que vous avez besoin.
213+![](/wiki-images/f/f3/SimpleShapePic1.jpg) Vous tracerez un triangle simple et pour cela le drapeau GL_TRIANGLES accomplira cette astuce. La fonction glVertex3f définit la position d'un sommet que vous voulez dessiner. Il y a plus de fonctions glVertex* . La seule différence est le nombre et le type de paramètres que ces fonctions prennent. Par exemple ... glVertex2i prend deux paramètres (x et y) du type nombre entier. glVertex3f sera presque toujours juste ce que vous avez besoin.
214214
215-Avant glVertex vous pouvez fixer la couleur, le matériel , les textures... Pour la simplicité vous indiquerez juste la couleur pour chaque sommet dans tutoriel . La couleur est paramétrée en utilisant la fonction <b>glColor3f</b>. glColor peut aussi prendre différents ensemble de paramètres comme glVertex.
215+Avant glVertex vous pouvez fixer la couleur, le matériel , les textures... Pour la simplicité vous indiquerez juste la couleur pour chaque sommet dans tutoriel . La couleur est paramétrée en utilisant la fonction glColor3f. glColor peut aussi prendre différents ensemble de paramètres comme glVertex.
216216
217-Si on jette un coup d'oeil sur le code, nous pouvons voir que Z est paramétré à 0 pour tous les sommets. Puisque vous avez fixé la plan proche à 0.1, le triangle ne sera pas visible. C'est là que nous avons passé les deux fonctions au commencement. Nous savons déjà que glLoadIdentity remet à zéro la matrice. <b>glTranslatef</b> déplace les triangles selon les valeurs X, Y et Z que vous fournissez. Puisque vous avez fixé Z à -5 (z négatif est plus loin de la caméra) tous les sommets seront dessinés avec un éloignement de 5 unités du point de vue et seront visibles.
217+Si on jette un coup d'oeil sur le code, nous pouvons voir que Z est paramétré à 0 pour tous les sommets. Puisque vous avez fixé la plan proche à 0.1, le triangle ne sera pas visible. C'est là que nous avons passé les deux fonctions au commencement. Nous savons déjà que glLoadIdentity remet à zéro la matrice. glTranslatef déplace les triangles selon les valeurs X, Y et Z que vous fournissez. Puisque vous avez fixé Z à -5 (z négatif est plus loin de la caméra) tous les sommets seront dessinés avec un éloignement de 5 unités du point de vue et seront visibles.
218218
219-À la fin vous appelez les fonctions <b>glEnd</b> qui finissent le dessin. Vous pourriez maintenant commencer d'autres bloc de dessin avec une nouvelle fonction glBegin si vous le souhaitez .
219+À la fin vous appelez les fonctions glEnd qui finissent le dessin. Vous pourriez maintenant commencer d'autres bloc de dessin avec une nouvelle fonction glBegin si vous le souhaitez .
220220
221221Téléchargez le code source , l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
222222
223223# Employer des listes d'affichage
224224
225-Parfois vous devrez dessiner quelques objets de multiples fois sur la scène. OpenGL a la capacité de construire <b>des listes d'affichage</b> ce qui rend le dessin un peu plus rapide.Créer une liste d'affichage est très facile ... dessinez juste les sommets comme vous l'avez fait dans le précédent tutoriel et enfermez-les avec les appels à <b>glNewList</b> et <b>glEndList</b>.
225+Parfois vous devrez dessiner quelques objets de multiples fois sur la scène. OpenGL a la capacité de construire des listes d'affichage ce qui rend le dessin un peu plus rapide.Créer une liste d'affichage est très facile ... dessinez juste les sommets comme vous l'avez fait dans le précédent tutoriel et enfermez-les avec les appels à glNewList et glEndList.
226226
227227``` pascal
228228 const
229229 LIST_OBJECT = 1;
230230
231231 procedure CreateList;
232232 begin
233233 glNewList(LIST_OBJECT, GL_COMPILE);
234234 glBegin(GL_TRIANGLE_FAN);
235235 glColor3f(1, 0, 0);
236236 glVertex3f(0, 0.5, 0);
237237
238238 glColor3f(1, 1, 0);
239239 glVertex3f(-0.5, -0.5, 0.5);
240240
241241 glColor3f(1, 1, 1);
242242 glVertex3f(0.5, -0.5, 0.5);
243243
244244 glColor3f(0, 1, 1);
245245 glVertex3f(0.5, -0.5, -0.5);
246246
247247 glColor3f(0, 0, 1);
248248 glVertex3f(-0.5, -0.5, -0.5);
249249
250250 glColor3f(0, 1, 0);
251251 glVertex3f(-0.5, -0.5, 0.5);
252252 glEnd;
253253
254254 glBegin(GL_QUADS);
255255 glColor3f(1, 1, 0);
256256 glVertex3f(-0.5, -0.5, 0.5);
257257
258258 glColor3f(1, 1, 1);
259259 glVertex3f(0.5, -0.5, 0.5);
260260
261261 glColor3f(0, 1, 1);
262262 glVertex3f(0.5, -0.5, -0.5);
263263
264264 glColor3f(0, 0, 1);
265265 glVertex3f(-0.5, -0.5, -0.5);
266266
267267 glColor3f(0, 1, 0);
268268 glVertex3f(-0.5, -0.5, 0.5);
269269 glEnd;
270270 glEndList;
271271 end;
272272```
273273
274-<b>glNewList</b> crée une nouvelle liste d'affichage et toutes les fonctions de dessin seront enregistrées jusqu'à ce que <b>glEndList</b> soit appelé. Le premier paramètre pour la fonction glNewList est l'identification de la liste(ID).Chaque liste est définie par son ID. Si une liste avec une identification donnée est déjà créée son contenu est effacé avant l'enregistrement. Si le deuxième paramètre est GL_COMPILE alors toutes les fonctions de dessin sont juste enregistrées , mais si c'est GL_COMPILE_AND_EXECUTE alors elles sont enregistrées et exécutées automatiquement.
274+glNewList crée une nouvelle liste d'affichage et toutes les fonctions de dessin seront enregistrées jusqu'à ce que glEndList soit appelé. Le premier paramètre pour la fonction glNewList est l'identification de la liste(ID).Chaque liste est définie par son ID. Si une liste avec une identification donnée est déjà créée son contenu est effacé avant l'enregistrement. Si le deuxième paramètre est GL_COMPILE alors toutes les fonctions de dessin sont juste enregistrées , mais si c'est GL_COMPILE_AND_EXECUTE alors elles sont enregistrées et exécutées automatiquement.
275275
276-La fonction <b>glIsList</b> peut vous aider avec des listes d'affichage. Il peut indiquer si une certaine identification de liste est déjà remplie de données. Une autre fonction utile est <b>glGenLists</b>. Il créera de multiple listes d'affichage vides. Vous passez le nombre de listes d'affichage dont vous avez besoin et vous obtenez l'identification de la première. Si vous exigez n listes, et obtenez r identifications,les listes d'affichage produites sont : r, r+1, r+2,..., r+n-1
276+La fonction glIsList peut vous aider avec des listes d'affichage. Il peut indiquer si une certaine identification de liste est déjà remplie de données. Une autre fonction utile est glGenLists. Il créera de multiple listes d'affichage vides. Vous passez le nombre de listes d'affichage dont vous avez besoin et vous obtenez l'identification de la première. Si vous exigez n listes, et obtenez r identifications,les listes d'affichage produites sont : r, r+1, r+2,..., r+n-1
277277
278278Toutes les listes créées devraient être supprimées. Vous ferez cela avant de quitter le programme :
279279
280280``` pascal
281281 procedure GLKeyboard(Key: Byte; X, Y: Longint); cdecl;
282282 begin
283283 if Key = 27 then
284284 begin
285285 glDeleteLists(LIST_OBJECT, 1);
286286 Halt(0);
287287 end;
288288 end;
289289```
290290
291-<b>glDeleteLists</b> prend 2 paramètres, l'identification de la liste d'affichage et le nombre de listes à supprimer. Si l'identification est r, et le nombre de listes à supprimer est n, les listes supprimées sont : r, r+1, r+2,..., r+n-1
291+glDeleteLists prend 2 paramètres, l'identification de la liste d'affichage et le nombre de listes à supprimer. Si l'identification est r, et le nombre de listes à supprimer est n, les listes supprimées sont : r, r+1, r+2,..., r+n-1
292292
293293Maintenant vous savez créer et supprimer des listes d'affichage ... voyons comment les dessiner :
294294
295295``` pascal
296296 procedure DrawGLScene; cdecl;
297297 begin
298298 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
299299
300300 glLoadIdentity;
301301 glTranslatef(-2, 0, -5);
302302 glRotatef(40, 1, 0, 1);
303303 glCallList(LIST_OBJECT);
304304
305305 glLoadIdentity;
306306 glTranslatef(1, -2, -10);
307307 glRotatef(62, 0, 1, 0);
308308 glCallList(LIST_OBJECT);
309309
310310 glLoadIdentity;
311311 glTranslatef(-4, 0.5, -15);
312312 glRotatef(200, 1, 0, 0);
313313 glCallList(LIST_OBJECT);
314314
315315 glutSwapBuffers;
316316 end;
317317```
318318
319-![](/wiki-images/a/a5/DisplayListsPic1.jpg) En utilisant <b>glCallList</b> vous pouvez dessiner seulement une liste d'affichage . Dans ce tutoriel, avant de dessiner une liste d'affichage, vous changez la matrice modèle et dessinez l'objet en différents endroits . Quelques fois vous voudriez dessiner des listes multiples d'un coup. C'est possible en utilisant la fonction <b>glCallLists</b>. Il prend le nombre de listes que vous voulez dessiner, le type de tableau qui contient les identifications de liste d'affichage et le tableau avec les identifications de liste d'affichage. Le type de liste peut être l'un des suivant :
319+![](/wiki-images/a/a5/DisplayListsPic1.jpg) En utilisant glCallList vous pouvez dessiner seulement une liste d'affichage . Dans ce tutoriel, avant de dessiner une liste d'affichage, vous changez la matrice modèle et dessinez l'objet en différents endroits . Quelques fois vous voudriez dessiner des listes multiples d'un coup. C'est possible en utilisant la fonction glCallLists. Il prend le nombre de listes que vous voulez dessiner, le type de tableau qui contient les identifications de liste d'affichage et le tableau avec les identifications de liste d'affichage. Le type de liste peut être l'un des suivant :
320320
321321GL_BYTE: la liste est traitée comme un tableau d'octets signés, chacun dans l'intervalle de -128 à 127 .
322322
323323GL_UNSIGNED_BYTE: la liste est traitée comme un tableau d'octets non signés, chacun dans l'intervalle de 0 à 255.
324324
325325GL_SHORT: la liste est traitée comme un tableau d'entiers sur 2 octets signés, chacun dans l'intervalle de -32768 à 32767.
326326
327327GL_UNSIGNED_SHORT: la liste est traitée comme un tableau d'entiers sur 2 octets non signés, chacun dans l'intervalle de 0 à 65535.
328328
329329GL_INT: la liste est traitée comme un tableau d'entiers sur 4 octets signés.
330330
331331GL_UNSIGNED_INT: la liste est traitée comme un tableau d'entiers sur 4 octets non signés.
332332
333333GL_FLOAT: la liste est traitée comme un tableau de valeurs à virgule flottante sur 4 octets.
334334
335335GL_2_BYTES: la liste est traitée comme un tableau d'octets non signés. Chaque paire d'octet spécifie une identification simple de la liste d'affichage. La valeur de la paire est calculée comme étant 256 fois la valeur du premier octet non signée plus la valeur du deuxième octet non signée .
336336
337337GL_3_BYTES: la liste est traitée comme un tableau d'octets non signés. Chaque triplet d'octet spécifie une identification simple de la liste d'affichage. La valeur du triplet est calculée comme étant 65536 fois la valeur du premier octet non signée, plus 256 fois la valeur du deuxième octet non signée, plus la valeur du troisième octet non signée.
338338
339339GL_4_BYTES: la liste est traitée comme un tableau d'octets non signés. Chaque quadruplet d'octet spécifie une identification simple de la liste d'affichage. La valeur du quadruplet est calculée comme étant 16777216 fois la valeur du premier octet non signée, plus 65536 fois la valeur du deuxième octet non signée, plus 256 la valeur du troisième octet non signée, plus la valeur du quatrième octet non signée.
340340
341341C'est tout pour le moment. Le prochain tutoriel montrera comment créer petit système planétaire. Nous parlerons des matrices et comment faire une scène animée qui ne dépend pas du nombre d'images par seconde .
342342
343343Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
344344
345345# Animation en plein écran
346346
347347Entrer dans le mode plein écran est facile avec GLUT. Changeons la partie principale du programme :
348348
349349``` pascal
350350 const
351351 FSMode = '800x600:32@75';
352352
353353 begin
354354 glutInitPascal(False);
355355 glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
356356 glutGameModeString(FSMode);
357357 glutEnterGameMode;
358358 glutSetCursor(GLUT_CURSOR_NONE);
359359
360360 InitializeGL;
361361
362362 glutDisplayFunc(@DrawGLScene);
363363 glutReshapeFunc(@ReSizeGLScene);
364364 glutKeyboardFunc(@GLKeyboard);
365365 glutIdleFunc(@DrawGLScene);
366366
367367 glutMainLoop;
368368 end.
369369```
370370
371-Puisque nous ne voulons pas que GLUT analyse la ligne de commande cette fois nous appelons glutInitPascal avec le paramètre false. Comme vous pouvez le voir, il n'y a aucun code pour la création de fenêtre. GLUT a <b>glutEnterGameMode</b> qui crée une fenêtre en mode plein écran. Pour indiquer quel genre de mode plein écran vous voulez, vous appelez la fonction <b>glutGameModeString</b> qui prend un chaine de caractères qui définie le mode que vous aimez . Le format de cette chaine de caractères est :
371+Puisque nous ne voulons pas que GLUT analyse la ligne de commande cette fois nous appelons glutInitPascal avec le paramètre false. Comme vous pouvez le voir, il n'y a aucun code pour la création de fenêtre. GLUT a glutEnterGameMode qui crée une fenêtre en mode plein écran. Pour indiquer quel genre de mode plein écran vous voulez, vous appelez la fonction glutGameModeString qui prend un chaine de caractères qui définie le mode que vous aimez . Le format de cette chaine de caractères est :
372372
373373`[largeur  "x" hauteur][":" bpp]["@" hertz]`
374374
375375Dans la chaine de caractères FSMode nous avons déclaré que le mode plein écran devrait être 800x600, avec une pallete de 32bit et un rafraîchissements de 75Hz. Il est possible de sauter un des groupes . Si vous omettez la taille , GLUT essayera d'employer la taille courante ou la première des plus petites qui peut fonctionner. Cette politique est employée et pour d'autres paramètres .
376376
377-Habituellement dans le mode plein écran le curseur n'est pas visible. Pour cacher le curseur vous utilisez la fonction <b>glutSetCursor</b>. Elle utilise seulement un paramètre qui décrit le curseur que vous voudriez voir :
377+Habituellement dans le mode plein écran le curseur n'est pas visible. Pour cacher le curseur vous utilisez la fonction glutSetCursor. Elle utilise seulement un paramètre qui décrit le curseur que vous voudriez voir :
378378
379379`GLUT_CURSOR_RIGHT_ARROW`\
380380`GLUT_CURSOR_LEFT_ARROW`\
381381`GLUT_CURSOR_INFO`\
382382`GLUT_CURSOR_DESTROY`\
383383`GLUT_CURSOR_HELP`\
384384`GLUT_CURSOR_CYCLE`\
385385`GLUT_CURSOR_SPRAY`\
386386`GLUT_CURSOR_WAIT`\
387387`GLUT_CURSOR_TEXT`\
388388`GLUT_CURSOR_CROSSHAIR`\
389389`GLUT_CURSOR_UP_DOWN`\
390390`GLUT_CURSOR_LEFT_RIGHT`\
391391`GLUT_CURSOR_TOP_SIDE`\
392392`GLUT_CURSOR_BOTTOM_SIDE`\
393393`GLUT_CURSOR_LEFT_SIDE`\
394394`GLUT_CURSOR_RIGHT_SIDE`\
395395`GLUT_CURSOR_TOP_LEFT_CORNER`\
396396`GLUT_CURSOR_TOP_RIGHT_CORNER`\
397397`GLUT_CURSOR_BOTTOM_RIGHT_CORNER`\
398398`GLUT_CURSOR_BOTTOM_LEFT_CORNER`\
399399`GLUT_CURSOR_FULL_CROSSHAIR`\
400400`GLUT_CURSOR_NONE`\
401401`GLUT_CURSOR_INHERIT`
402402
403-<b>glutIdleFunc</b> définit une fonction de rappel que vous voulez appeler chaque fois que votre programme n'a aucun message à traiter. Puisque nous voulons juste faire le rendu de la nouvelle image s'il n'y a rien à faire, juste faire tourner en idle DrawGLScene. Certains autres tutoriels montrent que la fonction idle devrait envoyer un message de refresh plutôt que de dessin, mais ainsi j'ai 50-100 images de moins qu'en utilisant la méthode que j'ai décrit .
403+glutIdleFunc définit une fonction de rappel que vous voulez appeler chaque fois que votre programme n'a aucun message à traiter. Puisque nous voulons juste faire le rendu de la nouvelle image s'il n'y a rien à faire, juste faire tourner en idle DrawGLScene. Certains autres tutoriels montrent que la fonction idle devrait envoyer un message de refresh plutôt que de dessin, mais ainsi j'ai 50-100 images de moins qu'en utilisant la méthode que j'ai décrit .
404404
405405Maintenant , regardons l'arrêt de programme là où vous devez quitter le mode plein écran :
406406
407407``` pascal
408408 procedure GLKeyboard(Key: Byte; X, Y: Longint); cdecl;
409409 begin
410410 if Key = 27 then
411411 begin
412412 glutLeaveGameMode;
413413 Halt(0);
414414 end;
415415 end;
416416```
417417
418-Comme vous pouvez le voir , tout que vous devez faire est d'appeler <b>glutLeaveGameMode</b>.
418+Comme vous pouvez le voir , tout que vous devez faire est d'appeler glutLeaveGameMode.
419419
420420Maintenant , nous allons présenter quelques nouvelles fonctions de matrice. D'abord, changeons la fonction ReSizeGLScene :
421421
422422``` pascal
423423 procedure ReSizeGLScene(Width, Height: Integer); cdecl;
424424 begin
425425 .
426426 .
427427 .
428428
429429 glMatrixMode(GL_MODELVIEW);
430430 glLoadIdentity;
431431 gluLookAt(0, 20, 25, 0, 0, 0, 0, 1, 0);
432432 end;
433433```
434434
435-<b>gluLookAt</b> créer la matrice qui définira d'où êtes vous pour regarder les objets. Les 3 premiers paramètres sont les coordonnées X, Y et Z de la position de la caméra. les 3 paramètres suivants sont les coordonnées X, Y et Z du point vers où la caméra regarde, et les 3 derniers paramètres définissent un vecteur « vers le haut » (C'est « vers le haut » pour la caméra). Habituellement , « vers le haut » est l'axe y positif.
435+gluLookAt créer la matrice qui définira d'où êtes vous pour regarder les objets. Les 3 premiers paramètres sont les coordonnées X, Y et Z de la position de la caméra. les 3 paramètres suivants sont les coordonnées X, Y et Z du point vers où la caméra regarde, et les 3 derniers paramètres définissent un vecteur « vers le haut » (C'est « vers le haut » pour la caméra). Habituellement , « vers le haut » est l'axe y positif.
436436
437437OK, dessinons maintenant. Puisque vous avez défini la matrice avec gluLookAt laquelle devrait être employé avec tous les objets, vous ne pouvez pas simplement employer glLoadIdentity pour remettre à zéro la matrice pour le prochain objet ... vous sauverez l'état précédent de la matrice et le restaurerez après que l'objet soit dessiné :
438438
439439``` pascal
440440 procedure DrawGLScene; cdecl;
441441 var
442442 T: Single;
443443 begin
444444 T := glutGet(GLUT_ELAPSED_TIME) / 1000;
445445 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
446446
447447 glPushMatrix;
448448 glRotatef(5 * T, 0, 1, 0);
449449 glColor3f(1, 1, 0);
450450 glutWireSphere(2, 20, 20);
451451 glPopMatrix;
452452
453453 glPushMatrix;
454454 glRotatef(90 * T, 0, 1, 0);
455455 glTranslatef(5, 0, 0);
456456 glRotatef(40 * T, 0, 1, 0);
457457 glColor3f(1, 0, 0);
458458 glutWireSphere(0.6, 10, 10);
459459 glPopMatrix;
460460
461461 glPushMatrix;
462462 glRotatef(60 * T, 0, 1, 0);
463463 glTranslatef(-3, 0, 9);
464464 glRotatef(50 * T, 0, 1, 0);
465465 glColor3f(0, 1, 0);
466466 glutWireSphere(1, 16, 16);
467467
468468 glPushMatrix;
469469 glRotatef(360 * T, 0, 1, 0);
470470 glTranslatef(-1.7, 0, 0);
471471 glRotatef(50 * T, 0, 1, 0);
472472 glColor3f(0, 0, 1);
473473 glutWireSphere(0.4, 10, 10);
474474 glPopMatrix;
475475
476476 glPopMatrix;
477477
478478 glutSwapBuffers;
479479 end;
480480```
481481
482-![](/wiki-images/5/51/FullScreenAnimationPic1.jpg) <b>glPushMatrix</b> et <b>glPopMatrix</b> sont employés pour enregistrer et restaurer l'état de la matrice. Comme vous pouvez le voir, nous enregistrons l'état de la matrice, ensuite changeons la matrice afin de dessiner l'objet à la bonne place, et restaurons ensuite l'ancien état de la matrice .
482+![](/wiki-images/5/51/FullScreenAnimationPic1.jpg) glPushMatrix et glPopMatrix sont employés pour enregistrer et restaurer l'état de la matrice. Comme vous pouvez le voir, nous enregistrons l'état de la matrice, ensuite changeons la matrice afin de dessiner l'objet à la bonne place, et restaurons ensuite l'ancien état de la matrice .
483483
484-Vous pouvez vous demander quel est le rôle de la variable <b>T</b> . Bien, elle est employée pour déterminer la vitesse d'animation. Chaque changement qui dépend du temps est multiplié par T. De cette manière, la vitesse d'animation est constante pour chaque rapidité d'affichage . La fonction <b>glutGet</b> avec le paramètre <b>GLUT_ELAPSED_TIME</b> renvoie le temps en milliseconds depuis que glutInit a été appelé. En divisant cette valeur par 1000, nous avons le temps en secondes .
484+Vous pouvez vous demander quel est le rôle de la variable T . Bien, elle est employée pour déterminer la vitesse d'animation. Chaque changement qui dépend du temps est multiplié par T. De cette manière, la vitesse d'animation est constante pour chaque rapidité d'affichage . La fonction glutGet avec le paramètre GLUT_ELAPSED_TIME renvoie le temps en milliseconds depuis que glutInit a été appelé. En divisant cette valeur par 1000, nous avons le temps en secondes .
485485
486-La fonction <b>glRotatef</b> créer une matrice de rotation. Le premier paramètre est l'angle en degrés,et les 3 derniers paramètres définissent l'axe autour duquel la rotation sera faite . Puisque vous avez multiplié l'angle par T, l'objet sera tourné de cet angle en exactement 1 seconde.
486+La fonction glRotatef créer une matrice de rotation. Le premier paramètre est l'angle en degrés,et les 3 derniers paramètres définissent l'axe autour duquel la rotation sera faite . Puisque vous avez multiplié l'angle par T, l'objet sera tourné de cet angle en exactement 1 seconde.
487487
488488Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
489489
490490# Lumière
491491
492492Ce tutoriel présentera une certaine lumière à la scène. Vous ferez tourner un cube et une lumière ajoutera du réalisme à la scène, mais d'abord faisons une unité d'outils .
493493
494494Dans l'immédiat, il y aura seulement des fonctions fondamentales pour nous aider à obtenir le temps courant et la variation de temps(temps qui s'est écoulé depuis un appel à un rendu à l'autre) afin de calculer le nombre d'images par secondes.
495495
496496``` pascal
497497 unit utils;
498498
499499 {$mode objfpc}{$H+}
500500
501501 interface
502502
503503 uses
504504 glut;
505505
506506 function GetTotalTime: Single;
507507 function GetDeltaTime: Single;
508508 procedure FrameRendered(Count: Integer = 1);
509509 function GetFPS: Single;
510510
511511 implementation
512512
513513 var
514514 OldTime: Integer = 0;
515515 FPSTime: Integer = 0;
516516 FPSCount: Integer = 0;
517517
518518 function GetTotalTime: Single;
519519 begin
520520 Result := glutGet(GLUT_ELAPSED_TIME) / 1000;
521521 end;
522522
523523 function GetDeltaTime: Single;
524524 var
525525 NewTime: Integer;
526526 begin
527527 NewTime := glutGet(GLUT_ELAPSED_TIME);
528528 Result := (NewTime - OldTime) / 1000;
529529 OldTime := NewTime;
530530 end;
531531
532532 procedure FrameRendered(Count: Integer);
533533 begin
534534 Inc(FPSCount, Count);
535535 end;
536536
537537 function GetFPS: Single;
538538 var
539539 NewTime: Integer;
540540 begin
541541 NewTime := glutGet(GLUT_ELAPSED_TIME);
542542
543543 Result := FPSCount / ((NewTime - FPSTime) / 1000);
544544
545545 FPSTime := NewTime;
546546 FPSCount := 0;
547547 end;
548548
549549 end.
550550```
551551
552552Comme vous pouvez le voir, il n'y a rien de compliqué dans cette unité. Le temps est simplement enregistré entre chaque appel et la différence est retournée. FrameRendered devrait être appelé chaque fois que vous dessinez la scène ainsi la fonction peut calculer les FPS.
553553
554554Maintenant, amusons nous avec les lumières.
555555
556556OpenGL a plusieurs types de lumières ... ambiante, diffuse, ponctuelle, spot, lumière spéculaire et émissive.
557557
558558La lumière ambiante est quelque chose comme le Soleil. Quand les rayons du soleil traversent la fenêtre d'une salle, ils frappent les murs et sont réfléchis et dispersés dans toutes les différentes directions ce qui illumine en moyenne toute la salle. Tous les sommets sont éclairés avec la lumière ambiante .
559559
560560La lumière diffuse peut être représentée par des rayons de lumière parallèles venant de loin. Ils vont seulement éclairer les sommets qui sont orientés vers la source lumineuse.
561561
562562La lumière ponctuelle éclaire tout autour d'elle. C'est comme une boule de feu, elle envoie des rayons lumineux tout autour d'elle et éclaire les sommets qui sont orientés vers la source lumineuse et qui sont assez proche.
563563
564564La lumière spot est comme la lumière d'une lampe-torche. C'est simplement une source ponctuelle lumineuse avec un petit faisceau de lumière en forme de cône. Tous les sommets qui tombent à l'intérieur du cône et sont assez proche sont éclairés.
565565
566566Juste comme la lumière diffuse, la lumière spéculaire est un type directionnel de lumière. Elle vient d'une direction particulière. La différence entre les deux est que la lumière spéculaire se reflète sur la surface d'une manière directionnelle et uniforme. Le rendu de la lumière spéculaire repose sur l'observateur et la source lumineuse. Du point de vue de l'observateur, la lumière spéculaire crée un secteur accentué sur la surface de l'objet vu, connu en tant que "specular highlight" ou réflexion spéculaire.
567567
568568La lumière émissive est peu une différente que tout autre composants lumineux précédemment expliqué. Cette lumière sort de l'objet que vous dessinez but pas n'éclaire pas d'autres objets dans son environnement .
569569
570570Pour plus de simplicité, nous emploierons seulement la lumière diffuse dans ce tutoriel. Plus tard, d'autres lumières peuvent apparaître dans les tutoriels :)
571571
572572Voyons comment autoriser la lumière dans la scène :
573573
574574``` pascal
575575 const
576576 DiffuseLight: array[0..3] of GLfloat = (0.8, 0.8, 0.8, 1);
577577
578578 glEnable(GL_LIGHTING);
579579 glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
580580 glEnable(GL_LIGHT0);
581581```
582582
583-Comme vous le voyez, nous permettons l'éclairage dans OpenGL ainsi les lumières affectent la scène dont vous faites le rendu. Des paramètres lumineux sont fixés avec la fonction <b>glLightfv</b>. Elle prend 3 paramètres... un pour le numéro de la lumière que vous voulez changer (OpenGL supporte jusqu'à 8 lumières), ensuite dit à OpenGL quel paramètre lumineux changer, et le dernier est un nouveau paramètre pour la lumière . Vous fixerez juste la couleur diffuse pour la lumière dans ce tutoriel. Après cela, vous pouvez permettre la lumière et il y aura la lumière dans la scène ... mais ... ce n'est pas tout .
583+Comme vous le voyez, nous permettons l'éclairage dans OpenGL ainsi les lumières affectent la scène dont vous faites le rendu. Des paramètres lumineux sont fixés avec la fonction glLightfv. Elle prend 3 paramètres... un pour le numéro de la lumière que vous voulez changer (OpenGL supporte jusqu'à 8 lumières), ensuite dit à OpenGL quel paramètre lumineux changer, et le dernier est un nouveau paramètre pour la lumière . Vous fixerez juste la couleur diffuse pour la lumière dans ce tutoriel. Après cela, vous pouvez permettre la lumière et il y aura la lumière dans la scène ... mais ... ce n'est pas tout .
584584
585585Plus à propos de [glLightfv](http://www.opengl.org//documentation/specs/man_pages/hardcopy/GL/html/gl/light.html)
586586
587587Si vous voulez employer des lumières, vous ne pouvez pas simplement fixer la couleur des sommets ... vous devez choisir le matériau pour les sommets . Installons le matériau pour le dessin :
588588
589589`glEnable(GL_COLOR_MATERIAL);`\
590590`glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);`
591591
592-![](/wiki-images/e/ed/LightPic1.jpg) Vous vous êtes attendus à quelque chose plus compliquée, n'est ce pas? :) Bien, ce code nous permet d'employer la fonction glColor pour fixer le matériau aux sommets. En employant la fonction glEnable et le drapeau GL_COLOR_MATERIAL, vous pouvez définir quelles propriétés matérielles vont changer glColor. <b>glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE)</b> dit à OpenGL que glColor change le matériau ambiant et diffus. Nous discuterons des matériaux davantage dans des tutoriels postérieurs .
592+![](/wiki-images/e/ed/LightPic1.jpg) Vous vous êtes attendus à quelque chose plus compliquée, n'est ce pas? :) Bien, ce code nous permet d'employer la fonction glColor pour fixer le matériau aux sommets. En employant la fonction glEnable et le drapeau GL_COLOR_MATERIAL, vous pouvez définir quelles propriétés matérielles vont changer glColor. glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) dit à OpenGL que glColor change le matériau ambiant et diffus. Nous discuterons des matériaux davantage dans des tutoriels postérieurs .
593593
594594Une chose de plus qui est importante en utilisant des lumières... chaque sommet doit avoir une normale qui lui est associée. La normale est employée pour trouver la direction du sommet ainsi la lumière peut être calculée correctement . Vous emploierez un fonction GLUT pour dessiner le cube et elle fournit les normales pour nous, ainsi cette fois nous marcherons juste par les normales (???).
595595
596596Après tout ces réglages, la lumière fera briller votre cube :)
597597
598598Une partie du texte est copiée depuis [La bible de la lumière avec OpenGL](http://www.falloutsoftware.com/tutorials/gl/gl8.htm)
599599
600600Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
601601
602602# Polices de caractères d'image
603603
604604Les jeux et les programmes doivent habituellement écrire un certain texte sur l'écran. GLUT fournit plusieurs fonctions pour dessiner des caractères qui sont indépendantes de la plate-forme .
605605
606606D'abord, nous montrerons comment employer les polices de caractères d'image par défaut. Presque toutes les additions de code seront faites à l'unité utils.pas .
607607
608608Puisque le texte sera dessiné en 2D, nous devrons savoir la largeur et la hauteur de la clôture(viewport) ... ainsi, nous écrirons deux fonctions pour cela :
609609
610610``` pascal
611611 function glGetViewportWidth: Integer;
612612 var
613613 Rect: array[0..3] of Integer;
614614 begin
615615 glGetIntegerv(GL_VIEWPORT, @Rect);
616616 Result := Rect[2] - Rect[0];
617617 end;
618618
619619 function glGetViewportHeight: Integer;
620620 var
621621 Rect: array[0..3] of Integer;
622622 begin
623623 glGetIntegerv(GL_VIEWPORT, @Rect);
624624 Result := Rect[3] - Rect[1];
625625 end;
626626```
627627
628628Nous récupérons juste la gauche /la droite, le haut/le bas et nous calculons la largeur/la hauteur en les soustrayant.
629629
630630Il doit y avoir des fonctions pour entrer et quitter le mode 2D :
631631
632632``` pascal
633633 procedure glEnter2D;
634634 begin
635635 glMatrixMode(GL_PROJECTION);
636636 glPushMatrix;
637637 glLoadIdentity;
638638 gluOrtho2D(0, glGetViewportWidth, 0, glGetViewportHeight);
639639
640640 glMatrixMode(GL_MODELVIEW);
641641 glPushMatrix;
642642 glLoadIdentity;
643643
644644 glDisable(GL_DEPTH_TEST);
645645 end;
646646
647647 procedure glLeave2D;
648648 begin
649649 glMatrixMode(GL_PROJECTION);
650650 glPopMatrix;
651651 glMatrixMode(GL_MODELVIEW);
652652 glPopMatrix;
653653
654654 glEnable(GL_DEPTH_TEST);
655655 end;
656656```
657657
658-Quand on entre dans le mode 2D, nous enregistrons les matrices en cours et paramétrons les matrices 2D en utilisant la fonction <b>gluOrtho2D</b>. De cette façon si nous dessinons quelque chose sur (un viewport de) 100, 100 cette chose sera dessinée sur exactement 100 Pixels à partir du bord gauche de la fenêtre, et 100 Pixels depuis le bord inférieur (le y positif est vers le haut). En outre , nous interdisons ZBuffer. De cette façon, le texte n'altèrera pas ZBuffer.
658+Quand on entre dans le mode 2D, nous enregistrons les matrices en cours et paramétrons les matrices 2D en utilisant la fonction gluOrtho2D. De cette façon si nous dessinons quelque chose sur (un viewport de) 100, 100 cette chose sera dessinée sur exactement 100 Pixels à partir du bord gauche de la fenêtre, et 100 Pixels depuis le bord inférieur (le y positif est vers le haut). En outre , nous interdisons ZBuffer. De cette façon, le texte n'altèrera pas ZBuffer.
659659
660660Le fait de quitter le mode 2D renvoie juste les anciennes matrices et autorise ZBuffer.
661661
662662Maintenant, nous pouvons créer la fonction pour dessiner du texte:
663663
664664``` pascal
665665 procedure glWrite(X, Y: GLfloat; Font: Pointer; Text: String);
666666 var
667667 I: Integer;
668668 begin
669669 glRasterPos2f(X, Y);
670670 for I := 1 to Length(Text) do
671671 glutBitmapCharacter(Font, Integer(Text[I]));
672672 end;
673673```
674674
675-<b>glutBitmapCharacter</b> peut dessiner seulement un caractère de la police de caractères choisie. Le premier paramètre est la police de caractères désirée (GLUT_BITMAP_9_BY_15, GLUT_BITMAP_8_BY_13, GLUT_BITMAP_TIMES_ROMAN_10, GLUT_BITMAP_TIMES_ROMAN_24, GLUT_BITMAP_HELVETICA_10, GLUT_BITMAP_HELVETICA_12 ou GLUT_BITMAP_HELVETICA_18) et l'autre paramètre est le caractère.
675+glutBitmapCharacter peut dessiner seulement un caractère de la police de caractères choisie. Le premier paramètre est la police de caractères désirée (GLUT_BITMAP_9_BY_15, GLUT_BITMAP_8_BY_13, GLUT_BITMAP_TIMES_ROMAN_10, GLUT_BITMAP_TIMES_ROMAN_24, GLUT_BITMAP_HELVETICA_10, GLUT_BITMAP_HELVETICA_12 ou GLUT_BITMAP_HELVETICA_18) et l'autre paramètre est le caractère.
676676
677-Le caractère sera dessiné à la position de trame en cours. Pour placer la position désirée de trame nous appelons la fonction <b>glRasterPos</b>. glRasterPos peut traiter des nombres et des types de paramètres différents juste comme la fonction glVertex. La coordonnée indiquée est transformée par les matrices modèle et de projection pour obtenir la coordonnée 2D là où sera la nouvelle position de trame. Depuis que nous sommes entrés dans le mode 2D , Les coordonnées X et Y sont les coordonnées 2D réelles où le dessin se produira .
677+Le caractère sera dessiné à la position de trame en cours. Pour placer la position désirée de trame nous appelons la fonction glRasterPos. glRasterPos peut traiter des nombres et des types de paramètres différents juste comme la fonction glVertex. La coordonnée indiquée est transformée par les matrices modèle et de projection pour obtenir la coordonnée 2D là où sera la nouvelle position de trame. Depuis que nous sommes entrés dans le mode 2D , Les coordonnées X et Y sont les coordonnées 2D réelles où le dessin se produira .
678678
679679Ces nouvelles fonctions vont rendre le dessin du texte très facile:
680680
681681``` pascal
682682 procedure DrawGLScene; cdecl;
683683 begin
684684 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
685685
686686 glLoadIdentity;
687687 glTranslatef(0, 0, -5);
688688 glRotatef(GetTotalTime * 10, 0, 0.5, 0.5);
689689
690690 glColor3f(1, 0, 0);
691691 glutSolidCube(2);
692692
693693 glEnter2D;
694694
695695 glColor3f(0.2, 0.8 + 0.2 * Sin(GetTotalTime * 5), 0);
696696 glWrite(20, glGetViewportHeight - 20, GLUT_BITMAP_8_BY_13,
697697 Format('OpenGL Tutorial :: Bitmap Fonts :: FPS - %.2f FPS', [FPS]));
698698
699699 glColor3f(1, 1, 1);
700700 glWrite(50, glGetViewportHeight - 60, GLUT_BITMAP_9_BY_15, 'GLUT_BITMAP_9_BY_15');
701701 glWrite(50, glGetViewportHeight - 90, GLUT_BITMAP_8_BY_13, 'GLUT_BITMAP_8_BY_13');
702702 glWrite(50, glGetViewportHeight - 120, GLUT_BITMAP_TIMES_ROMAN_10, 'GLUT_BITMAP_TIMES_ROMAN_10');
703703 glWrite(50, glGetViewportHeight - 150, GLUT_BITMAP_TIMES_ROMAN_24, 'GLUT_BITMAP_TIMES_ROMAN_24');
704704 glWrite(50, glGetViewportHeight - 180, GLUT_BITMAP_HELVETICA_10, 'GLUT_BITMAP_HELVETICA_10');
705705 glWrite(50, glGetViewportHeight - 210, GLUT_BITMAP_HELVETICA_12, 'GLUT_BITMAP_HELVETICA_12');
706706 glWrite(50, glGetViewportHeight - 240, GLUT_BITMAP_HELVETICA_18, 'GLUT_BITMAP_HELVETICA_18');
707707
708708 glColor3f(0.5, 0.5, 1);
709709 glWrite(
710710 glGetViewportWidth - glutBitmapLength(GLUT_BITMAP_9_BY_15, LazText) - 5,
711711 10, GLUT_BITMAP_9_BY_15, LazText);
712712
713713 glLeave2D;
714714
715715 glutSwapBuffers;
716716
717717 FrameRendered;
718718 end;
719719```
720720
721-![](/wiki-images/b/ba/BitmapFontsPic1.jpg) Nous dessinons un cube rouge et le faisons tourner, et un peu de texte pour montrer à quel point les diverses polices de caractères d'image ressemblent. La fonction <b>glutBitmapLength</b> est employée pour trouver la largeur des chaînes de caractères ainsi elles pourraient être alignées vers la droite. Le code peut facilement être changé pour centrer le texte .
721+![](/wiki-images/b/ba/BitmapFontsPic1.jpg) Nous dessinons un cube rouge et le faisons tourner, et un peu de texte pour montrer à quel point les diverses polices de caractères d'image ressemblent. La fonction glutBitmapLength est employée pour trouver la largeur des chaînes de caractères ainsi elles pourraient être alignées vers la droite. Le code peut facilement être changé pour centrer le texte .
722722
723723Note: Voir comment les cubes apparaissent sans lumière.
724724
725725Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
726726
727727# Textures
728728
729729Il est temps d'employer des textures :)
730730
731731Ce tutoriel montrera comment dessiner les polygones texturisés et comment mélanger des textures en utilisant une technique à plusieurs passages. Puisque OpenGL n'a aucun mécanisme interne pour télécharger des textures, nous emploierons une bibliothèque externe : [la bibliothèque Imaging de Vampyre](http://imaginglib.sourceforge.net/). Nous emploierons juste des fonctions d'aide d'OpenGL, mais vous pouvez trouver cette bibliothèque maniable pour aussi d'autres choses.
732732
733733Soyons prêt à démarrer... nous créerons une liste d'affichage pour dessiner un rectangle texturisé :
734734
735735``` pascal
736736 procedure CreateList;
737737 begin
738738 glNewList(LIST_OBJECT, GL_COMPILE);
739739 glBegin(GL_QUADS);
740740 glTexCoord2f(1, 0);
741741 glVertex3f( 2, 2, 0);
742742 glTexCoord2f(0, 0);
743743 glVertex3f(-2, 2, 0);
744744 glTexCoord2f(0, 1);
745745 glVertex3f(-2,-2, 0);
746746 glTexCoord2f(1, 1);
747747 glVertex3f( 2,-2, 0);
748748 glEnd;
749749 glEndList;
750750 end;
751751```
752752
753-Notez les fonctions <b>glTexCoord</b>. Elles sont utilisées pour indiquer quelle partie de la texture est assignée au sommet. Les coordonnées définies dans ces fonctions vont de 0 à 1 (Les valeurs supérieures à 1 sont permises mais peuvent produire des résultats différents). 0 est le premier Pixel et 1 est le dernier Pixel . Ainsi, 0.5 sera exactement au milieu de la texture.
753+Notez les fonctions glTexCoord. Elles sont utilisées pour indiquer quelle partie de la texture est assignée au sommet. Les coordonnées définies dans ces fonctions vont de 0 à 1 (Les valeurs supérieures à 1 sont permises mais peuvent produire des résultats différents). 0 est le premier Pixel et 1 est le dernier Pixel . Ainsi, 0.5 sera exactement au milieu de la texture.
754754
755755Le téléchargement de texture est extrêmement aisé avec la bibliothèque Imaging de Vampyre:
756756
757757``` pascal
758758 var
759759 Tex1, Tex2: GLuint;
760760
761761 procedure InitializeGL;
762762 begin
763763 glClearColor(0, 0, 0, 0);
764764 Tex1 := LoadGLTextureFromFile('ashwood.bmp');
765765 Tex2 := LoadGLTextureFromFile('Flare.bmp');
766766 glEnable(GL_TEXTURE_2D);
767767 end;
768768```
769769
770-<b>LoadGLTextureFromFile</b> charge une texture depuis un fichier et renvoie son ID. Quand la texture est chargée elle est déjà paramétrée pour le rendu. La dernière ligne autorise juste les textures 2D.
770+LoadGLTextureFromFile charge une texture depuis un fichier et renvoie son ID. Quand la texture est chargée elle est déjà paramétrée pour le rendu. La dernière ligne autorise juste les textures 2D.
771771
772772Pour dessiner un polygone texturisé vous devez lier la texture et paramétrer les coordonnées de texture(les coordonnées de texture sont fixées dans la liste d'affichage dans ce tutoriel):
773773
774774``` pascal
775775 ...
776776 glLoadIdentity;
777777 glTranslatef(-5, 0, -15);
778778 glBindTexture(GL_TEXTURE_2D, Tex1);
779779 glCallList(LIST_OBJECT);
780780 ...
781781```
782782
783-La fonction <b>glBindTexture</b> est employée pour choisir la texture. Quand vous dessinez des polygones ils auront la texture sélectionnée sur eux. C'est aussi simple :)
783+La fonction glBindTexture est employée pour choisir la texture. Quand vous dessinez des polygones ils auront la texture sélectionnée sur eux. C'est aussi simple :)
784784
785785Ainsi , employer une texture est facile ... mais comment mélanger deux textures . Fondamentalement vous dessinez le polygone une fois avec une texture, paramétrez les paramètres du mélange, et dessinez le polygone une fois de plus avec une autre texture. Vous pouvez mélanger des centaines de texture de cette façon. Voyons à quoi le code pour faire ceci ressemble :
786786
787787``` pascal
788788 ...
789789 glLoadIdentity;
790790 glTranslatef(5, 0, -15);
791791 glBindTexture(GL_TEXTURE_2D, Tex1);
792792 glCallList(LIST_OBJECT);
793793
794794 glEnable(GL_BLEND);
795795 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
796796 glLoadIdentity;
797797 glTranslatef(5, 0, -15);
798798 glBindTexture(GL_TEXTURE_2D, Tex2);
799799 glCallList(LIST_OBJECT);
800800 glDisable(GL_BLEND);
801801 ...
802802```
803803
804-Comme vous pouvez le voir , le polygone est dessiné la première fois comme nous le savons déjà. Avant le deuxième dessin nous permettons le mélange de textures en appelant la procédure <b>glEnable(GL_BLEND)</b>. Mélanger signifie que la couleur finale du Pixel est calculée comme ceci :
804+Comme vous pouvez le voir , le polygone est dessiné la première fois comme nous le savons déjà. Avant le deuxième dessin nous permettons le mélange de textures en appelant la procédure glEnable(GL_BLEND). Mélanger signifie que la couleur finale du Pixel est calculée comme ceci :
805805
806806`DrawingColor * SRCBLEND + BackgroundColor * DESTBLEND`
807807
808-SRCBLEND et DESTBLEND sont définis en utilisant la fonction <b>glBlendFunc</b>. Dans ce tutoriel nous paramétrons SRCBLEND à GL_ZERO (zero) et DESTBLENT à GL_SRC_COLOR (DrawingColor) et la couleur finale est alors:
808+SRCBLEND et DESTBLEND sont définis en utilisant la fonction glBlendFunc. Dans ce tutoriel nous paramétrons SRCBLEND à GL_ZERO (zero) et DESTBLENT à GL_SRC_COLOR (DrawingColor) et la couleur finale est alors:
809809
810810`DrawingColor * 0 + BackgroundColor * DrawingColor`
811811
812-<figure>
813-<img src="TexturesPic1.jpg" title="TexturesPic1.jpg" />
814-<figcaption>TexturesPic1.jpg</figcaption>
815-</figure>
812+![](/wiki-images/d/d4/TexturesPic1.jpg)
816813
817814Ceci signifie que l'arrière plan deviendra plus foncé quand vous dessinez avec des couleurs foncées ... quand vous dessinez avec de la couleur blanche , la couleur de l'arrière plan ne sera pas changée. Le résultat ressemblera à ceci
818815
819816La fois prochaine , nous utiliserons des extensions pour montrer comment utiliser le multitexturing en une passe.
820817
821818Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
822819
823820# Multitexturing (extensions)
824821
825822Quand vous connaissez le multitexturing en plusieurs passes, celui en une passe est très simple. Appliquer une texture est séparé en étapes. La première étape permet de paramétrer et de dessiner la première texture, la seconde étape en dessine une autre et ainsi de suite. Tous que vous devez faire est de paramétrer les étapes avec les textures et de faire le rendu de l'objet.
826823
827824Voyons à quoi le code ressemble :
828825
829826``` pascal
830827 procedure InitializeGL;
831828 begin
832829 Load_GL_ARB_multitexture;
833830 glClearColor(0, 0, 0, 0);
834831 Tex1 := LoadGLTextureFromFile('Lazarus.bmp');
835832 Tex2 := LoadGLTextureFromFile('Mask.bmp');
836833 glActiveTextureARB(GL_TEXTURE0_ARB);
837834 glEnable(GL_TEXTURE_2D);
838835 glBindTexture(GL_TEXTURE_2D, Tex1);
839836 glActiveTextureARB(GL_TEXTURE1_ARB);
840837 glEnable(GL_TEXTURE_2D);
841838 glBindTexture(GL_TEXTURE_2D, Tex2);
842839 end;
843840```
844841
845-D'abord nous avons besoin de l'extension OpenGL qui nous permettrons d'utiliser les fonctions de multitexture. <b>Load_GL_ARB_multitexture</b> essayera de charger ces extensions et renverra TRUE si l'opération est réussie.
842+D'abord nous avons besoin de l'extension OpenGL qui nous permettrons d'utiliser les fonctions de multitexture. Load_GL_ARB_multitexture essayera de charger ces extensions et renverra TRUE si l'opération est réussie.
846843
847-Pour choisir l'étape de texture sur laquelle vous voulez travailler, utilisez la fonction <b>glActiveTextureARB</b>. Elle demande seulement un paramètre qui défini l'étape que vous voulez. Après ça toutes les fonctions de texture (enabling, disabling, binding, creating...) affecteront cette étape .
844+Pour choisir l'étape de texture sur laquelle vous voulez travailler, utilisez la fonction glActiveTextureARB. Elle demande seulement un paramètre qui défini l'étape que vous voulez. Après ça toutes les fonctions de texture (enabling, disabling, binding, creating...) affecteront cette étape .
848845
849846Puisque nous avons paramétrés tout dans la fonction d'initialisation, tout que nous avons à faire est de dessiner l'objet :
850847
851848``` pascal
852849 procedure DrawGLScene; cdecl;
853850 begin
854851 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
855852
856853 glLoadIdentity;
857854 glTranslatef(0, 0, -5);
858855
859856 glBegin(GL_QUADS);
860857 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
861858 glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1, 0);
862859 glVertex3f(2.516, 2, 0);
863860 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
864861 glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0, 0);
865862 glVertex3f(-2.516, 2, 0);
866863 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
867864 glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0, 1);
868865 glVertex3f(-2.516,-2, 0);
869866 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
870867 glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1, 1);
871868 glVertex3f(2.516,-2, 0);
872869 glEnd;
873870
874871 glutSwapBuffers;
875872 end;
876873```
877874
878-![](/wiki-images/5/52/MultitexturePic1.jpg) Comme vous pouvez le voir, la différence est seulement dans la définitions des coordonnées de texture. Nous utilisons maintenant la fonction <b>glMultiTexCoord2fARB</b> qui prend l'étape de texture et les coordonnées de texture en paramètre. Tout le reste est inchangé.
875+![](/wiki-images/5/52/MultitexturePic1.jpg) Comme vous pouvez le voir, la différence est seulement dans la définitions des coordonnées de texture. Nous utilisons maintenant la fonction glMultiTexCoord2fARB qui prend l'étape de texture et les coordonnées de texture en paramètre. Tout le reste est inchangé.
879876
880877Aujourd'hui presque toutes les cartes graphiques supportent au moins 2 étapes de texture . L'utilisation du multitexturing en une passe est plus rapide que la version multipasse puisque vous dessinez les objets une seule fois. Si le matériel supporte le multitexturing en une passe (Load_GL_ARB_multitexture renvoie TRUE) utilisez le.
881878
882879Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
883880
884881# Faire du rendu pour obtenir une texture
885882
886883Ce paragraphe sera court. OpenGL peut capturer la scène courante pour en faire une texture ainsi vous pouvez l'employer pour appliquer une texture sur d'autres objets (écran TV , miroir ou quelque chose d'autre). Bien faisons immédiatement un rendu de scène vers une texture et appliquons la à un plan rotatif.
887884
888885D'abord, nous devons créer une texture vide qui est bien utilisée pour capturer la scène:
889886
890887``` pascal
891888 procedure SetupRenderTexture;
892889 var
893890 Data: Pointer;
894891 begin
895892 GetMem(Data, 256*256*3);
896893 glGenTextures(1, @RenderTexture);
897894 glBindTexture(GL_TEXTURE_2D, RenderTexture);
898895 glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);
899896 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
900897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
901898 FreeMem(Data);
902899 end;
903900```
904901
905902La mémoire tampon de l'image RGB 256*256 pixels est crée et elle est utilisée pour paramétrer la texture 2D.
906903
907904La partie principale est dans la fonction de dessin:
908905
909906``` pascal
910907 procedure DrawGLScene; cdecl;
911908 var
912909 TotalTime: Single;
913910 begin
914911 glClearColor(0, 0, 0, 0);
915912 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
916913 glEnable(GL_LIGHTING);
917914 glDisable(GL_TEXTURE_2D);
918915 glViewport(0, 0, 256, 256);
919916
920917 TotalTime := GetTotalTime;
921918
922919 glLoadIdentity;
923920 glTranslatef(0, 0, -5);
924921 glRotatef(50 * TotalTime, 1, 0, 0);
925922 glRotatef(100 * TotalTime, 0, 1, 0);
926923 glRotatef(50 * TotalTime, 0, 0, 1);
927924
928925 glColor3f(1, 1, 1);
929926 glutSolidCube(2);
930927
931928 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 256, 256, 0);
932929
933930 glClearColor(0.18, 0.20, 0.66, 0);
934931 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
935932 glDisable(GL_LIGHTING);
936933 glEnable(GL_TEXTURE_2D);
937934 glViewport(0, 0, AppWidth, AppHeight);
938935
939936 glLoadIdentity;
940937 glTranslatef(0, 0, -7);
941938 glRotatef(20 * TotalTime, 1, 0, 0);
942939 glRotatef(50 * TotalTime, 0, 1, 0);
943940
944941 glBegin(GL_QUADS);
945942 glTexCoord2f(1, 0);
946943 glVertex3f(2, 2, 0);
947944 glTexCoord2f(0, 0);
948945 glVertex3f(-2, 2, 0);
949946 glTexCoord2f(0, 1);
950947 glVertex3f(-2,-2, 0);
951948 glTexCoord2f(1, 1);
952949 glVertex3f(2,-2, 0);
953950 glEnd;
954951
955952 glutSwapBuffers;
956953 end;
957954```
958955
959-![](/wiki-images/6/6e/RenderToTexturePic1.jpg) D'abord, tout est paramétré pour la scène qui sera capturée. La fenêtre de clôture(Viewport)est réduite à 256*256 de telle façon qu'elle s'adapte à la texture et la scène est dessinée . <b>glCopyTexImage2D</b> est employé pour capturer la scène à la texture actuellement choisie .
956+![](/wiki-images/6/6e/RenderToTexturePic1.jpg) D'abord, tout est paramétré pour la scène qui sera capturée. La fenêtre de clôture(Viewport)est réduite à 256*256 de telle façon qu'elle s'adapte à la texture et la scène est dessinée . glCopyTexImage2D est employé pour capturer la scène à la texture actuellement choisie .
960957
961958Quand nous avons capturé la scène vers la texture, tout peut être effacé à nouveau, La fenêtre de clôture(viewport) peut se remettre à sa taille d'origine et la scène finale est dessinée en utilisant la scène précédente comme texture.
962959
963-P.S. une texture capturée peut être enregistrée en utilisant la fonction <b>SaveGLTextureToFile</b> de la bibliothèque [Imaging de Vampyre](http://imaginglib.sourceforge.net/).
960+P.S. une texture capturée peut être enregistrée en utilisant la fonction SaveGLTextureToFile de la bibliothèque [Imaging de Vampyre](http://imaginglib.sourceforge.net/).
964961
965962Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
966963
967964# Tableau de Sommets
968965
969966OpenGL est capable de faire le rendu de primitives en utilisant les données qui sont stockées dans les mémoires tampons au lieu d'appeler glVertex. Les mémoires tampons peuvent être appelées pour définir les coordonnées des sommets et celles des textures, et les couleurs (index et RGBA), les drapeaux normaux et de bord.
970967
971968Dans ce tutoriel nous utiliserons seulement les mémoires tampon de sommet et de couleur, et nous montrerons du dessin non-indexé et indexé. le mode non-indexé dessine des mémoires tampon en tant que flux. Le mode indexé dessinera des éléments de la mémoire tampon dans l'ordre dans lequel cela a été défini dans l'index de la mémoire tampon. Mais assez parlé... Commençons à coder.
972969
973970D'abord, définissons quelques types et constantes :
974971
975972``` pascal
976973 type
977974 TVertex3f = record
978975 X, Y, Z: Single;
979976 end;
980977
981978 TColor3f = record
982979 R, G, B: Single;
983980 end;
984981
985982 VertexBuffer: array [0..5] of TVertex3f = (
986983 (X : 1; Y : 1; Z : 0),
987984 (X : -1; Y : 1; Z : 0),
988985 (X : -1; Y : -1; Z : 0),
989986 (X : 1; Y : 1; Z : 0),
990987 (X : -1; Y : -1; Z : 0),
991988 (X : 1; Y : -1; Z : 0)
992989 );
993990 ColorBuffer: array [0..5] of TColor3f = (
994991 (R : 1; G : 0; B : 1),
995992 (R : 0; G : 0; B : 1),
996993 (R : 0; G : 1; B : 0),
997994 (R : 1; G : 0; B : 1),
998995 (R : 0; G : 1; B : 0),
999996 (R : 1; G : 1; B : 0)
1000997 );
1001998```
1002999
10031000Nous avons deux mémoires tampon. Une pour les coordonnées des sommets et une pour les couleurs des sommets. Ces 6 sommets définissent 2 triangles qui forment un rectangle.
10041001
10051002Dessiner des primitives en utilisant les mémoires tampons est facile:
10061003
10071004``` pascal
10081005 glEnableClientState(GL_VERTEX_ARRAY);
10091006 glEnableClientState(GL_COLOR_ARRAY);
10101007 glVertexPointer(3, GL_FLOAT, 0, @VertexBuffer[0]);
10111008 glColorPointer(3, GL_FLOAT, 0, @ColorBuffer[0]);
10121009
10131010 glDrawArrays(GL_TRIANGLES, 0, Length(VertexBuffer));
10141011
10151012 glDisableClientState(GL_VERTEX_ARRAY);
10161013 glDisableClientState(GL_COLOR_ARRAY);
10171014```
10181015
1019-D'abord nous autorisons les mémoires tampon que nous voulons employer en utilisant la fonction <b>glEnableClientState</b>. Ensuite nous pouvons sélectionner les mémoires tampons que nous voulons utiliser. Chaque type de mémoire tampon a une fonction propre pour cette sélection (<b>glColorPointer</b>, <b>glEdgeFlagPointer</b>, <b>glIndexPointer</b>, <b>glNormalPointer</b>, <b>glTexCoordPointer</b>, <b>glVertexPointer</b>). Le premier paramètre de ces fonctions défini combien de nombres chaque élément contient. Par exemple , prenons la mémoire tampon des sommets. Si ce paramètre est 2 alors OpenGL compte que chaque élément de la mémoire tampon contienne les coordonnées x et y. Si ce paramètre est , par exemple , 4, alors chaque élément devrait contenir les coordonnées x, y, z et w. Le paramètre suivant défini quel type d'élément de donnée la mémoire tampon contient (GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT ou GL_DOUBLE). Le suivant défini combien il y a d'octets entre chaque élément. De cette façon, vous pouvez avoir une mémoire tampon qui contient des coordonnées de sommets et quelques données faites sur commande. Pour des types de données arbitraire, ce paramètre peut être calculé ainsi:
1016+D'abord nous autorisons les mémoires tampon que nous voulons employer en utilisant la fonction glEnableClientState. Ensuite nous pouvons sélectionner les mémoires tampons que nous voulons utiliser. Chaque type de mémoire tampon a une fonction propre pour cette sélection (glColorPointer, glEdgeFlagPointer, glIndexPointer, glNormalPointer, glTexCoordPointer, glVertexPointer). Le premier paramètre de ces fonctions défini combien de nombres chaque élément contient. Par exemple , prenons la mémoire tampon des sommets. Si ce paramètre est 2 alors OpenGL compte que chaque élément de la mémoire tampon contienne les coordonnées x et y. Si ce paramètre est , par exemple , 4, alors chaque élément devrait contenir les coordonnées x, y, z et w. Le paramètre suivant défini quel type d'élément de donnée la mémoire tampon contient (GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT ou GL_DOUBLE). Le suivant défini combien il y a d'octets entre chaque élément. De cette façon, vous pouvez avoir une mémoire tampon qui contient des coordonnées de sommets et quelques données faites sur commande. Pour des types de données arbitraire, ce paramètre peut être calculé ainsi:
10201017
10211018``` pascal
10221019 type
10231020 TBufferData = record
10241021 DataBefore: TDataBefore;
10251022 Vertex: TVertex;
10261023 DataAfter: TDataAfter;
10271024 end;
10281025
10291026 Bytes between elements = SizeOf(TDataBefore) + SizeOf(TDataAfter)
10301027```
10311028
10321029Le dernier paramètre est un pointeur vers le début de la mémoire tampon.
10331030
1034-Quand les mémoires tampons sont sélectionnées, nous pouvons les dessiner employant les fonctions <b>glDrawArrays</b>. Toutes les mémoires tampons autorisées sont utilisées pour dessiner les primitives. Le genre de polygones qui sont générés est défini dans le premier paramètre (pareil que avec la fonction glBegin). Les deux paramètres suivant définissent le sous-ensemble de mémoire tampon qui est utilisé pour dessiner (début et compte).
1031+Quand les mémoires tampons sont sélectionnées, nous pouvons les dessiner employant les fonctions glDrawArrays. Toutes les mémoires tampons autorisées sont utilisées pour dessiner les primitives. Le genre de polygones qui sont générés est défini dans le premier paramètre (pareil que avec la fonction glBegin). Les deux paramètres suivant définissent le sous-ensemble de mémoire tampon qui est utilisé pour dessiner (début et compte).
10351032
10361033Quand les mémoires tampons ne sont pas nécessaires vous pouvez les neutraliser .
10371034
10381035Pour démontrer le mode indexé, j'ai réalisé un classe de maillage simple qui peut charger des sommet, des couleurs et indexer les données depuis des fichiers externes:
10391036
10401037``` pascal
10411038 type
10421039 TMesh = class
10431040 private
10441041 FVertices: array of TVertex3f;
10451042 FColors: array of TColor3f;
10461043 FIndices: array of Integer;
10471044 procedure FreeBuffers;
10481045 public
10491046 constructor Create;
10501047 destructor Destroy; override;
10511048 procedure LoadMesh(FileName: String);
10521049 procedure DrawMesh;
10531050 end;
10541051```
10551052
10561053FVertices contiendra les données sur les sommets , FColors les données sur les couleurs et FIndices les données sur les index quand le fichier externe est chargé.
10571054
10581055D'abord, nous écrirons du code qui traite la création et la destruction de classe:
10591056
10601057``` pascal
10611058 procedure TMesh.FreeBuffers;
10621059 begin
10631060 FVertices := nil;
10641061 FColors := nil;
10651062 FIndices := nil;
10661063 end;
10671064
10681065 constructor TMesh.Create;
10691066 begin
10701067 FreeBuffers;
10711068 end;
10721069
10731070 destructor TMesh.Destroy;
10741071 begin
10751072 FreeBuffers;
10761073 inherited Destroy;
10771074 end;
10781075```
10791076
10801077Le fichier qui contiendra les données de maillage est un simple fichier texte. La première ligne contiendra le nombre de sommets et les index séparés par un espace. Après cette ligne viendra les lignes pour chaque sommet et couleur. X, Y, Z, R, G et B toutes séparées par un espace. A la fin, il y aura les lignes des index... chaque nombre représentant un index est écrit dans sa propre ligne... ainsi , pour un triangle, le fichier de données ressemblera à ceci:
10811078
10821079`3 3`\
10831080`-1 -1 0 1 1 1`\
10841081`1 -1 0 1 1 1`\
10851082`0 1 0 1 1 1`\
10861083`0`\
10871084`1`\
10881085`2`
10891086
10901087Cela signifie qu'il y a 3 sommets et 3 index défini dans le fichier. Le premier sommer est à la position -1, -1, 0 et a comme couleur RGB 1, 1, 1 et ainsi de suite . Les index définissent cet ordre dans lequel les sommets sont dessinés (dans ce cas-ci les sommets sont dessinés dans le même ordre qu'ils sont défini ).
10911088
10921089Le code pour charger ces données ressemblera à celui-ci:
10931090
10941091``` pascal
10951092 procedure TMesh.LoadMesh(FileName: String);
10961093 var
10971094 MeshFile: TextFile;
10981095 VertexCount, IndexCount: Integer;
10991096 iV, iI: Integer;
11001097 begin
11011098 FreeBuffers;
11021099
11031100 AssignFile(MeshFile, FileName);
11041101 Reset(MeshFile);
11051102
11061103 ReadLn(MeshFile, VertexCount, IndexCount);
11071104
11081105 SetLength(FVertices, VertexCount);
11091106 SetLength(FColors, VertexCount);
11101107 SetLength(FIndices, IndexCount);
11111108
11121109 for iV := 0 to VertexCount - 1 do
11131110 ReadLn(MeshFile,
11141111 FVertices[iV].X, FVertices[iV].Y, FVertices[iV].Z,
11151112 FColors[iV].R, FColors[iV].G, FColors[iV].B);
11161113
11171114 for iI := 0 to IndexCount - 1 do
11181115 ReadLn(MeshFile, FIndices[iI]);
11191116
11201117 CloseFile(MeshFile);
11211118 end;
11221119```
11231120
11241121Après le chargement des données, nous avons tout pour faire le dessin :
11251122
11261123``` pascal
11271124 procedure TMesh.DrawMesh;
11281125 begin
11291126 glEnableClientState(GL_VERTEX_ARRAY);
11301127 glEnableClientState(GL_COLOR_ARRAY);
11311128 glVertexPointer(3, GL_FLOAT, 0, @FVertices[0]);
11321129 glColorPointer(3, GL_FLOAT, 0, @FColors[0]);
11331130
11341131 glDrawElements(GL_TRIANGLES, Length(FIndices), GL_UNSIGNED_INT, @FIndices[0]);
11351132
11361133 glDisableClientState(GL_VERTEX_ARRAY);
11371134 glDisableClientState(GL_COLOR_ARRAY);
11381135 end;
11391136```
11401137
1141-![](/wiki-images/7/77/VertexArrayPic1.jpg)Comme vous pouvez le voir, presque tout est identique que faire un dessin non indexé, excepté la fonction qui dessine actuellement les polygones. Dans ce cas nous employons la fonction <b>glDrawElements</b>. Pour celle-ci, nous indiquons quel genre de polygones nous voulons, combien d'index sont dans la mémoire tampon, le type de données dans l'index de la mémoire tampon et un pointeur vers le début de l'index de la mémoire tampon.
1138+![](/wiki-images/7/77/VertexArrayPic1.jpg)Comme vous pouvez le voir, presque tout est identique que faire un dessin non indexé, excepté la fonction qui dessine actuellement les polygones. Dans ce cas nous employons la fonction glDrawElements. Pour celle-ci, nous indiquons quel genre de polygones nous voulons, combien d'index sont dans la mémoire tampon, le type de données dans l'index de la mémoire tampon et un pointeur vers le début de l'index de la mémoire tampon.
11421139
11431140Le code source complet vient avec le fichier de données de maillage que cette classe peut employer pour générer un rectangle qui est identique à celui qui est dessiné en utilisant le mode non-indexé. Le fichier de données de maillage ressemble à ceci:
11441141
11451142`4 6`\
11461143`1 1 0 1 0 1`\
11471144`-1 1 0 0 0 1`\
11481145`-1 -1 0 0 1 0`\
11491146`1 -1 0 1 1 0`\
11501147`0`\
11511148`1`\
11521149`2`\
11531150`0`\
11541151`2`\
11551152`3`
11561153
11571154Comme vous pouvez le voir, il y a des données pour seulement 4 sommets et 6 index. Ainsi, le premier triangle est défini par les sommets 0, 1 et 2, et le second par les sommets 0, 2 et 3. En utilisant le mode indexé, nous n'avons pas à dupliquer les sommets.
11581155
11591156Téléchargez le code source, l'exécutable linux ou l'exécutable windows depuis [le dépôt Lazarus CCR de SourceForge](http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=199145).
11601157
11611158---
11621159*From the Free Pascal wiki, page "OpenGL Tutorial/fr", as it stood on 2020-02-23 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history