diff options
author | julieng <julien.gattelier@gmail.com> | 2021-10-02 17:20:24 +0200 |
---|---|---|
committer | SphinxKnight <SphinxKnight@users.noreply.github.com> | 2021-10-02 17:30:20 +0200 |
commit | 1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde (patch) | |
tree | 30a56efd3eff3a01bd1611e1840fdbbfacf544a4 /files/fr/web/api/webgl_api/tutorial | |
parent | c05efa8d7ae464235cf83d7c0956e42dc6974103 (diff) | |
download | translated-content-1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde.tar.gz translated-content-1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde.tar.bz2 translated-content-1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde.zip |
convert content to md
Diffstat (limited to 'files/fr/web/api/webgl_api/tutorial')
9 files changed, 753 insertions, 770 deletions
diff --git a/files/fr/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md b/files/fr/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md index 2369abb5e4..4beb39300e 100644 --- a/files/fr/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md +++ b/files/fr/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md @@ -15,294 +15,285 @@ tags: translation_of: Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context original_slug: Web/API/WebGL_API/Tutorial/Ajouter_du_contenu_à_WebGL --- -<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}}</p> +{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}} -<p>Une fois que vous avez correctement créé un contexte WebGL, vous pouvez commencer à y dessiner. Une chose simple que nous pouvons faire est de dessiner un simple carré 2D sans texture, commençons donc par là, en construisant un code pour dessiner un carré 2D.</p> +Une fois que vous avez correctement créé un contexte WebGL, vous pouvez commencer à y dessiner. Une chose simple que nous pouvons faire est de dessiner un simple carré 2D sans texture, commençons donc par là, en construisant un code pour dessiner un carré 2D. -<h2 id="Dessiner_la_scène">Dessiner la scène</h2> +## Dessiner la scène -<p>La chose la plus importante à comprendre avant que nous ne commencions est que, bien que nous dessinions seulement un carré 2D dans cet exemple, nous sommes toujours en train de dessiner dans un espace 3D. Nous dessinons juste un carré et nous le mettons exactement en face de la caméra, perpendiculairement à la direction de vision. Nous avons besoin de définir les shaders qui créeront la couleur pour notre scène simple, et qui dessineront notre objet. Cela définira comment notre carré 2D apparaîtra à l'écran.</p> +La chose la plus importante à comprendre avant que nous ne commencions est que, bien que nous dessinions seulement un carré 2D dans cet exemple, nous sommes toujours en train de dessiner dans un espace 3D. Nous dessinons juste un carré et nous le mettons exactement en face de la caméra, perpendiculairement à la direction de vision. Nous avons besoin de définir les shaders qui créeront la couleur pour notre scène simple, et qui dessineront notre objet. Cela définira comment notre carré 2D apparaîtra à l'écran. -<h3 id="Les_shaders">Les shaders</h3> +### Les shaders -<p>Un shader est un programme, écrit en utilisant le <a href="https://www.khronos.org/files/opengles_shading_language.pdf">OpenGL ES Shading Language</a> (GLSL), qui utilise les informations des sommets constituant une forme, et qui génère les données nécessaires pour faire un rendu des pixels à l'écran : nommément, les positions des pixels et leurs couleurs.</p> +Un shader est un programme, écrit en utilisant le [OpenGL ES Shading Language](https://www.khronos.org/files/opengles_shading_language.pdf) (GLSL), qui utilise les informations des sommets constituant une forme, et qui génère les données nécessaires pour faire un rendu des pixels à l'écran : nommément, les positions des pixels et leurs couleurs. -<p>Deux fonctions de shader sont exécutées lors du dessin d'un contenu WebGL : le <strong>shader de sommet</strong> et le <strong>shader de fragment</strong>. Vous les écrivez en GLSL et vous passez le texte du code à WebGL pour qu'il soit compilé pour exécution dans la GPU. Pris conjointement, un ensemble de shaders de sommet et de fragment sont appelés un <strong>programme shader</strong>.</p> +Deux fonctions de shader sont exécutées lors du dessin d'un contenu WebGL : le **shader de sommet** et le **shader de fragment**. Vous les écrivez en GLSL et vous passez le texte du code à WebGL pour qu'il soit compilé pour exécution dans la GPU. Pris conjointement, un ensemble de shaders de sommet et de fragment sont appelés un **programme shader**. -<p>Jetons un coup d'œil rapide aux deux types de shaders, en gardant présent à l'esprit l'exemple du dessin d'une forme 2D dans le contexte WebGL.</p> +Jetons un coup d'œil rapide aux deux types de shaders, en gardant présent à l'esprit l'exemple du dessin d'une forme 2D dans le contexte WebGL. -<h4 id="Le_shader_de_sommet">Le shader de sommet</h4> +#### Le shader de sommet -<p>Chaque fois qu'une forme est rendue, le shader de sommet est exécuté pour chaque sommet de la forme. Son travail consiste à effectuer les transformations souhaitées sur la position du sommet.</p> +Chaque fois qu'une forme est rendue, le shader de sommet est exécuté pour chaque sommet de la forme. Son travail consiste à effectuer les transformations souhaitées sur la position du sommet. -<p>Les informations de position sont stockées dans une variable spéciale fournie par GLSL, appelée <code>gl_Position</code>.</p> +Les informations de position sont stockées dans une variable spéciale fournie par GLSL, appelée `gl_Position`. -<p>Le shader de sommet peut, au besoin, aussi faire des choses comme déterminer les coordonnées dans la texture des faces du {{interwiki ("wikipedia", "texel")}} à appliquer au sommet, appliquer les normales pour déterminer le facteur d'éclairage à appliquer au sommet, et ainsi de suite. Ces informations peuvent alors être stockées dans des variations ou des attributs comme approprié, pour être partagées avec le shader de fragment.</p> +Le shader de sommet peut, au besoin, aussi faire des choses comme déterminer les coordonnées dans la texture des faces du {{interwiki ("wikipedia", "texel")}} à appliquer au sommet, appliquer les normales pour déterminer le facteur d'éclairage à appliquer au sommet, et ainsi de suite. Ces informations peuvent alors être stockées dans des variations ou des attributs comme approprié, pour être partagées avec le shader de fragment. -<p>Notre shader de sommet ci-dessous reçoit des valeurs de position de sommet à partir d'un attribut que nous définissons, appelé <code>aVertexPosition</code>. Cette position est ensuite multipliée par deux matrices 4x4 que nous fournissons, appelées <code>uProjectionMatrix</code> et <code>uModelMatrix</code> ; <code>gl_Position</code> est définie comme étant le résultat. Pour plus d'informations sur la projection et autres matrices, <a href="https://webglfundamentals.org/webgl/lessons/webgl-3d-perspective.html">vous pourriez trouver cet article utile</a>.</p> +Notre shader de sommet ci-dessous reçoit des valeurs de position de sommet à partir d'un attribut que nous définissons, appelé `aVertexPosition`. Cette position est ensuite multipliée par deux matrices 4x4 que nous fournissons, appelées `uProjectionMatrix` et `uModelMatrix` ; `gl_Position` est définie comme étant le résultat. Pour plus d'informations sur la projection et autres matrices, [vous pourriez trouver cet article utile](https://webglfundamentals.org/webgl/lessons/webgl-3d-perspective.html). -<pre><code>// Programme shader de sommet + // Programme shader de sommet -const vsSource = ` - attribute vec4 aVertexPosition; + const vsSource = ` + attribute vec4 aVertexPosition; - uniform mat4 uModelViewMatrix; - uniform mat4 uProjectionMatrix; + uniform mat4 uModelViewMatrix; + uniform mat4 uProjectionMatrix; - void main() { - gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; - } -`;</code></pre> + void main() { + gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; + } + `; -<p>Dans cet exemple, nous ne calculons pas d'éclairage du tout, puisque nous n'en avons pas encore appliqué à la scène. Cela viendra plus tard, dans l'exemple <a href="/fr-FR/docs/Web/API/WebGL_API/Tutorial/Lighting_in_WebGL">Éclairage en WebGL</a>. Notez également l'absence de tout travail sur les textures ici ; cela sera ajouté dans <a href="/fr-FR/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL">Utilisation de textures en WebGL</a>.</p> +Dans cet exemple, nous ne calculons pas d'éclairage du tout, puisque nous n'en avons pas encore appliqué à la scène. Cela viendra plus tard, dans l'exemple [Éclairage en WebGL](/fr-FR/docs/Web/API/WebGL_API/Tutorial/Lighting_in_WebGL). Notez également l'absence de tout travail sur les textures ici ; cela sera ajouté dans [Utilisation de textures en WebGL](/fr-FR/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL). -<h4 id="Le_shader_de_fragment">Le shader de fragment</h4> +#### Le shader de fragment -<p>Le <strong>shader de fragment</strong> est appelé une fois pour chaque pixel de chaque forme à dessiner, une fois que les sommets de la forme ont été traités par le shader de sommet. Son travail consiste à déterminer la couleur de ce pixel en déterminant quel texel (c'est-à-dire le pixel de la texture de la forme) appliquer au pixel, à obtenir la couleur de ce texel, puis à appliquer l'éclairage approprié à la couleur. La couleur est ensuite renvoyée à la couche WebGL en la stockant dans la variable spéciale <code>gl_FragColor</code>. Cette couleur est alors dessinée à l'écran dans la position correcte pour le pixel correspondant de la forme.</p> +Le **shader de fragment** est appelé une fois pour chaque pixel de chaque forme à dessiner, une fois que les sommets de la forme ont été traités par le shader de sommet. Son travail consiste à déterminer la couleur de ce pixel en déterminant quel texel (c'est-à-dire le pixel de la texture de la forme) appliquer au pixel, à obtenir la couleur de ce texel, puis à appliquer l'éclairage approprié à la couleur. La couleur est ensuite renvoyée à la couche WebGL en la stockant dans la variable spéciale `gl_FragColor`. Cette couleur est alors dessinée à l'écran dans la position correcte pour le pixel correspondant de la forme. -<p>Dans ce cas, nous retournons simplement du blanc à chaque fois, car nous sommes seulement en train de dessiner un carré blanc, sans éclairage.</p> +Dans ce cas, nous retournons simplement du blanc à chaque fois, car nous sommes seulement en train de dessiner un carré blanc, sans éclairage. -<pre><code> const fsSource = ` - void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); - } - `;</code> -</pre> - -<h3 id="Initialisation_des_shaders">Initialisation des shaders</h3> - -<p>Maintenant que nous avons défini les deux shaders, nous devons les transmettre à WebGL, les compiler et les lier ensemble. Le code ci-dessous crée les deux shaders en appelant <code>loadShader()</code>, lui passant le type et la source du shader. Il crée alors un programme, attache les shaders et les relie ensemble. Si la compilation ou la liaison échoue, le code affiche une alerte.</p> - -<pre><code>// -// Initialiser un programme shader, de façon à ce que WebGL sache comment dessiner nos données -// -function initShaderProgram(gl, vsSource, fsSource) { - const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); - const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); - - // Créer le programme shader + const fsSource = ` + void main() { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + `; - const shaderProgram = gl.createProgram(); - gl.attachShader(shaderProgram, vertexShader); - gl.attachShader(shaderProgram, fragmentShader); - gl.linkProgram(shaderProgram); +### Initialisation des shaders - // Si la création du programme shader a échoué, alerte +Maintenant que nous avons défini les deux shaders, nous devons les transmettre à WebGL, les compiler et les lier ensemble. Le code ci-dessous crée les deux shaders en appelant `loadShader()`, lui passant le type et la source du shader. Il crée alors un programme, attache les shaders et les relie ensemble. Si la compilation ou la liaison échoue, le code affiche une alerte. - if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - alert('Impossible d'initialiser le programme shader : ' + gl.getProgramInfoLog(shaderProgram)); - return null; - } + // + // Initialiser un programme shader, de façon à ce que WebGL sache comment dessiner nos données + // + function initShaderProgram(gl, vsSource, fsSource) { + const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); + const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); - return shaderProgram; -} + // Créer le programme shader -// -// Crée un shader du type fourni, charge le source et le compile. -// -function loadShader(gl, type, source) { - const shader = gl.createShader(type); + const shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); + gl.attachShader(shaderProgram, fragmentShader); + gl.linkProgram(shaderProgram); - // Envoyer le source à l'objet shader + // Si la création du programme shader a échoué, alerte - gl.shaderSource(shader, source); + if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { + alert('Impossible d'initialiser le programme shader : ' + gl.getProgramInfoLog(shaderProgram)); + return null; + } - // Compiler le programme shader + return shaderProgram; + } - gl.compileShader(shader); + // + // Crée un shader du type fourni, charge le source et le compile. + // + function loadShader(gl, type, source) { + const shader = gl.createShader(type); - // Vérifier s'il a ét compilé avec succès + // Envoyer le source à l'objet shader - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader)); - gl.deleteShader(shader); - return null; - } + gl.shaderSource(shader, source); - return shader; -}</code></pre> + // Compiler le programme shader -<p>La fonction <code>loadShader()</code> prend en entrée le contexte WebGL, le type de shader et le code source, puis crée et compile le shader comme suit :</p> + gl.compileShader(shader); -<ol> - <li>un nouveau shader est créé en appelant {{domxref("WebGLRenderingContext.createShader", "gl.createShader()")}} ;</li> - <li>le code source du shader est envoyé au shader en appelant {{domxref("WebGLRenderingContext.shaderSource", "gl.shaderSource()")}} ;</li> - <li>une fois que le shader a le code source, il est compilé en utilisant {{domxref("WebGLRenderingContext.compileShader", "gl.compileShader()")}} ;</li> - <li>pour vérifier que le shader a été compilé avec succès, le paramètre <code>gl.COMPILE_STATUS</code> du shader est vérifié ; pour obtenir sa valeur, nous appelons {{domxref("WebGLRenderingContext.getShaderParameter", "gl.getShaderParameter()")}}, en indiquant le shader et le nom du paramètre que nous voulons vérifier (<code>gl.COMPILE_STATUS</code>) ; si c'est <code>false</code>, nous savons que le shader n'a pas pu être compilé, aussi nous affichons une alerte avec les informations du journalisation obtenues du compilateur en utilisant {{domxref ("WebGLRenderingContext.getShaderInfoLog", "gl.getShaderInfoLog()")}}, puis nous supprimons le shader et nous renvoyons <code>null</code> pour indiquer l'échec du chargement du shader ;</li> - <li>si le shader a été chargé et compilé avec succès, le shader compilé est renvoyé à l'appelant.</li> -</ol> + // Vérifier s'il a ét compilé avec succès -<p>Pour utiliser ce code, nous l'appelons de la façon suivante :</p> + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader)); + gl.deleteShader(shader); + return null; + } -<pre><code> const shaderProgram = initShaderProgram(gl, vsSource, fsSource);</code> -</pre> + return shader; + } -<p>Après avoir créé un programme de shaders, nous devons rechercher les emplacements que WebGL a assignés à nos entrées. Dans ce cas, nous avons un attribut et deux uniformes. Les attributs reçoivent des valeurs des tampons. Chaque itération du shader des sommets reçoit la valeur suivante du tampon affecté à cet attribut. Les uniformes sont similaires aux variables globales JavaScript. Ils conservent la même valeur pour toutes les itérations d'un shader. Du fait que les attributs et les emplacements des uniformes sont spécifiques à un programme de shader donné, nous les stockerons ensemble pour les rendre plus faciles à transmettre.</p> +La fonction `loadShader()` prend en entrée le contexte WebGL, le type de shader et le code source, puis crée et compile le shader comme suit : -<pre><code> const programInfo = { - program: shaderProgram, - attribLocations: { - vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), - }, - uniformLocations: { - projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), - modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), - }, - };</code> -</pre> +1. un nouveau shader est créé en appelant {{domxref("WebGLRenderingContext.createShader", "gl.createShader()")}} ; +2. le code source du shader est envoyé au shader en appelant {{domxref("WebGLRenderingContext.shaderSource", "gl.shaderSource()")}} ; +3. une fois que le shader a le code source, il est compilé en utilisant {{domxref("WebGLRenderingContext.compileShader", "gl.compileShader()")}} ; +4. pour vérifier que le shader a été compilé avec succès, le paramètre `gl.COMPILE_STATUS` du shader est vérifié ; pour obtenir sa valeur, nous appelons {{domxref("WebGLRenderingContext.getShaderParameter", "gl.getShaderParameter()")}}, en indiquant le shader et le nom du paramètre que nous voulons vérifier (`gl.COMPILE_STATUS`) ; si c'est `false`, nous savons que le shader n'a pas pu être compilé, aussi nous affichons une alerte avec les informations du journalisation obtenues du compilateur en utilisant {{domxref ("WebGLRenderingContext.getShaderInfoLog", "gl.getShaderInfoLog()")}}, puis nous supprimons le shader et nous renvoyons `null` pour indiquer l'échec du chargement du shader ; +5. si le shader a été chargé et compilé avec succès, le shader compilé est renvoyé à l'appelant. -<h2 id="Création_du_carré_2D">Création du carré 2D</h2> +Pour utiliser ce code, nous l'appelons de la façon suivante : -<p>Avant de pouvoir faire un rendu de notre carré 2D, nous devons créer le tampon qui contiendra les positions de ses sommets et y placer les positions des sommets. Nous ferons cela en utilisant une fonction que nous appelerons <code>initBuffers()</code> ; à mesure que nous explorerons des concepts WebGL plus avancés, cette routine sera augmentée pour créer plus d'objets 3D, et plus complexes.</p> + const shaderProgram = initShaderProgram(gl, vsSource, fsSource); -<pre><code>function initBuffers(gl) { +Après avoir créé un programme de shaders, nous devons rechercher les emplacements que WebGL a assignés à nos entrées. Dans ce cas, nous avons un attribut et deux uniformes. Les attributs reçoivent des valeurs des tampons. Chaque itération du shader des sommets reçoit la valeur suivante du tampon affecté à cet attribut. Les uniformes sont similaires aux variables globales JavaScript. Ils conservent la même valeur pour toutes les itérations d'un shader. Du fait que les attributs et les emplacements des uniformes sont spécifiques à un programme de shader donné, nous les stockerons ensemble pour les rendre plus faciles à transmettre. - // Créer un tampon des positions pour le carré. + const programInfo = { + program: shaderProgram, + attribLocations: { + vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), + }, + uniformLocations: { + projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), + modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), + }, + }; - const positionBuffer = gl.createBuffer(); +## Création du carré 2D - // Définir le positionBuffer comme étant celui auquel appliquer les opérations - // de tampon à partir d'ici. +Avant de pouvoir faire un rendu de notre carré 2D, nous devons créer le tampon qui contiendra les positions de ses sommets et y placer les positions des sommets. Nous ferons cela en utilisant une fonction que nous appelerons `initBuffers()` ; à mesure que nous explorerons des concepts WebGL plus avancés, cette routine sera augmentée pour créer plus d'objets 3D, et plus complexes. - gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + function initBuffers(gl) { - // Créer maintenant un tableau des positions pour le carré. + // Créer un tampon des positions pour le carré. - const positions = [ - 1.0, 1.0, - -1.0, 1.0, - 1.0, -1.0, - -1.0, -1.0, - ]; + const positionBuffer = gl.createBuffer(); - // Passer mainenant la liste des positions à WebGL pour construire la forme. - // Nous faisons cela en créant un Float32Array à partir du tableau JavaScript, - // puis en l'utilisant pour remplir le tampon en cours. + // Définir le positionBuffer comme étant celui auquel appliquer les opérations + // de tampon à partir d'ici. - gl.bufferData(gl.ARRAY_BUFFER, - new Float32Array(positions), - gl.STATIC_DRAW); - - return { - position: positionBuffer, - }; -}</code></pre> + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); -<p>Cette routine est assez simpliste du fait de la nature basique de la scène dans cet exemple. Elle commence par appeler la méthode {{domxref ("WebGLRenderingContext.createBuffer()", "createBuffer()")}} de l'objet gl pour obtenir un tampon dans lequel nous stockerons les positions des sommets. Ce dernier est ensuite lié au contexte en appelant la méthode {{domxref ("WebGLRenderingContext.bindBuffer()", "bindBuffer()")}}.</p> + // Créer maintenant un tableau des positions pour le carré. -<p>Une fois que cela est fait, nous créons un tableau JavaScript contenant la position de chaque sommet du carré 2D. Ce dernier est ensuite converti en un tableau de flottants et transmis à la méthode {{domxref ("WebGLRenderingContext.bufferData()", "bufferData()")}} de l'objet <code>gl</code> pour définir les positions des sommets de l'objet.</p> + const positions = [ + 1.0, 1.0, + -1.0, 1.0, + 1.0, -1.0, + -1.0, -1.0, + ]; -<h2 id="Rendu_de_la_scène">Rendu de la scène</h2> + // Passer mainenant la liste des positions à WebGL pour construire la forme. + // Nous faisons cela en créant un Float32Array à partir du tableau JavaScript, + // puis en l'utilisant pour remplir le tampon en cours. -<p>Une fois que les shaders sont définis, que les emplacements sont retrouvés, et que les positions des sommets du carré 2D sont stockées dans le tampon, nous pouvons faire effectivement le rendu de la scène. Puisque nous n'animons rien dans cet exemple, notre fonction <code>drawScene()</code> est très simple. Elle utilise quelques routines utilitaires que nous décrirons sous peu.</p> + gl.bufferData(gl.ARRAY_BUFFER, + new Float32Array(positions), + gl.STATIC_DRAW); -<div class="note"> -<p><strong>Note :</strong> Vous pourriez obtenir une erreur JavaScript indiquant <em>"mat4 n'est pas défini"</em>. Cela signifie qu'il existe une dépendance à <strong>glmatrix</strong>. Vous pouvez inclure <a href="https://mdn.github.io/webgl-examples/tutorial/gl-matrix.js">gl-matrix.js</a> pour résoudre ce problème, comme suggéré <a href="https://github.com/mdn/webgl-examples/issues/20">ici</a>.</p> -</div> + return { + position: positionBuffer, + }; + } -<pre><code>function drawScene(gl, programInfo, buffers) { - gl.clearColor(0.0, 0.0, 0.0, 1.0); // effacement en noir, complètement opaque - gl.clearDepth(1.0); // tout effacer - gl.enable(gl.DEPTH_TEST); // activer le test de profondeur - gl.depthFunc(gl.LEQUAL); // les choses proches cachent les choses lointaines +Cette routine est assez simpliste du fait de la nature basique de la scène dans cet exemple. Elle commence par appeler la méthode {{domxref ("WebGLRenderingContext.createBuffer()", "createBuffer()")}} de l'objet gl pour obtenir un tampon dans lequel nous stockerons les positions des sommets. Ce dernier est ensuite lié au contexte en appelant la méthode {{domxref ("WebGLRenderingContext.bindBuffer()", "bindBuffer()")}}. + +Une fois que cela est fait, nous créons un tableau JavaScript contenant la position de chaque sommet du carré 2D. Ce dernier est ensuite converti en un tableau de flottants et transmis à la méthode {{domxref ("WebGLRenderingContext.bufferData()", "bufferData()")}} de l'objet `gl` pour définir les positions des sommets de l'objet. + +## Rendu de la scène + +Une fois que les shaders sont définis, que les emplacements sont retrouvés, et que les positions des sommets du carré 2D sont stockées dans le tampon, nous pouvons faire effectivement le rendu de la scène. Puisque nous n'animons rien dans cet exemple, notre fonction `drawScene()` est très simple. Elle utilise quelques routines utilitaires que nous décrirons sous peu. + +> **Note :** Vous pourriez obtenir une erreur JavaScript indiquant _"mat4 n'est pas défini"_. Cela signifie qu'il existe une dépendance à **glmatrix**. Vous pouvez inclure [gl-matrix.js](https://mdn.github.io/webgl-examples/tutorial/gl-matrix.js) pour résoudre ce problème, comme suggéré [ici](https://github.com/mdn/webgl-examples/issues/20). + + function drawScene(gl, programInfo, buffers) { + gl.clearColor(0.0, 0.0, 0.0, 1.0); // effacement en noir, complètement opaque + gl.clearDepth(1.0); // tout effacer + gl.enable(gl.DEPTH_TEST); // activer le test de profondeur + gl.depthFunc(gl.LEQUAL); // les choses proches cachent les choses lointaines + + // Effacer le canevas avant que nous ne commencions à dessiner dessus. + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + // Créer une matrice de perspective, une matrice spéciale qui est utilisée pour + // simuler la distorsion de la perspective dans une caméra. + // Notre champ de vision est de 45 degrés, avec un rapport largeur/hauteur qui + // correspond à la taille d'affichage du canvas ; + // et nous voulons seulement voir les objets situés entre 0,1 unité et 100 unités + // à partir de la caméra. + + const fieldOfView = 45 * Math.PI / 180; // en radians + const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight; + const zNear = 0.1; + const zFar = 100.0; + const projectionMatrix = mat4.create(); + + // note: glmatrix.js a toujours comme premier argument la destination + // où stocker le résultat. + mat4.perspective(projectionMatrix, + fieldOfView, + aspect, + zNear, + zFar); + + // Définir la position de dessin comme étant le point "origine", qui est + // le centre de la scène. + const modelViewMatrix = mat4.create(); + + // Commencer maintenant à déplacer la position de dessin un peu vers là où + // nous voulons commencer à dessiner le carré. + + mat4.translate(modelViewMatrix, // matrice de destination + modelViewMatrix, // matrice de déplacement + [-0.0, 0.0, -6.0]); // quantité de déplacement + + // Indiquer à WebGL comment extraire les positions à partir du tampon des + // positions pour les mettre dans l'attribut vertexPosition. + { + const numComponents = 2; // extraire 2 valeurs par itération + const type = gl.FLOAT; // les données dans le tampon sont des flottants 32bit + const normalize = false; // ne pas normaliser + const stride = 0; // combien d'octets à extraire entre un jeu de valeurs et le suivant + // 0 = utiliser le type et numComponents ci-dessus + const offset = 0; // démarrer à partir de combien d'octets dans le tampon + gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position); + gl.vertexAttribPointer( + programInfo.attribLocations.vertexPosition, + numComponents, + type, + normalize, + stride, + offset); + gl.enableVertexAttribArray( + programInfo.attribLocations.vertexPosition); + } + + // Indiquer à WebGL d'utiliser notre programme pour dessiner + + gl.useProgram(programInfo.program); + + // Définir les uniformes du shader + + gl.uniformMatrix4fv( + programInfo.uniformLocations.projectionMatrix, + false, + projectionMatrix); + gl.uniformMatrix4fv( + programInfo.uniformLocations.modelViewMatrix, + false, + modelViewMatrix); + + { + const offset = 0; + const vertexCount = 4; + gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount); + } + } - // Effacer le canevas avant que nous ne commencions à dessiner dessus. +La première étape consiste à effacer le canevas avec notre arrière plan ; ensuite, nous établissons la perspective de la caméra. Nous définissons un champ de vision de 45°, avec un rapport largeur sur hauteur qui correspond aux dimensions d'affichage de notre canevas. Nous indiquons également que seuls les objets situés entre 0,1 et 100 unités à partir de la caméra doivent être rendus. - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); +Ensuite, nous établissons la position du carré 2D en chargeant la position de l'origine et en nous déplaçant de 6 unités à partir de la caméra. Après cela, nous lions le tampon des sommets du carré à l'attribut que le shader utilise comme `aVertexPosition` et nous indiquons à WebGL comment en extraire les données. Enfin, nous dessinons l'objet en appelant la méthode {{domxref ("WebGLRenderingContext.drawArrays()", "drawArrays()")}}. - // Créer une matrice de perspective, une matrice spéciale qui est utilisée pour - // simuler la distorsion de la perspective dans une caméra. - // Notre champ de vision est de 45 degrés, avec un rapport largeur/hauteur qui - // correspond à la taille d'affichage du canvas ; - // et nous voulons seulement voir les objets situés entre 0,1 unité et 100 unités - // à partir de la caméra. +{{EmbedGHLiveSample('webgl-examples/tutorial/sample2/index.html', 670, 510) }} - const fieldOfView = 45 * Math.PI / 180; // en radians - const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight; - const zNear = 0.1; - const zFar = 100.0; - const projectionMatrix = mat4.create(); +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample2) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample2/) - // note: glmatrix.js a toujours comme premier argument la destination - // où stocker le résultat. - mat4.perspective(projectionMatrix, - fieldOfView, - aspect, - zNear, - zFar); +## Opérations utilitaires matricielles - // Définir la position de dessin comme étant le point "origine", qui est - // le centre de la scène. - const modelViewMatrix = mat4.create(); +Les opérations matricielles peuvent sembler compliquées, mais [elles sont en fait assez simples si vous en prenez une à la fois](https://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html). En général, les gens utilisent une bibliothèque matricielle plutôt que d'écrire la leur. Dans notre cas, nous utilisons la bibliothèque populaire [glMatrix](http://glmatrix.net/). - // Commencer maintenant à déplacer la position de dessin un peu vers là où - // nous voulons commencer à dessiner le carré. +Voir aussi : - mat4.translate(modelViewMatrix, // matrice de destination - modelViewMatrix, // matrice de déplacement - [-0.0, 0.0, -6.0]); // quantité de déplacement +- les [matrices](https://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html) sur WebGLFundamentals ; +- les [matrices](http://mathworld.wolfram.com/Matrix.html) sur Wolfram MathWorld ; +- l'article [matrice](<https://fr.wikipedia.org/wiki/Matrice_(math%C3%A9matiques)>) sur Wikipedia. - // Indiquer à WebGL comment extraire les positions à partir du tampon des - // positions pour les mettre dans l'attribut vertexPosition. - { - const numComponents = 2; // extraire 2 valeurs par itération - const type = gl.FLOAT; // les données dans le tampon sont des flottants 32bit - const normalize = false; // ne pas normaliser - const stride = 0; // combien d'octets à extraire entre un jeu de valeurs et le suivant - // 0 = utiliser le type et numComponents ci-dessus - const offset = 0; // démarrer à partir de combien d'octets dans le tampon - gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position); - gl.vertexAttribPointer( - programInfo.attribLocations.vertexPosition, - numComponents, - type, - normalize, - stride, - offset); - gl.enableVertexAttribArray( - programInfo.attribLocations.vertexPosition); - } - - // Indiquer à WebGL d'utiliser notre programme pour dessiner - - gl.useProgram(programInfo.program); - - // Définir les uniformes du shader - - gl.uniformMatrix4fv( - programInfo.uniformLocations.projectionMatrix, - false, - projectionMatrix); - gl.uniformMatrix4fv( - programInfo.uniformLocations.modelViewMatrix, - false, - modelViewMatrix); - - { - const offset = 0; - const vertexCount = 4; - gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount); - } -}</code></pre> - -<p>La première étape consiste à effacer le canevas avec notre arrière plan ; ensuite, nous établissons la perspective de la caméra. Nous définissons un champ de vision de 45°, avec un rapport largeur sur hauteur qui correspond aux dimensions d'affichage de notre canevas. Nous indiquons également que seuls les objets situés entre 0,1 et 100 unités à partir de la caméra doivent être rendus.</p> - -<p>Ensuite, nous établissons la position du carré 2D en chargeant la position de l'origine et en nous déplaçant de 6 unités à partir de la caméra. Après cela, nous lions le tampon des sommets du carré à l'attribut que le shader utilise comme <code>aVertexPosition</code> et nous indiquons à WebGL comment en extraire les données. Enfin, nous dessinons l'objet en appelant la méthode {{domxref ("WebGLRenderingContext.drawArrays()", "drawArrays()")}}.</p> - -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample2/index.html', 670, 510) }}</p> - -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample2">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample2/">Ouvrir cette démo dans une nouvelle page</a></p> - -<h2 id="Opérations_utilitaires_matricielles">Opérations utilitaires matricielles</h2> - -<p>Les opérations matricielles peuvent sembler compliquées, mais <a href="https://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html">elles sont en fait assez simples si vous en prenez une à la fois</a>. En général, les gens utilisent une bibliothèque matricielle plutôt que d'écrire la leur. Dans notre cas, nous utilisons la bibliothèque populaire <a href="http://glmatrix.net/">glMatrix</a>.</p> - -<p>Voir aussi :</p> - -<ul> - <li>les <a href="https://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html">matrices</a> sur WebGLFundamentals ;</li> - <li>les <a href="http://mathworld.wolfram.com/Matrix.html">matrices</a> sur Wolfram MathWorld ;</li> - <li>l'article <a href="https://fr.wikipedia.org/wiki/Matrice_(math%C3%A9matiques)">matrice</a> sur Wikipedia.</li> -</ul> - -<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}}</p> +{{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}} diff --git a/files/fr/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md b/files/fr/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md index 05b7ea8e12..c8111be23c 100644 --- a/files/fr/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md +++ b/files/fr/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md @@ -7,54 +7,51 @@ tags: translation_of: Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL original_slug: Web/API/WebGL_API/Tutorial/Animer_des_objets_avec_WebGL --- -<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }}</p> +{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }} -<p>Dans cet exemple, nous allons faire tourner notre carré 2D.</p> +Dans cet exemple, nous allons faire tourner notre carré 2D. -<h2 id="Faire_tourner_le_carré">Faire tourner le carré</h2> +## Faire tourner le carré -<p>Commençons par faire tourner le carré. La première chose dont nous avons besoin est une variable pour mémoriser la rotation courante du carré :</p> +Commençons par faire tourner le carré. La première chose dont nous avons besoin est une variable pour mémoriser la rotation courante du carré : -<pre class="brush: js">var <code>squareRotation</code> = 0.0; -</pre> +```js +var squareRotation = 0.0; +``` -<p>Maintenant, nous devons modifier la fonction <code>drawScene() </code>pour appliquer la rotation courante du carré quand on le dessine. Après déplacement à la position de dessin initiale du carré, nous appliquons la rotation comme suit : </p> +Maintenant, nous devons modifier la fonction `drawScene() `pour appliquer la rotation courante du carré quand on le dessine. Après déplacement à la position de dessin initiale du carré, nous appliquons la rotation comme suit : -<pre><code> mat4.rotate(modelViewMatrix, // matrice de destination - modelViewMatrix, // matrice de rotation - squareRotation, // rotation en radians - [0, 0, 1]); // axe autour duquel tourner</code></pre> + mat4.rotate(modelViewMatrix, // matrice de destination + modelViewMatrix, // matrice de rotation + squareRotation, // rotation en radians + [0, 0, 1]); // axe autour duquel tourner -<p>Ceci fait tourner la modelViewMatrix de la valeur courante de <code>squareRotation</code>, autour de l'axe Z.</p> +Ceci fait tourner la modelViewMatrix de la valeur courante de `squareRotation`, autour de l'axe Z. -<p>Pour réaliser effectivement l'animation, nous avons besoin d'ajouter du code qui change la valeur de <code>squareRotation</code> au fil du temps. Nous pouvons faire cela en créant une nouvelle variable pour mémoriser l'instant auquel nous avons réalisé l'animation pour la dernière fois (appelons le <code>then</code>), puis en ajoutant le code suivant à la fin de la fonction principale :</p> +Pour réaliser effectivement l'animation, nous avons besoin d'ajouter du code qui change la valeur de `squareRotation` au fil du temps. Nous pouvons faire cela en créant une nouvelle variable pour mémoriser l'instant auquel nous avons réalisé l'animation pour la dernière fois (appelons le `then`), puis en ajoutant le code suivant à la fin de la fonction principale : -<pre><code>var then = 0; + var then = 0; -// Dessiner la scène répétitivement -function render(now) { - now *= 0.001; // conversion en secondes - const deltaTime = now - then; - then = now; + // Dessiner la scène répétitivement + function render(now) { + now *= 0.001; // conversion en secondes + const deltaTime = now - then; + then = now; - drawScene(gl, programInfo, buffers, deltaTime); + drawScene(gl, programInfo, buffers, deltaTime); - requestAnimationFrame(render); -} -requestAnimationFrame(render);</code></pre> + requestAnimationFrame(render); + } + requestAnimationFrame(render); -<p>Ce code utilise <code>requestAnimationFrame</code> pour demander au navigateur d'appeler la fonction "<code>render</code>" à chaque image. <code>requestAnimationFrame</code> nous transmet le temps en millisecondes depuis le chargement de la page. Nous le convertissons en secondes, puis nous lui soustrayons le dernier instant pour calculer <code>deltaTime</code>, qui est le nombre de secondes depuis le rendu de la dernière image. À la fin de drawscene, nous ajoutons le code pour mettre à jour <code>squareRotation</code>.</p> +Ce code utilise `requestAnimationFrame` pour demander au navigateur d'appeler la fonction "`render`" à chaque image. `requestAnimationFrame` nous transmet le temps en millisecondes depuis le chargement de la page. Nous le convertissons en secondes, puis nous lui soustrayons le dernier instant pour calculer `deltaTime`, qui est le nombre de secondes depuis le rendu de la dernière image. À la fin de drawscene, nous ajoutons le code pour mettre à jour `squareRotation`. -<pre><code> squareRotation += deltaTime;</code></pre> + squareRotation += deltaTime; -<p>Ce code utilise le laps de temps qui s'est écoulé depuis la dernière fois que nous avons mis à jour la valeur <code>squareRotation</code> pour déterminer de combien faire tourner le carré.</p> +Ce code utilise le laps de temps qui s'est écoulé depuis la dernière fois que nous avons mis à jour la valeur `squareRotation` pour déterminer de combien faire tourner le carré. -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample4/index.html', 670, 510) }}</p> +{{EmbedGHLiveSample('webgl-examples/tutorial/sample4/index.html', 670, 510) }} -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample4">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample4/">Ouvrir cette démo dans une nouvelle page</a></p> +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample4) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample4/) -<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }}</p> - -<p> </p> - -<p> </p> +{{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }} diff --git a/files/fr/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md b/files/fr/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md index df7fcb4658..6844827c75 100644 --- a/files/fr/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md +++ b/files/fr/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md @@ -9,15 +9,16 @@ tags: translation_of: Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL original_slug: Web/API/WebGL_API/Tutorial/Animation_de_textures_en_WebGL --- -<p>{{WebGLSidebar("Tutorial") }} {{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> +{{WebGLSidebar("Tutorial") }} {{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} -<p>Dans cette démonstration, nous construisons sur l'exemple précédent en remplaçant nos textures statiques par les images d'un fichier vidéo mp4 en cours de lecture. C'est en fait assez facile à faire, mais c'est amusant à regarder, alors commençons. Un code similaire peut être réalisé pour utiliser n'importe quel type de données (comme un {{HTMLElement ("canvas")}}) comme source pour vos textures..</p> +Dans cette démonstration, nous construisons sur l'exemple précédent en remplaçant nos textures statiques par les images d'un fichier vidéo mp4 en cours de lecture. C'est en fait assez facile à faire, mais c'est amusant à regarder, alors commençons. Un code similaire peut être réalisé pour utiliser n'importe quel type de données (comme un {{HTMLElement ("canvas")}}) comme source pour vos textures.. -<h2 id="Accéder_à_la_vidéo">Accéder à la vidéo</h2> +## Accéder à la vidéo -<p>La première étape consiste à créer l'élément {{HTMLElement("video")}} que nous utiliserons pour récupérer les images vidéo :</p> +La première étape consiste à créer l'élément {{HTMLElement("video")}} que nous utiliserons pour récupérer les images vidéo : -<pre class="brush: js">// sera mis à true quand la vidéo pourra être copiée dans la texture +```js +// sera mis à true quand la vidéo pourra être copiée dans la texture var copierVideo = false; function configurerVideo(url) { @@ -30,8 +31,8 @@ function configurerVideo(url) { video.muted = true; video.loop = true; - <code>// </code>Le fait d'attendre ces 2 évènements assure<code> - // </code>qu'il y a des données dans la vidéo + // Le fait d'attendre ces 2 évènements assure + // qu'il y a des données dans la vidéo video.addEventListener('playing', function() { playing = true; @@ -47,31 +48,32 @@ function configurerVideo(url) { video.play(); function verifierPret() { - if (playing && timeupdate) { + if (playing && timeupdate) { copierVideo = true; } } return video; } -</pre> +``` -<p>D'abord, nous créons un élément vidéo. Nous le mettons en lecture automatique, nous coupons le son et nous faisons tourner la vidéo en boucle. Nous configurons ensuite 2 événements pour voir que la vidéo est en cours de lecture et que le temps a été mis à jour. Nous avons besoin de ces deux vérifications, car c'est une erreur que d'essayer de télécharger sur WebGL une vidéo qui n'a pas encore de données disponibles. La vérification de ces deux événements garantit que des données sont disponibles et que l'on peut démarrer en toute sécurité le chargement de la vidéo dans une texture WebGL. Dans le code ci-dessus, nous vérifions si nous avons reçu ces deux événements et si c'est le cas, nous mettons une variable globale, <code>copierVideo</code>, à true pour nous dire qu'il est possible de commencer à copier la vidéo dans une texture.</p> +D'abord, nous créons un élément vidéo. Nous le mettons en lecture automatique, nous coupons le son et nous faisons tourner la vidéo en boucle. Nous configurons ensuite 2 événements pour voir que la vidéo est en cours de lecture et que le temps a été mis à jour. Nous avons besoin de ces deux vérifications, car c'est une erreur que d'essayer de télécharger sur WebGL une vidéo qui n'a pas encore de données disponibles. La vérification de ces deux événements garantit que des données sont disponibles et que l'on peut démarrer en toute sécurité le chargement de la vidéo dans une texture WebGL. Dans le code ci-dessus, nous vérifions si nous avons reçu ces deux événements et si c'est le cas, nous mettons une variable globale, `copierVideo`, à true pour nous dire qu'il est possible de commencer à copier la vidéo dans une texture. -<p>Et enfin, nous définissons l'attribut <code>src</code> pour commencer, et nous appelons <code>play</code> pour démarrer le chargement et la lecture de la vidéo.</p> +Et enfin, nous définissons l'attribut `src` pour commencer, et nous appelons `play` pour démarrer le chargement et la lecture de la vidéo. -<h2 id="Utilisation_des_images_vidéo_comme_texture">Utilisation des images vidéo comme texture</h2> +## Utilisation des images vidéo comme texture -<p>La prochaine modification porte sur <code>initTexture()</code>, qui devient beaucoup plus simple, car elle n'a plus besoin de charger un fichier image. A la place, tout ce qu'elle fait est de créer un objet texture vide, d'y mettre un unique pixel et de définir son filtrage pour une utilisation ultérieure :</p> +La prochaine modification porte sur `initTexture()`, qui devient beaucoup plus simple, car elle n'a plus besoin de charger un fichier image. A la place, tout ce qu'elle fait est de créer un objet texture vide, d'y mettre un unique pixel et de définir son filtrage pour une utilisation ultérieure : -<pre class="brush: js">function initTexture(gl, url) { +```js +function initTexture(gl, url) { const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); -<code> // </code>Parce que la vidéo doit être téléchargée depuis sur Internet,<code> - // </code>cela peut prendre un certain temps jusqu'à ce qu'elle soit prête, donc<code> - // </code>mettre un seul pixel dans la texture, de façon à ce que nous puissions<code> - // </code>l'utiliser immédiatement. + // Parce que la vidéo doit être téléchargée depuis sur Internet, + // cela peut prendre un certain temps jusqu'à ce qu'elle soit prête, donc + // mettre un seul pixel dans la texture, de façon à ce que nous puissions + // l'utiliser immédiatement. const niveau = 0; const formatInterne = gl.RGBA; const largeur = 1; @@ -92,11 +94,12 @@ function configurerVideo(url) { return texture; } -</pre> +``` -<div>Voici à quoi ressemble la fonction <code>mettreAJourTexture()</code> ; c'est là où le vrai travail est fait :</div> +Voici à quoi ressemble la fonction `mettreAJourTexture()` ; c'est là où le vrai travail est fait : -<pre class="brush: js">function mettreAJourTexture(gl, texture, video) { +```js +function mettreAJourTexture(gl, texture, video) { const niveau = 0; const formatInterne = gl.RGBA; const formatSrc = gl.RGBA; @@ -105,13 +108,14 @@ function configurerVideo(url) { gl.texImage2D(gl.TEXTURE_2D, niveau, formatInterne, formatSrc, typeSrc, video); } -</pre> +``` -<p>Vous avez déjà vu ce code. Il est presque identique à la fonction onload de l'image dans l'exemple précédent, sauf quand nous appellons <code>texImage2D()</code>, au lieu de passer un objet <code>Image</code>, nous passons l'élément {{HTMLElement ("video")}}. WebGL sait comment extraire l'image en cours et l'utiliser comme texture.</p> +Vous avez déjà vu ce code. Il est presque identique à la fonction onload de l'image dans l'exemple précédent, sauf quand nous appellons `texImage2D()`, au lieu de passer un objet `Image`, nous passons l'élément {{HTMLElement ("video")}}. WebGL sait comment extraire l'image en cours et l'utiliser comme texture. -<p>Si <code>copierVideo</code> est true, alors <code>mettreAJourTexture()</code> est appelé à chaque fois juste avant que nous appellions la fonction <code>dessinerScene()</code>.</p> +Si `copierVideo` est true, alors `mettreAJourTexture()` est appelé à chaque fois juste avant que nous appellions la fonction `dessinerScene()`. -<pre class="brush: js"> var alors = 0; +```js + var alors = 0; // Dessiner la scène répétitivement function dessiner(maintenant) { @@ -120,7 +124,7 @@ function configurerVideo(url) { alors = maintenant; if (copierVideo) { - <code>mettreAJour</code>Texture(gl, texture, video); + mettreAJourTexture(gl, texture, video); } dessinerScene(gl, programInfo, buffers, texture, ecartTemps); @@ -128,18 +132,16 @@ function configurerVideo(url) { requestAnimationFrame(dessiner); } requestAnimationFrame(dessiner); -</pre> +``` -<p>C'est tout pour ce qu'il y a à faire pour cela !</p> +C'est tout pour ce qu'il y a à faire pour cela ! -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample8/index.html', 670, 510) }}</p> +{{EmbedGHLiveSample('webgl-examples/tutorial/sample8/index.html', 670, 510) }} -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample8">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample8/">Ouvrir cette démo dans une nouvelle page</a></p> +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample8) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample8/) -<h2 id="Voir_aussi">Voir aussi</h2> +## Voir aussi -<ul> - <li><a href="/fr/Using_HTML5_audio_and_video">Utilisation de l'audio et de la video dans Firefox</a></li> -</ul> +- [Utilisation de l'audio et de la video dans Firefox](/fr/Using_HTML5_audio_and_video) -<p>{{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> +{{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} diff --git a/files/fr/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md b/files/fr/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md index 844ee8f454..3691a94ab7 100644 --- a/files/fr/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md +++ b/files/fr/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md @@ -7,17 +7,18 @@ tags: translation_of: Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL original_slug: Web/API/WebGL_API/Tutorial/Creer_des_objets_3D_avec_WebGL --- -<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}</p> +{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}} -<p>Transformons notre carré en trois dimensions en lui ajoutant cinq faces supplémentaires pour créer un cube. Pour faire cela efficacement, nous allons passer du dessin de sommets par l'appel direct de la méthode {{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}}, à l'utilisation du tableau des sommets comme une table, et à référencer les sommets individuels dans cette table pour définir les positions des sommets de chaque face, en appelant directement {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}.</p> +Transformons notre carré en trois dimensions en lui ajoutant cinq faces supplémentaires pour créer un cube. Pour faire cela efficacement, nous allons passer du dessin de sommets par l'appel direct de la méthode {{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}}, à l'utilisation du tableau des sommets comme une table, et à référencer les sommets individuels dans cette table pour définir les positions des sommets de chaque face, en appelant directement {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}. -<p>Notez que chaque face nécessite quatre sommets pour la définir, mais que chaque sommet est partagé entre trois faces. Nous pouvons donc passer beaucoup moins de données en faisant un tableau des 24 sommets, puis en référençant chaque sommet par son indice dans ce tableau, au lieu de passer des ensembles complets de coordonnées. Si vous vous demandez pourquoi nous avons besoin de 24 sommets, et non pas seulement de 8, c'est parce que chaque coin appartient à trois faces de couleurs différentes, et qu'un sommet donné doit avoir une couleur spécifique - c'est pourquoi nous allons créer 3 copies de chaque sommet dans les trois couleurs différentes, une pour chaque face.</p> +Notez que chaque face nécessite quatre sommets pour la définir, mais que chaque sommet est partagé entre trois faces. Nous pouvons donc passer beaucoup moins de données en faisant un tableau des 24 sommets, puis en référençant chaque sommet par son indice dans ce tableau, au lieu de passer des ensembles complets de coordonnées. Si vous vous demandez pourquoi nous avons besoin de 24 sommets, et non pas seulement de 8, c'est parce que chaque coin appartient à trois faces de couleurs différentes, et qu'un sommet donné doit avoir une couleur spécifique - c'est pourquoi nous allons créer 3 copies de chaque sommet dans les trois couleurs différentes, une pour chaque face. -<h2 id="Définir_la_position_des_sommets_du_cube">Définir la position des sommets du cube</h2> +## Définir la position des sommets du cube -<p>Tout d'abord, construisons le tampon des sommets du cube en mettant à jour le code de <code>initBuffer()</code>. C'est sensiblement le même que pour le carré, mais en plus long, du fait qu'il y a 24 sommets (4 par côté) :</p> +Tout d'abord, construisons le tampon des sommets du cube en mettant à jour le code de `initBuffer()`. C'est sensiblement le même que pour le carré, mais en plus long, du fait qu'il y a 24 sommets (4 par côté) : -<pre class="brush: js"> const positions = [ +```js + const positions = [ // Face avant -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, @@ -54,31 +55,32 @@ original_slug: Web/API/WebGL_API/Tutorial/Creer_des_objets_3D_avec_WebGL -1.0, 1.0, 1.0, -1.0, 1.0, -1.0 ]; -</pre> - -<p>Du fait que nous avons ajouté une composante z à nos sommets, nous avons besoin de changer en 3 le <code>numComponents</code> de notre attribut <code>vertexPosition</code>.</p> - -<pre><code>// Indiquer à WebGL comment extraire les positions du tampon des -// positions dans l'attribut vertexPosition -{ - const numComponents = 3; - ... - gl.vertexAttribPointer( - programInfo.attribLocations.vertexPosition, - numComponents, - type, - normalize, - stride, - offset); - gl.enableVertexAttribArray( - programInfo.attribLocations.vertexPosition); -}</code></pre> - -<h2 id="Définir_les_couleurs_des_sommets">Définir les couleurs des sommets</h2> - -<p>Nous avons aussi besoin de construire un tableau des couleurs pour chacun des 24 sommets. Ce code commence par définir une couleur pour chaque face, puis il utilise une boucle pour assembler le tableau de toutes les couleurs pour chacun des sommets.</p> - -<pre class="brush: js"> const <code>faceColors </code>= [ +``` + +Du fait que nous avons ajouté une composante z à nos sommets, nous avons besoin de changer en 3 le `numComponents` de notre attribut `vertexPosition`. + + // Indiquer à WebGL comment extraire les positions du tampon des + // positions dans l'attribut vertexPosition + { + const numComponents = 3; + ... + gl.vertexAttribPointer( + programInfo.attribLocations.vertexPosition, + numComponents, + type, + normalize, + stride, + offset); + gl.enableVertexAttribArray( + programInfo.attribLocations.vertexPosition); + } + +## Définir les couleurs des sommets + +Nous avons aussi besoin de construire un tableau des couleurs pour chacun des 24 sommets. Ce code commence par définir une couleur pour chaque face, puis il utilise une boucle pour assembler le tableau de toutes les couleurs pour chacun des sommets. + +```js + const faceColors = [ [1.0, 1.0, 1.0, 1.0], // Face avant : blanc [1.0, 0.0, 0.0, 1.0], // Face arrière : rouge [0.0, 1.0, 0.0, 1.0], // Face supérieure : vert @@ -89,25 +91,26 @@ original_slug: Web/API/WebGL_API/Tutorial/Creer_des_objets_3D_avec_WebGL // Conversion du tableau des couleurs en une table pour tous les sommets - var <code>colors </code>= []; + var colors = []; - for (j=0; j<<code>faceColors</code>.length; j++) { + for (j=0; j<faceColors.length; j++) { const c = faceColors[j]; // Répéter chaque couleur quatre fois pour les quatre sommets d'une face - colors = colors<code>.concat(c, c, c, c); - </code>} + colors = colors.concat(c, c, c, c); + } const colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); -</pre> +``` -<h2 id="Définir_le_tableau_des_éléments">Définir le tableau des éléments</h2> +## Définir le tableau des éléments -<p>Une fois que les tableaux des sommets sont générés, nous devons construire le tableau des éléments.</p> +Une fois que les tableaux des sommets sont générés, nous devons construire le tableau des éléments. -<pre class="brush: js"> <code>const indexBuffer = gl.createBuffer(); +```js + const indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); // Ce tableau définit chaque face comme deux triangles, en utilisant les @@ -129,40 +132,41 @@ original_slug: Web/API/WebGL_API/Tutorial/Creer_des_objets_3D_avec_WebGL new Uint16Array(indices), gl.STATIC_DRAW); return { - position: positionBuffer</code><code>, - color: colorBuffer</code><code>, - indices: indexBuffer</code><code>, + position: positionBuffer, + color: colorBuffer, + indices: indexBuffer, }; -}</code></pre> +} +``` -<p>Le tableau <code>indices</code> définit chaque face comme étant une paire de triangles, en spécifiant chaque sommet du triangle comme un indice dans les tableaux des sommets du cube. Ainsi le cube est décrit comme une collection de 12 triangles.</p> +Le tableau `indices` définit chaque face comme étant une paire de triangles, en spécifiant chaque sommet du triangle comme un indice dans les tableaux des sommets du cube. Ainsi le cube est décrit comme une collection de 12 triangles. -<h2 id="Dessiner_le_cube">Dessiner le cube</h2> +## Dessiner le cube -<p>Ensuite, nous devons ajouter du code à notre fonction <code>drawScene()</code> pour dessiner le tampon des indices du cube, en ajoutant de nouveaux appels à {{domxref("WebGLRenderingContext.bindBuffer()", "gl.bindBuffer()")}} et {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}} :</p> +Ensuite, nous devons ajouter du code à notre fonction `drawScene()` pour dessiner le tampon des indices du cube, en ajoutant de nouveaux appels à {{domxref("WebGLRenderingContext.bindBuffer()", "gl.bindBuffer()")}} et {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}} : -<pre><code> // Indiquer à WebGL quels indices utiliser pour indexer les sommets - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tampons.indices); + // Indiquer à WebGL quels indices utiliser pour indexer les sommets + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tampons.indices); -... + ... - { - const vertexCount = 36; - const type = gl.UNSIGNED_SHORT; - const offset = 0; - gl.drawElements(gl.TRIANGLES, vertexCount, type, offset); - }</code></pre> + { + const vertexCount = 36; + const type = gl.UNSIGNED_SHORT; + const offset = 0; + gl.drawElements(gl.TRIANGLES, vertexCount, type, offset); + } -<p>Du fait que chaque face de notre cube est composée de deux triangles, il y a 6 sommets par côté, soit 36 sommets au total dans le cube, même si beaucoup d'entre eux sont des doublons.</p> +Du fait que chaque face de notre cube est composée de deux triangles, il y a 6 sommets par côté, soit 36 sommets au total dans le cube, même si beaucoup d'entre eux sont des doublons. -<p>Finalement, remplaçons notre variable <code>squareRotation</code> par <code>cubeRotation</code> et ajoutons une seconde rotation autour de l'axe des x :</p> +Finalement, remplaçons notre variable `squareRotation` par `cubeRotation` et ajoutons une seconde rotation autour de l'axe des x : -<pre><code>mat4.rotate(modelViewMatrix, modelViewMatrix, cubeRotation * .7, [0, 1, 0]);</code></pre> + mat4.rotate(modelViewMatrix, modelViewMatrix, cubeRotation * .7, [0, 1, 0]); -<p>À ce stade, nous avons un cube animé en rotation, ses six faces ayant des couleurs assez vives.</p> +À ce stade, nous avons un cube animé en rotation, ses six faces ayant des couleurs assez vives. -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample5/index.html', 670, 510) }}</p> +{{EmbedGHLiveSample('webgl-examples/tutorial/sample5/index.html', 670, 510) }} -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample5">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample5/">Ouvrir cette démo dans une nouvelle page</a></p> +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample5) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample5/) -<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}</p> +{{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}} diff --git a/files/fr/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md b/files/fr/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md index 10adde485e..737b272fbe 100644 --- a/files/fr/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md +++ b/files/fr/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md @@ -7,32 +7,34 @@ tags: translation_of: Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL original_slug: Web/API/WebGL_API/Tutorial/Commencer_avec_WebGL --- -<p>{{WebGLSidebar("Tutorial")}} {{Next("Web/API/WebGL_API/Tutorial/Ajouter_du_contenu_à_WebGL")}}<a href="http://www.khronos.org/webgl/">WebGL</a> permet à un contenu web d'utiliser l'API basée sur <a href="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0 pour effectuer un rendu 2D et 3D dans un <a href="/fr/HTML/Canvas">canvas</a> dans les navigateurs qui le supportent, sans utilisation d'un module complémentaire. Les programmes WebGL sont constitués de code de contrôle écrit en JavaScript, et le code d'ombrage (GLSL) est exécuté dans l'Unité de Traitement Graphique (GPU) de l'ordinateur. Les éléments WebGL peuvent être mélangés avec d'autres éléments HTML, et composés d'autres parties de la page ou de l'arrière-plan de la page.</p> +{{WebGLSidebar("Tutorial")}} {{Next("Web/API/WebGL_API/Tutorial/Ajouter_du_contenu_à_WebGL")}}[WebGL](http://www.khronos.org/webgl/) permet à un contenu web d'utiliser l'API basée sur [OpenGL ES](http://www.khronos.org/opengles/) 2.0 pour effectuer un rendu 2D et 3D dans un [canvas](/fr/HTML/Canvas) dans les navigateurs qui le supportent, sans utilisation d'un module complémentaire. Les programmes WebGL sont constitués de code de contrôle écrit en JavaScript, et le code d'ombrage (GLSL) est exécuté dans l'Unité de Traitement Graphique (GPU) de l'ordinateur. Les éléments WebGL peuvent être mélangés avec d'autres éléments HTML, et composés d'autres parties de la page ou de l'arrière-plan de la page. -<p>Cet article va vous donner une introduction aux bases de l'utilisation de WebGL. Il est supposé que vous avez déjà une compréhension des mathématiques impliquées dans les graphismes 3D, et cet article ne prétend pas vous enseigner les concepts des graphismes 3D par eux-mêmes.</p> +Cet article va vous donner une introduction aux bases de l'utilisation de WebGL. Il est supposé que vous avez déjà une compréhension des mathématiques impliquées dans les graphismes 3D, et cet article ne prétend pas vous enseigner les concepts des graphismes 3D par eux-mêmes. -<p>Les exemples de code de ce tutoriel peuvent aussi être trouvés dans le <a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial">webgl-examples GitHub repository</a>.</p> +Les exemples de code de ce tutoriel peuvent aussi être trouvés dans le [webgl-examples GitHub repository](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial). -<h2 id="Préparation_au_rendu_3D">Préparation au rendu 3D</h2> +## Préparation au rendu 3D -<p>La première chose dont vous avez besoin pour utiliser WebGL pour faire un rendu est un canvas. Le fragment d'HTML ci-dessous déclare un canvas dans lequel notre exemple se dessinera.</p> +La première chose dont vous avez besoin pour utiliser WebGL pour faire un rendu est un canvas. Le fragment d'HTML ci-dessous déclare un canvas dans lequel notre exemple se dessinera. -<pre class="brush: html"><code><body> - <canvas id="glCanvas" width="640" height="480"></canvas> -</body></code> -</pre> +```html +<body> + <canvas id="glCanvas" width="640" height="480"></canvas> +</body> +``` -<h3 id="Préparation_du_contexte_WebGL">Préparation du contexte WebGL</h3> +### Préparation du contexte WebGL -<p>La fonction <code>main()</code> dans notre code JavaScript est appelée quand notre script est chargé. Son but est de créer le contexte WebGL et de commencer à rendre du contenu.</p> +La fonction `main()` dans notre code JavaScript est appelée quand notre script est chargé. Son but est de créer le contexte WebGL et de commencer à rendre du contenu. -<pre class="brush: js"><code>main(); +```js +main(); // // Début ici // function main() { - </code> const canvas = document.querySelector("#glCanvas"); + const canvas = document.querySelector("#glCanvas"); // Initialisation du contexte WebGL const gl = canvas.getContext("webgl"); @@ -47,26 +49,24 @@ function main() { // Effacer le tampon de couleur avec la couleur d'effacement spécifiée gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT); } -</pre> +``` -<p>La première chose que nous faisons ici est d'obtenir une référence au canvas, en l'affectant à une variable dénommée <code>canvas</code>.</p> +La première chose que nous faisons ici est d'obtenir une référence au canvas, en l'affectant à une variable dénommée `canvas`. -<p>Une fois que nous avons le canvas, nous essayons de lui obtenir un <a href="/fr-FR/docs/Web/API/WebGLRenderingContext">WebGLRenderingContext</a>, en appelant <a href="/fr-FR/docs/Web/API/HTMLCanvasElement/getContext">getContext</a> et en lui passant la chaîne <code>"webgl"</code>. Si le navigateur ne supporte pas WebGL, <code>getContext</code> retournera <code>null</code>, auquel cas nous afficherons un message pour l'utilisateur, et nous sortirons.</p> +Une fois que nous avons le canvas, nous essayons de lui obtenir un [WebGLRenderingContext](/fr-FR/docs/Web/API/WebGLRenderingContext), en appelant [getContext](/fr-FR/docs/Web/API/HTMLCanvasElement/getContext) et en lui passant la chaîne `"webgl"`. Si le navigateur ne supporte pas WebGL, `getContext` retournera `null`, auquel cas nous afficherons un message pour l'utilisateur, et nous sortirons. -<p>Si le contexte est initialisé avec succès, la variable <code>gl</code> sera notre référence à celui-ci. Dans ce cas, nous définissons la couleur d'effacement comme étant le noir, et nous effaçons le contexte avec cette couleur (redessin du canvas avec la couleur d'arrière-plan).</p> +Si le contexte est initialisé avec succès, la variable `gl` sera notre référence à celui-ci. Dans ce cas, nous définissons la couleur d'effacement comme étant le noir, et nous effaçons le contexte avec cette couleur (redessin du canvas avec la couleur d'arrière-plan). -<p>A ce stade, votre code est suffisant pour que le contexte WebGL puisse s'initialiser avec succès, et vous devriez vous retrouver avec une grande boîte noire et vide, prête à - et attendant de - recevoir du contenu.</p> +A ce stade, votre code est suffisant pour que le contexte WebGL puisse s'initialiser avec succès, et vous devriez vous retrouver avec une grande boîte noire et vide, prête à - et attendant de - recevoir du contenu. -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample1/index.html', 670, 510) }}</p> +{{EmbedGHLiveSample('webgl-examples/tutorial/sample1/index.html', 670, 510) }} -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample1">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample1/">Ouvrir cette démo dans une nouvelle page</a></p> +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample1) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample1/) -<h2 id="Voir_aussi">Voir aussi</h2> +## Voir aussi -<ul> - <li><a href="https://dev.opera.com/articles/introduction-to-webgl-part-1/">An introduction to WebGL</a> : écrite par Luz Caballero, publiée sur dev.opera.com. Cet article traite de ce qu'est WebGL, explique comment WebGL fonctionne (incluant le concept de pipeline de rendu), et présente quelques bibliothèques WebGL.</li> - <li><a href="http://webglfundamentals.org/">WebGL Fundamentals</a></li> - <li><a href="http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html">An intro to modern OpenGL :</a> une série de bons articles sur OpenGL écrits par Joe Groff, fournissant une introduction claire à OpenGL, depuis son histoire jusqu'au concept important de pipeline de graphismes, qui comprend aussi quelques exemples montrant comment OpenGL fonctionne. Si vous n'avez aucune idée de ce qu'est OpenGL, c'est un bon endroit pour commencer.</li> -</ul> +- [An introduction to WebGL](https://dev.opera.com/articles/introduction-to-webgl-part-1/) : écrite par Luz Caballero, publiée sur dev.opera.com. Cet article traite de ce qu'est WebGL, explique comment WebGL fonctionne (incluant le concept de pipeline de rendu), et présente quelques bibliothèques WebGL. +- [WebGL Fundamentals](http://webglfundamentals.org/) +- [An intro to modern OpenGL :](http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html) une série de bons articles sur OpenGL écrits par Joe Groff, fournissant une introduction claire à OpenGL, depuis son histoire jusqu'au concept important de pipeline de graphismes, qui comprend aussi quelques exemples montrant comment OpenGL fonctionne. Si vous n'avez aucune idée de ce qu'est OpenGL, c'est un bon endroit pour commencer. -<p>{{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}}</p>
\ No newline at end of file +{{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}} diff --git a/files/fr/web/api/webgl_api/tutorial/index.md b/files/fr/web/api/webgl_api/tutorial/index.md index 671b448a9d..7a9d0e4aba 100644 --- a/files/fr/web/api/webgl_api/tutorial/index.md +++ b/files/fr/web/api/webgl_api/tutorial/index.md @@ -8,33 +8,31 @@ tags: - WebGL translation_of: Web/API/WebGL_API/Tutorial --- -<div>{{WebGLSidebar}}</div> +{{WebGLSidebar}} -<p><a href="http://www.khronos.org/webgl/">WebGL</a> permet au contenu web d'utiliser une API basée sur <a href="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0 pour effectuer des rendus 3D dans un {{HTMLElement("canvas")}} HTML dans les navigateurs qui le supportent, sans avoir recours à des modules complémentaires. Les programmes WebGL sont constitués de code de contrôle rédigé en JavaScript, et de code d'effets spéciaux (code shader) qui est exécuté sur l'Unité de Traitement Graphique (GPU) d'un ordinateur. Les éléments WebGL peuvent être mélangés avec d'autres éléments HTML et composés avec d'autres parties de la page ou du fond de la page.</p> +[WebGL](http://www.khronos.org/webgl/) permet au contenu web d'utiliser une API basée sur [OpenGL ES](http://www.khronos.org/opengles/) 2.0 pour effectuer des rendus 3D dans un {{HTMLElement("canvas")}} HTML dans les navigateurs qui le supportent, sans avoir recours à des modules complémentaires. Les programmes WebGL sont constitués de code de contrôle rédigé en JavaScript, et de code d'effets spéciaux (code shader) qui est exécuté sur l'Unité de Traitement Graphique (GPU) d'un ordinateur. Les éléments WebGL peuvent être mélangés avec d'autres éléments HTML et composés avec d'autres parties de la page ou du fond de la page. -<p>Ce tutoriel décrit comment utiliser l'élément <code><canvas></code> pour dessiner des graphiques WebGL, en commençant par les bases. Les exemples suivants devraient vous donner des idées de ce que vous pouvez faire avec WebGL et vont vous fournir des fragments de code qui pourraient vous aider à construire votre propre contenu.</p> +Ce tutoriel décrit comment utiliser l'élément `<canvas>` pour dessiner des graphiques WebGL, en commençant par les bases. Les exemples suivants devraient vous donner des idées de ce que vous pouvez faire avec WebGL et vont vous fournir des fragments de code qui pourraient vous aider à construire votre propre contenu. -<h2 id="Avant_que_vous_ne_commenciez">Avant que vous ne commenciez</h2> +## Avant que vous ne commenciez -<p>L'utilisation de l'élément <code><canvas></code> n'est pas très difficile, mais vous avez besoin d'une compréhension de base de l'<a href="/en-US/docs/Web/HTML">HTML</a> et du <a href="/en-US/docs/Web/JavaScript">JavaScript</a>. L'élément <code><canvas></code> et WebGL ne sont pas supportés par certains anciens navigateurs, mais ils sont supportés dans les versions récentes de tous les principaux navigateurs. Pour dessiner des graphiques sur le canevas, on utilise un objet de contexte Javascript, qui crée des graphiques à la volée.</p> +L'utilisation de l'élément `<canvas>` n'est pas très difficile, mais vous avez besoin d'une compréhension de base de l'[HTML](/en-US/docs/Web/HTML) et du [JavaScript](/en-US/docs/Web/JavaScript). L'élément `<canvas>` et WebGL ne sont pas supportés par certains anciens navigateurs, mais ils sont supportés dans les versions récentes de tous les principaux navigateurs. Pour dessiner des graphiques sur le canevas, on utilise un objet de contexte Javascript, qui crée des graphiques à la volée. -<h2 id="Dans_ce_tutoriel">Dans ce tutoriel</h2> +## Dans ce tutoriel -<dl> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Commencer_avec_WebGL">Commencer avec WebGL</a></dt> - <dd>Comment mettre en place un contexte WebGL.</dd> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Ajouter_du_contenu_à_WebGL">Ajouter du contenu à WebGL</a></dt> - <dd>Comment faire un rendu simple de figures planes avec WebGL.</dd> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Ajouter_des_couleurs_avec_les_shaders">Ajouter des couleurs avec les nuanceurs</a></dt> - <dd>Démontre comment ajouter de la couleur aux formes avec des nuanceurs.</dd> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Animer_des_objets_avec_WebGL">Animer des objets avec WebGL</a></dt> - <dd>Montre comment tourner et déplacer des objets pour créer des animations simples.</dd> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Creer_des_objets_3D_avec_WebGL">Créer des objets 3D avec WebGL</a></dt> - <dd>Montre comment créer et animer un objet 3D (dans ce cas, un cube).</dd> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Utiliser_les_textures_avec_WebGL">Utilisation des textures dans WebGL</a></dt> - <dd>Démontrer comment appliquer des textures sur les faces d'un objet.</dd> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Eclairage_en_WebGL"> Éclairage en WebGL</a></dt> - <dd>Comment simuler des effets d'illumination dans votre contexte WebGL.</dd> - <dt><a href="/fr/docs/Web/API/WebGL_API/Tutorial/Animation_de_textures_en_WebGL">Animation de textures en WebGL</a></dt> - <dd>Montre comment animer des textures ; dans ce cas, en appliquant une vidéo Ogg sur les faces d'un cube en rotation.</dd> -</dl> +- [Commencer avec WebGL](/fr/docs/Web/API/WebGL_API/Tutorial/Commencer_avec_WebGL) + - : Comment mettre en place un contexte WebGL. +- [Ajouter du contenu à WebGL](/fr/docs/Web/API/WebGL_API/Tutorial/Ajouter_du_contenu_à_WebGL) + - : Comment faire un rendu simple de figures planes avec WebGL. +- [Ajouter des couleurs avec les nuanceurs](/fr/docs/Web/API/WebGL_API/Tutorial/Ajouter_des_couleurs_avec_les_shaders) + - : Démontre comment ajouter de la couleur aux formes avec des nuanceurs. +- [Animer des objets avec WebGL](/fr/docs/Web/API/WebGL_API/Tutorial/Animer_des_objets_avec_WebGL) + - : Montre comment tourner et déplacer des objets pour créer des animations simples. +- [Créer des objets 3D avec WebGL](/fr/docs/Web/API/WebGL_API/Tutorial/Creer_des_objets_3D_avec_WebGL) + - : Montre comment créer et animer un objet 3D (dans ce cas, un cube). +- [Utilisation des textures dans WebGL](/fr/docs/Web/API/WebGL_API/Tutorial/Utiliser_les_textures_avec_WebGL) + - : Démontrer comment appliquer des textures sur les faces d'un objet. +- [ Éclairage en WebGL](/fr/docs/Web/API/WebGL_API/Tutorial/Eclairage_en_WebGL) + - : Comment simuler des effets d'illumination dans votre contexte WebGL. +- [Animation de textures en WebGL](/fr/docs/Web/API/WebGL_API/Tutorial/Animation_de_textures_en_WebGL) + - : Montre comment animer des textures ; dans ce cas, en appliquant une vidéo Ogg sur les faces d'un cube en rotation. diff --git a/files/fr/web/api/webgl_api/tutorial/lighting_in_webgl/index.md b/files/fr/web/api/webgl_api/tutorial/lighting_in_webgl/index.md index e61f615228..d5da082872 100644 --- a/files/fr/web/api/webgl_api/tutorial/lighting_in_webgl/index.md +++ b/files/fr/web/api/webgl_api/tutorial/lighting_in_webgl/index.md @@ -4,38 +4,35 @@ slug: Web/API/WebGL_API/Tutorial/Lighting_in_WebGL translation_of: Web/API/WebGL_API/Tutorial/Lighting_in_WebGL original_slug: Web/API/WebGL_API/Tutorial/Eclairage_en_WebGL --- -<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Utiliser_les_textures_avec_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}}</p> +{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Utiliser_les_textures_avec_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}} -<p>La première chose à comprendre à propos de WebGL est que contrairement au standard OpenGL, WebGL n'a pas de support pour l'éclairage. Vous avez à le faire par vous même. Heureusement ce n'est pas si dur à faire, et cet article va vous expliquer quelques bases.</p> +La première chose à comprendre à propos de WebGL est que contrairement au standard OpenGL, WebGL n'a pas de support pour l'éclairage. Vous avez à le faire par vous même. Heureusement ce n'est pas si dur à faire, et cet article va vous expliquer quelques bases. -<h2 id="Simuler_l'éclairage_et_les_ombres_en_3D">Simuler l'éclairage et les ombres en 3D</h2> +## Simuler l'éclairage et les ombres en 3D -<p>Rentrer dans les détails de la théorie derrière la simulation de l'éclairage 3D est assez loin du sujet de cet article mais il vaut mieux en connaitre un minimum le sujet. Au lieu de rentrer dans le vif du sujet ici, jetez un coup d'oeil sur <a href="https://fr.wikipedia.org/wiki/Ombrage_de_Phong">l'ombrage de Phong</a> sur Wikipédia, qui fourni une bonne vue d'ensemble comme modèle d'éclairage.</p> +Rentrer dans les détails de la théorie derrière la simulation de l'éclairage 3D est assez loin du sujet de cet article mais il vaut mieux en connaitre un minimum le sujet. Au lieu de rentrer dans le vif du sujet ici, jetez un coup d'oeil sur [l'ombrage de Phong](https://fr.wikipedia.org/wiki/Ombrage_de_Phong) sur Wikipédia, qui fourni une bonne vue d'ensemble comme modèle d'éclairage. -<p>Il y a trois types basiques d'éclairage :</p> +Il y a trois types basiques d'éclairage : -<ol> - <li><strong>Ambient light (Lumière Ambiante) </strong>est la lumière qui imprègne, qui se répand sur la scène. Elle n'a pas de direction et s'applique sur toutes les faces de la scène de la même façon.</li> - <li><strong>Directional light (Lumière Directionnelle)</strong> est une lumière émise depuis une direction spécifique. Par exemple le soleil, est une lumière directionnelle.</li> - <li><strong>Point light</strong> <strong>(Point de lumière) </strong>est une lumière émise depuis un point, éméttant une lumière dans toutes les directions, contrairement à la Lumière Directionnelle. C'est comme ceci que les lumières fonctionnent principalement dans notre monde, comme par exemple une ampoule.</li> -</ol> +1. **Ambient light (Lumière Ambiante)** est la lumière qui imprègne, qui se répand sur la scène. Elle n'a pas de direction et s'applique sur toutes les faces de la scène de la même façon. +2. **Directional light (Lumière Directionnelle)** est une lumière émise depuis une direction spécifique. Par exemple le soleil, est une lumière directionnelle. +3. **Point light** **(Point de lumière)** est une lumière émise depuis un point, éméttant une lumière dans toutes les directions, contrairement à la Lumière Directionnelle. C'est comme ceci que les lumières fonctionnent principalement dans notre monde, comme par exemple une ampoule. -<p>Pour notre tutorial, nous allons simplifier le model d'éclairage, en considérant seulement une unique lumière directionnelle et une lumière ambiante. Nous allons réutiliser notre <a href="/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL">précédent exemple avec le cube en rotation</a>.</p> +Pour notre tutorial, nous allons simplifier le model d'éclairage, en considérant seulement une unique lumière directionnelle et une lumière ambiante. Nous allons réutiliser notre [précédent exemple avec le cube en rotation](/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL). -<p>Une fois que nous avons appréhendé le concept de source et de réfléction de la lumière, il y a deux choses que nous avons besoin d'implémenter pour nos lumières directionnelles.</p> +Une fois que nous avons appréhendé le concept de source et de réfléction de la lumière, il y a deux choses que nous avons besoin d'implémenter pour nos lumières directionnelles. -<ol> - <li>Nous avons besoin d'associer la <strong>surface normale</strong> avec chaque sommet. C'est un vecteur qui est perpendiculaire à la face associé à ce sommet.</li> - <li>Nous avons besoin de connaître la direction dans laquelle la lumière arrive. Ceci est défini par la direction du vecteur.</li> -</ol> +1. Nous avons besoin d'associer la **surface normale** avec chaque sommet. C'est un vecteur qui est perpendiculaire à la face associé à ce sommet. +2. Nous avons besoin de connaître la direction dans laquelle la lumière arrive. Ceci est défini par la direction du vecteur. -<p>Puis nous mettons à jour le vertex shader pour ajuster la couleur de chaque sommet. en prenant en compte la lumière ambiante ainsi que l'effet de la lumière directionnelle donné par l'angle qui rencontre la face du cube. Nous allons voir comment faire avec les shaders.</p> +Puis nous mettons à jour le vertex shader pour ajuster la couleur de chaque sommet. en prenant en compte la lumière ambiante ainsi que l'effet de la lumière directionnelle donné par l'angle qui rencontre la face du cube. Nous allons voir comment faire avec les shaders. -<h2 id="Créer_les_normales_pour_les_sommets">Créer les normales pour les sommets</h2> +## Créer les normales pour les sommets -<p>La première chose dont nous avons besoin, est de générer le tableau des <strong>normales</strong> pour tous les sommets que constituent notre cube. Comme un cube est un simple objet, c'est plutôt simple à faire, évidemment pour des objets plus complexe, calculer les normales sera plus compliqué.</p> +La première chose dont nous avons besoin, est de générer le tableau des **normales** pour tous les sommets que constituent notre cube. Comme un cube est un simple objet, c'est plutôt simple à faire, évidemment pour des objets plus complexe, calculer les normales sera plus compliqué. -<pre class="brush: js">cubeVerticesNormalBuffer = gl.createBuffer(); +```js +cubeVerticesNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer); var vertexNormals = [ @@ -77,33 +74,36 @@ var vertexNormals = [ ]; gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertexNormals), gl.STATIC_DRAW); -</pre> +``` -<p>Ceci doit vous être plutôt familier maintenant. Nous créons un nouveau buffer, on le lie avec le tableau sur lequel nous allons travailler, puis nous allons envoyer l'ensemble de notre tableau au buffer en appelant la méthode <code>bufferData()</code>.</p> +Ceci doit vous être plutôt familier maintenant. Nous créons un nouveau buffer, on le lie avec le tableau sur lequel nous allons travailler, puis nous allons envoyer l'ensemble de notre tableau au buffer en appelant la méthode `bufferData()`. -<p>Ensuite nous allons ajouter le code à la fonction <code>drawScene() </code>pour attacher le tableau de normales à l'attribut du shader, comme ça le code du shader y aura accès:</p> +Ensuite nous allons ajouter le code à la fonction `drawScene() `pour attacher le tableau de normales à l'attribut du shader, comme ça le code du shader y aura accès: -<pre class="brush: js">gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer); +```js +gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer); gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0); -</pre> +``` -<p>Enfin, nous avons besoin de mettre à jour le code qui construit les matrices uniformes pour générer et livrer au shader une matrice normale, qui sera utilisée pour transformer les normales en fonction de l'orientation actuelle du cube par rapport à la source de lumière.</p> +Enfin, nous avons besoin de mettre à jour le code qui construit les matrices uniformes pour générer et livrer au shader une matrice normale, qui sera utilisée pour transformer les normales en fonction de l'orientation actuelle du cube par rapport à la source de lumière. -<pre class="brush: js">var normalMatrix = mvMatrix.inverse(); +```js +var normalMatrix = mvMatrix.inverse(); normalMatrix = normalMatrix.transpose(); var nUniform = gl.getUniformLocation(shaderProgram, 'uNormalMatrix'); gl.uniformMatrix4fv(nUniform, false, new WebGLFloatArray(normalMatrix.flatten())); -</pre> +``` -<h2 id="Mettre_à_jour_les_shaders">Mettre à jour les shaders</h2> +## Mettre à jour les shaders -<p>Maintenant que les shaders ont toutes les données dont ils ont besoin, nous mettons à jour leur code.</p> +Maintenant que les shaders ont toutes les données dont ils ont besoin, nous mettons à jour leur code. -<h3 id="Le_vertex_shader">Le vertex shader</h3> +### Le vertex shader -<p>La première chose à faire est de mettre à jour le vertex shader en générant une valeur pour l'ombre de chaque sommet, en se basant sur l'éclairage ambiant ainsi que la direction de la lumière. Jettons un oeil sur le code suivant:</p> +La première chose à faire est de mettre à jour le vertex shader en générant une valeur pour l'ombre de chaque sommet, en se basant sur l'éclairage ambiant ainsi que la direction de la lumière. Jettons un oeil sur le code suivant: -<pre class="brush: html"><script id="shader-vs" type="x-shader/x-vertex"> +```html +<script id="shader-vs" type="x-shader/x-vertex"> attribute highp vec3 aVertexNormal; attribute highp vec3 aVertexPosition; attribute highp vec2 aTextureCoord; @@ -130,20 +130,21 @@ gl.uniformMatrix4fv(nUniform, false, new WebGLFloatArray(normalMatrix.flatten()) highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0); vLighting = ambientLight + (directionalLightColor * directional); } -</script> -</pre> +</script> +``` -<p>Une fois que la position du sommet est calculée, et que nous obtenons les coordonnées des texels (tas de pixel pour une texture) correspondant au sommet, nous pouvons travailler sur le calcul de l'ombre de chaque sommet.</p> +Une fois que la position du sommet est calculée, et que nous obtenons les coordonnées des texels (tas de pixel pour une texture) correspondant au sommet, nous pouvons travailler sur le calcul de l'ombre de chaque sommet. -<p>La première chose que nous allons faire est de transformer la base normale sur la position actuelle et l'orientation du cube, en calculant les normales des sommets par la matrice normale. Nous pouvons alors calculer la quantité d'éclairage qui doit être appliquée au sommet en calculant le produit de la normale transformée et du vecteur directionnel (la direction d'où la lumière vient). Si le résultat est inférieur à zéro, alors on le met à 0. Car une lumière négative n'a pas de sens dans notre cas.</p> +La première chose que nous allons faire est de transformer la base normale sur la position actuelle et l'orientation du cube, en calculant les normales des sommets par la matrice normale. Nous pouvons alors calculer la quantité d'éclairage qui doit être appliquée au sommet en calculant le produit de la normale transformée et du vecteur directionnel (la direction d'où la lumière vient). Si le résultat est inférieur à zéro, alors on le met à 0. Car une lumière négative n'a pas de sens dans notre cas. -<p>Une fois la quantité de lumière directionnelle calculée, nous pouvons générer la valeur d'éclairage en prenant l'éclairage ambiant et en y ajoutant le produit de la couleur de la lumière directionnelle, et aussi la quantité de la lumière directionnelle à fournir. Comme résultat, nous avons maintenant une valeur RGB qui sera utilisé par le fragment shader pour ajuster la couleur de chaque pixel.</p> +Une fois la quantité de lumière directionnelle calculée, nous pouvons générer la valeur d'éclairage en prenant l'éclairage ambiant et en y ajoutant le produit de la couleur de la lumière directionnelle, et aussi la quantité de la lumière directionnelle à fournir. Comme résultat, nous avons maintenant une valeur RGB qui sera utilisé par le fragment shader pour ajuster la couleur de chaque pixel. -<h3 id="Le_fragment_shader">Le fragment shader</h3> +### Le fragment shader -<p>Le fragment shader a maintenant besoin d'être mis à jour en prenant en compte la quantité de lumière calculée précédemment par le vertex shader:</p> +Le fragment shader a maintenant besoin d'être mis à jour en prenant en compte la quantité de lumière calculée précédemment par le vertex shader: -<pre class="brush: html"><script id="shader-fs" type="x-shader/x-fragment"> +```html +<script id="shader-fs" type="x-shader/x-fragment"> varying highp vec2 vTextureCoord; varying highp vec3 vLighting; @@ -154,23 +155,23 @@ gl.uniformMatrix4fv(nUniform, false, new WebGLFloatArray(normalMatrix.flatten()) gl_FragColor = vec4(texelColor.rgb * vLighting, texelColor.a); } -</script> -</pre> +</script> +``` + +Ici nous récupérons la couleur de chaque texel (tas de pixel pour une texture) , comme nous avons fait pour l'exemple précédent, mais avant d'ajuster la couleur du fragment, nous multiplions la couleur des pixels par la quantité de lumière, pour appliquer l'effet d'éclairage. -<p>Ici nous récupérons la couleur de chaque texel (tas de pixel pour une texture) , comme nous avons fait pour l'exemple précédent, mais avant d'ajuster la couleur du fragment, nous multiplions la couleur des pixels par la quantité de lumière, pour appliquer l'effet d'éclairage.</p> +Et c'est tout ! -<p>Et c'est tout !</p> -<p> </p> -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample7/index.html', 670, 510) }}</p> +{{EmbedGHLiveSample('webgl-examples/tutorial/sample7/index.html', 670, 510) }} -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample7">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample7/">Ouvrir cette démo dans une nouvelle page</a></p> +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample7) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample7/) -<h2 id="Exercices">Exercices</h2> +## Exercices -<p>Évidemment, ceci est un simple exemple, une implémentation basique de calcul de lumière par sommet. Pour aller plus loin, nous voulons implémenter un calcul de lumière par pixel, mais ceci vous mènera dans la bonne direction. </p> +Évidemment, ceci est un simple exemple, une implémentation basique de calcul de lumière par sommet. Pour aller plus loin, nous voulons implémenter un calcul de lumière par pixel, mais ceci vous mènera dans la bonne direction. -<p>Vous pouvez aussi implémenter avec la direction de source de lumière, la couleur de la source, la distance, etc..</p> +Vous pouvez aussi implémenter avec la direction de source de lumière, la couleur de la source, la distance, etc.. -<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}}</p> +{{PreviousNext("Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}} diff --git a/files/fr/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md b/files/fr/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md index 0bd4a47c5d..8b0ab94f97 100644 --- a/files/fr/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md +++ b/files/fr/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md @@ -7,112 +7,112 @@ tags: translation_of: Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL original_slug: Web/API/WebGL_API/Tutorial/Ajouter_des_couleurs_avec_les_shaders --- -<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}}</p> +{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}} -<p>Dans la <a href="/fr/docs/WebGL/Ajouter_du_contenu_à_WebGL">démonstration précédente</a>, nous avons créé un carré 2D, la prochaine étape évidente consiste à lui appliquer de la couleur. Nous allons faire cela en révisant les nuanceurs.</p> +Dans la [démonstration précédente](/fr/docs/WebGL/Ajouter_du_contenu_à_WebGL), nous avons créé un carré 2D, la prochaine étape évidente consiste à lui appliquer de la couleur. Nous allons faire cela en révisant les nuanceurs. -<h2 id="Application_de_couleur_aux_sommets">Application de couleur aux sommets</h2> +## Application de couleur aux sommets -<p>En WebGL, les objets sont construits en utilisant des sommets, chacun d'entre eux ayant une position et une couleur ; par défaut, les couleurs des autres sommets (et tous leurs autres attributs, incluant leur position) sont calculés en utilisant une interpolation linéaire, créant ainsi automatiquement des dégradés. Précédemment, notre nuanceur de sommet n'appliquait aucunes couleurs spécifiques aux sommets ; entre cela et le fait que le nuanceur de fragment assignait la valeur blanche à chaque pixel, le carré entier était rendu en blanc uni.</p> +En WebGL, les objets sont construits en utilisant des sommets, chacun d'entre eux ayant une position et une couleur ; par défaut, les couleurs des autres sommets (et tous leurs autres attributs, incluant leur position) sont calculés en utilisant une interpolation linéaire, créant ainsi automatiquement des dégradés. Précédemment, notre nuanceur de sommet n'appliquait aucunes couleurs spécifiques aux sommets ; entre cela et le fait que le nuanceur de fragment assignait la valeur blanche à chaque pixel, le carré entier était rendu en blanc uni. -<p>Supposons que nous voulions faire un rendu en dégradé dans lequel chaque coin du carré est de couleur différente : rouge, bleu, vert et blanc. La première chose à faire est de définir ces couleurs pour les quatre sommets. Pour ce faire, nous devons d'abord créer un tableau des couleurs des sommets, puis le stocker dans un tampon WebGL ; nous le ferons en ajoutant le code suivant à notre fonction <code>initBuffers()</code> :</p> +Supposons que nous voulions faire un rendu en dégradé dans lequel chaque coin du carré est de couleur différente : rouge, bleu, vert et blanc. La première chose à faire est de définir ces couleurs pour les quatre sommets. Pour ce faire, nous devons d'abord créer un tableau des couleurs des sommets, puis le stocker dans un tampon WebGL ; nous le ferons en ajoutant le code suivant à notre fonction `initBuffers()` : -<pre><code> const colors = [ - 1.0, 1.0, 1.0, 1.0, // blanc - 1.0, 0.0, 0.0, 1.0, // rouge - 0.0, 1.0, 0.0, 1.0, // vert - 0.0, 0.0, 1.0, 1.0, // bleu - ]; + const colors = [ + 1.0, 1.0, 1.0, 1.0, // blanc + 1.0, 0.0, 0.0, 1.0, // rouge + 0.0, 1.0, 0.0, 1.0, // vert + 0.0, 0.0, 1.0, 1.0, // bleu + ]; - const colorBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); + const colorBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); - return { - position: positionBuffer, - color: colorBuffer, - }; -}</code></pre> + return { + position: positionBuffer, + color: colorBuffer, + }; + } -<p>Ce code commence par créer un tableau JavaScript contenant des vecteurs à 4 valeurs, un pour chaque couleur de sommet. Un tampon WebGL est alors alloué pour stocker ces couleurs, et le tableau est converti en flottants et stocké dans le tampon.</p> +Ce code commence par créer un tableau JavaScript contenant des vecteurs à 4 valeurs, un pour chaque couleur de sommet. Un tampon WebGL est alors alloué pour stocker ces couleurs, et le tableau est converti en flottants et stocké dans le tampon. -<p>Pour que ces couleurs soient effectivement utilisées, le nuanceur de sommet doit être mis à jour pour extraire la couleur appropriée du tampon des couleurs :</p> +Pour que ces couleurs soient effectivement utilisées, le nuanceur de sommet doit être mis à jour pour extraire la couleur appropriée du tampon des couleurs : -<pre><code> const vsSource = ` - attribute vec4 aVertexPosition; - attribute vec4 aVertexColor; + const vsSource = ` + attribute vec4 aVertexPosition; + attribute vec4 aVertexColor; - uniform mat4 uModelViewMatrix; - uniform mat4 uProjectionMatrix; + uniform mat4 uModelViewMatrix; + uniform mat4 uProjectionMatrix; - varying lowp vec4 vColor; + varying lowp vec4 vColor; - void main(void) { - gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; - vColor = aVertexColor; - } - `;</code></pre> + void main(void) { + gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; + vColor = aVertexColor; + } + `; -<p>La différence clé est ici que, pour chaque sommet, nous passons sa couleur au nuanceur de fragment en utilisant un <code>varying</code>.</p> +La différence clé est ici que, pour chaque sommet, nous passons sa couleur au nuanceur de fragment en utilisant un `varying`. -<h2 id="Coloriage_des_fragments">Coloriage des fragments</h2> +## Coloriage des fragments -<p>Pour mémoire, voici à quoi ressemblait précédemment notre nuanceur de fragment :</p> +Pour mémoire, voici à quoi ressemblait précédemment notre nuanceur de fragment : -<pre><code> const fsSource = ` - void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); - } - `;</code></pre> + const fsSource = ` + void main() { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + `; -<p>Afin de choisir la couleur interpolée pour chaque pixel, nous devons le changer pour récupérer la valeur depuis le varying <code>vColor</code> :</p> +Afin de choisir la couleur interpolée pour chaque pixel, nous devons le changer pour récupérer la valeur depuis le varying `vColor` : -<pre><code> const fsSource = ` - varying lowp vec4 vColor; + const fsSource = ` + varying lowp vec4 vColor; - void main(void) { - gl_FragColor = vColor; - } - `;</code></pre> - -<p>La principale différence ici c'est que pour chaque sommet, on assigne la valeur correspondant à sa couleur dans le tableau.</p> - -<h2 id="Dessiner_en_utilisant_les_couleurs">Dessiner en utilisant les couleurs</h2> - -<p>Ensuite, il est nécessaire d'ajouter le code recherchant les couleurs dans l'emplacement de l'attribut, et de configurer cet attribut pour le programme nuanceur :</p> - -<pre><code> const programInfo = { - program: shaderProgram, - attribLocations: { - vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), - vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'), - }, - ...</code></pre> - -<p>Ensuite, <code>drawScene()</code> peut être modifié pour utiliser réellement ces couleurs lors du dessin du carré :</p> - -<pre><code> // Indiquer à WebGL comment transférer les couleurs du tampon des couleurs - // dans l'attribut vertexColor. - { - const numComponents = 4; - const type = gl.FLOAT; - const normalize = false; - const stride = 0; - const offset = 0; - gl.bindBuffer(gl.ARRAY_BUFFER, buffers.color); - gl.vertexAttribPointer( - programInfo.attribLocations.vertexColor, - numComponents, - type, - normalize, - stride, - offset); - gl.enableVertexAttribArray( - programInfo.attribLocations.vertexColor); - }</code></pre> - -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample3/index.html', 670, 510) }}</p> - -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample3">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample3/">Ouvrir cette démo dans une nouvelle page</a></p> - -<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}}</p> + void main(void) { + gl_FragColor = vColor; + } + `; + +La principale différence ici c'est que pour chaque sommet, on assigne la valeur correspondant à sa couleur dans le tableau. + +## Dessiner en utilisant les couleurs + +Ensuite, il est nécessaire d'ajouter le code recherchant les couleurs dans l'emplacement de l'attribut, et de configurer cet attribut pour le programme nuanceur : + + const programInfo = { + program: shaderProgram, + attribLocations: { + vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), + vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'), + }, + ... + +Ensuite, `drawScene()` peut être modifié pour utiliser réellement ces couleurs lors du dessin du carré : + + // Indiquer à WebGL comment transférer les couleurs du tampon des couleurs + // dans l'attribut vertexColor. + { + const numComponents = 4; + const type = gl.FLOAT; + const normalize = false; + const stride = 0; + const offset = 0; + gl.bindBuffer(gl.ARRAY_BUFFER, buffers.color); + gl.vertexAttribPointer( + programInfo.attribLocations.vertexColor, + numComponents, + type, + normalize, + stride, + offset); + gl.enableVertexAttribArray( + programInfo.attribLocations.vertexColor); + } + +{{EmbedGHLiveSample('webgl-examples/tutorial/sample3/index.html', 670, 510) }} + +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample3) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample3/) + +{{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}} diff --git a/files/fr/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md b/files/fr/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md index 002be155c6..7982addf80 100644 --- a/files/fr/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md +++ b/files/fr/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md @@ -7,275 +7,265 @@ tags: translation_of: Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL original_slug: Web/API/WebGL_API/Tutorial/Utiliser_les_textures_avec_WebGL --- -<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> - -<p>Maintenant que notre programme peut faire tourner un cube 3D, appliquons lui une texture, au lieu d'avoir des couleurs unies pour ses faces.</p> - -<h2 id="Chargement_des_textures">Chargement des textures</h2> - -<p>La première chose à faire est d'ajouter le code pour charger les textures. Dans notre cas, nous utiliserons une texture unique, appliquée à chacune des six faces de notre cube en rotation ; mais la même technique peut être utilisée un nombre quelconque de textures.</p> - -<div class="note"> - <p><strong>Note :</strong> il est important de noter que le chargement des textures suit les <a href="/fr-FR/docs/Web/HTTP/CORS">règles inter-domaines</a> ; donc vous pouvez seulement charger des textures depuis les sites pour lesquels votre contenu a l'approbation CORS. Voir les textures inter-domaines ci-dessous pour plus de détails.</p> -</div> - -<p>Le code qui charge la texture ressemble à ce qui suit : </p> - -<pre><code>// -// Initialiser une texture et charger une image. -// Quand le chargement d'une image est terminé, la copier dans la texture. -// -function loadTexture(gl, url) { - const texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - - // Du fait que les images doivent être téléchargées depuis l'internet, - // il peut s'écouler un certain temps avant qu'elles ne soient prêtes. - // Jusque là, mettre un seul pixel dans la texture, de sorte que nous puissions - // l'utiliser immédiatement. Quand le téléchargement de la page sera terminé, - // nous mettrons à jour la texture avec le contenu de l'image. - const level = 0; - const internalFormat = gl.RGBA; - const width = 1; - const height = 1; - const border = 0; - const srcFormat = gl.RGBA; - const srcType = gl.UNSIGNED_BYTE; - const pixel = new Uint8Array([0, 0, 255, 255]); // bleu opaque - gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, - width, height, border, srcFormat, srcType, - pixel); - - const image = new Image(); - image.onload = function() { - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, - srcFormat, srcType, image); - - // WebGL1 a des spécifications différentes pour les images puissances de 2 - // par rapport aux images non puissances de 2 ; aussi vérifier si l'image est une - // puissance de 2 sur chacune de ses dimensions. - if (isPowerOf2(image.width) && isPowerOf2(image.height)) { - // Oui, c'est une puissance de 2. Générer les mips. - gl.generateMipmap(gl.TEXTURE_2D); - } else { - // Non, ce n'est pas une puissance de 2. Désactiver les mips et définir l'habillage - // comme "accrocher au bord" - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); +{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} + +Maintenant que notre programme peut faire tourner un cube 3D, appliquons lui une texture, au lieu d'avoir des couleurs unies pour ses faces. + +## Chargement des textures + +La première chose à faire est d'ajouter le code pour charger les textures. Dans notre cas, nous utiliserons une texture unique, appliquée à chacune des six faces de notre cube en rotation ; mais la même technique peut être utilisée un nombre quelconque de textures. + +> **Note :** il est important de noter que le chargement des textures suit les [règles inter-domaines](/fr-FR/docs/Web/HTTP/CORS) ; donc vous pouvez seulement charger des textures depuis les sites pour lesquels votre contenu a l'approbation CORS. Voir les textures inter-domaines ci-dessous pour plus de détails. + +Le code qui charge la texture ressemble à ce qui suit : + + // + // Initialiser une texture et charger une image. + // Quand le chargement d'une image est terminé, la copier dans la texture. + // + function loadTexture(gl, url) { + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + + // Du fait que les images doivent être téléchargées depuis l'internet, + // il peut s'écouler un certain temps avant qu'elles ne soient prêtes. + // Jusque là, mettre un seul pixel dans la texture, de sorte que nous puissions + // l'utiliser immédiatement. Quand le téléchargement de la page sera terminé, + // nous mettrons à jour la texture avec le contenu de l'image. + const level = 0; + const internalFormat = gl.RGBA; + const width = 1; + const height = 1; + const border = 0; + const srcFormat = gl.RGBA; + const srcType = gl.UNSIGNED_BYTE; + const pixel = new Uint8Array([0, 0, 255, 255]); // bleu opaque + gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, + width, height, border, srcFormat, srcType, + pixel); + + const image = new Image(); + image.onload = function() { + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, + srcFormat, srcType, image); + + // WebGL1 a des spécifications différentes pour les images puissances de 2 + // par rapport aux images non puissances de 2 ; aussi vérifier si l'image est une + // puissance de 2 sur chacune de ses dimensions. + if (isPowerOf2(image.width) && isPowerOf2(image.height)) { + // Oui, c'est une puissance de 2. Générer les mips. + gl.generateMipmap(gl.TEXTURE_2D); + } else { + // Non, ce n'est pas une puissance de 2. Désactiver les mips et définir l'habillage + // comme "accrocher au bord" + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + } + }; + image.src = url; + + return texture; } - }; - image.src = url; - return texture; -} - -function isPowerOf2(value) { - return (value & (value - 1)) == 0; -}</code></pre> - -<p>La routine <code>loadTexture()</code> commence par créer un objet texture WebGL <code>texture</code> en appelant la fonction WebGL {{domxref ("WebGLRenderingContext.createTexture()", "createTexture()")}}. Il téléverse ensuite un seul pixel bleu en utilisant {{domxref ("WebGLRenderingContext.texImage2D()", "texImage2D()")}}. Cela rend la texture immédiatement utilisable comme une couleur bleue unie, alors que cela peut prendre quelques instants pour télécharger notre image.</p> - -<p>Pour charger la texture à partir du fichier image, elle crée ensuite un objet Image et en affecte le src à l'URL de l'image que nous souhaitons utiliser comme texture. La fonction que nous affectons à <code>image.onload</code> sera appelée une fois terminé le téléchargement de l'image. À ce stade, nous appelons à nouveau {{domxref ("WebGLRenderingContext.texImage2D()", "texImage2D()")}}, cette fois en utilisant l'image comme source pour la texture. Après cela, nous configurons le filtrage et l'habillage de la texture suivant que l'image que nous téléchargeons a ou non une puissance de 2 selon ses deux dimensions.</p> - -<p>WebGL1 ne peut utiliser que des textures non puissances de 2 avec d'un filtrage défini à NEAREST ou LINEAR, et il ne peut pas générer de mipmap pour elles. Leur mode d'habillage doit également être défini à CLAMP_TO_EDGE. Inversement, si la texture est une puissance de 2 dans les deux dimensions, alors WebGL peut faire un filtrage de meilleure qualité, il peut utiliser mipmap, et il peut définir le mode d'habillage à REPEAT ou MIRRORED_REPEAT.</p> + function isPowerOf2(value) { + return (value & (value - 1)) == 0; + } -<p>Un exemple de texture répétée est le pavage d'une image par quelques briques pour couvrir un mur de briques.</p> +La routine `loadTexture()` commence par créer un objet texture WebGL `texture` en appelant la fonction WebGL {{domxref ("WebGLRenderingContext.createTexture()", "createTexture()")}}. Il téléverse ensuite un seul pixel bleu en utilisant {{domxref ("WebGLRenderingContext.texImage2D()", "texImage2D()")}}. Cela rend la texture immédiatement utilisable comme une couleur bleue unie, alors que cela peut prendre quelques instants pour télécharger notre image. -<p>Le mipmapping et la répétition UV peuvent être désactivés avec {{domxref ("WebGLRenderingContext.texParameter()", "texParameteri()")}}. Cela permettra des textures non-puissances-de-deux (NPOT) au prix du mipmapping, de l'habillage UV, du pavage UV, et de votre contrôle sur la manière dont le périphérique gérera votre texture.</p> +Pour charger la texture à partir du fichier image, elle crée ensuite un objet Image et en affecte le src à l'URL de l'image que nous souhaitons utiliser comme texture. La fonction que nous affectons à `image.onload` sera appelée une fois terminé le téléchargement de l'image. À ce stade, nous appelons à nouveau {{domxref ("WebGLRenderingContext.texImage2D()", "texImage2D()")}}, cette fois en utilisant l'image comme source pour la texture. Après cela, nous configurons le filtrage et l'habillage de la texture suivant que l'image que nous téléchargeons a ou non une puissance de 2 selon ses deux dimensions. -<pre><code>// gl.NEAREST est aussi permis, au lieu de gl.LINEAR, du fait qu'aucun ne fait de mipmap. -gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); -// Empêcher l'habillage selon la coordonnée s (répétition). -gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); -// Empêcher l'habillage selon la coordonnée t (répétition). -gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);</code></pre> +WebGL1 ne peut utiliser que des textures non puissances de 2 avec d'un filtrage défini à NEAREST ou LINEAR, et il ne peut pas générer de mipmap pour elles. Leur mode d'habillage doit également être défini à CLAMP_TO_EDGE. Inversement, si la texture est une puissance de 2 dans les deux dimensions, alors WebGL peut faire un filtrage de meilleure qualité, il peut utiliser mipmap, et il peut définir le mode d'habillage à REPEAT ou MIRRORED_REPEAT. -<p>A nouveau, avec ces paramètres, les appareils WebGL compatibles accepteront automatiquement toute résolution pour cette texture (jusqu'à leurs dimensions maximum). A défaut de la configuration ci-dessus, WebGL requiert que tous les échantillons de textures NPOT échouent, en retournant du noir transparent : <code>rgba (0,0,0,0)</code>.</p> +Un exemple de texture répétée est le pavage d'une image par quelques briques pour couvrir un mur de briques. -<p>Pour charger l'image, ajoutons un appel à notre fonction <code>loadTexture()</code> dans notre fonction <code>main()</code>. Cela peut être ajouté après l'appel <code>initBuffers(gl)</code>.</p> +Le mipmapping et la répétition UV peuvent être désactivés avec {{domxref ("WebGLRenderingContext.texParameter()", "texParameteri()")}}. Cela permettra des textures non-puissances-de-deux (NPOT) au prix du mipmapping, de l'habillage UV, du pavage UV, et de votre contrôle sur la manière dont le périphérique gérera votre texture. -<pre><code>// Charger la texture -const texture = loadTexture(gl, 'cubetexture.png');</code> -</pre> + // gl.NEAREST est aussi permis, au lieu de gl.LINEAR, du fait qu'aucun ne fait de mipmap. + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + // Empêcher l'habillage selon la coordonnée s (répétition). + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + // Empêcher l'habillage selon la coordonnée t (répétition). + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); -<h2 id="Application_de_la_texture_sur_les_faces">Application de la texture sur les faces</h2> +A nouveau, avec ces paramètres, les appareils WebGL compatibles accepteront automatiquement toute résolution pour cette texture (jusqu'à leurs dimensions maximum). A défaut de la configuration ci-dessus, WebGL requiert que tous les échantillons de textures NPOT échouent, en retournant du noir transparent : `rgba (0,0,0,0)`. -<p>À ce stade, la texture est chargée et prête à être utilisée. Mais avant de pouvoir l'utiliser, nous devons définir l'application des coordonnées de texture aux sommets des faces de notre cube. Cela remplace tout le code précédemment existant pour la configuration des couleurs pour chacune des faces du cube dans <code>initBuffers()</code>.</p> +Pour charger l'image, ajoutons un appel à notre fonction `loadTexture()` dans notre fonction `main()`. Cela peut être ajouté après l'appel `initBuffers(gl)`. -<pre><code> const textureCoordBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); + // Charger la texture + const texture = loadTexture(gl, 'cubetexture.png'); - const textureCoordinates = [ - // Front - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - // Back - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - // Top - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - // Bottom - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - // Right - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - // Left - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - ]; +## Application de la texture sur les faces - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), - gl.STATIC_DRAW); +À ce stade, la texture est chargée et prête à être utilisée. Mais avant de pouvoir l'utiliser, nous devons définir l'application des coordonnées de texture aux sommets des faces de notre cube. Cela remplace tout le code précédemment existant pour la configuration des couleurs pour chacune des faces du cube dans `initBuffers()`. -... - return { - position: positionBuffer, - textureCoord: textureCoordBuffer, - indices: indexBuffer, - };</code></pre> + const textureCoordBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); -<p>Tout d'abord, ce code crée un tampon WebGL dans lequel nous stockerons les coordonnées de texture pour chaque face, puis nous lions ce tampon comme étant le tableau dans lequel nous allons écrire.</p> + const textureCoordinates = [ + // Front + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // Back + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // Top + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // Bottom + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // Right + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // Left + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + ]; -<p>Le tableau <code>textureCoordinates</code> définit les coordonnées de texture correspondant à chaque sommet de chaque face. Notez que les coordonnées de texture vont de 0,0 à 1,0 ; les dimensions des textures sont normalisées dans une plage de 0,0 à 1,0 quelque soit leur taille réelle, aux fins d'application de la texture.</p> + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), + gl.STATIC_DRAW); -<p>Une fois que nous avons mis en place le tableau d'application de la texture, nous l'envoyons dans le tampon, de sorte que WebGL ait ces données prêtes pour son utilisation.</p> + ... + return { + position: positionBuffer, + textureCoord: textureCoordBuffer, + indices: indexBuffer, + }; -<h2 id="Mise_à_jour_des_shaders">Mise à jour des shaders</h2> +Tout d'abord, ce code crée un tampon WebGL dans lequel nous stockerons les coordonnées de texture pour chaque face, puis nous lions ce tampon comme étant le tableau dans lequel nous allons écrire. -<p>Le programme shader doit également être mis à jour pour utiliser des textures au lieu de couleurs unies.</p> +Le tableau `textureCoordinates` définit les coordonnées de texture correspondant à chaque sommet de chaque face. Notez que les coordonnées de texture vont de 0,0 à 1,0 ; les dimensions des textures sont normalisées dans une plage de 0,0 à 1,0 quelque soit leur taille réelle, aux fins d'application de la texture. -<h3 id="Le_shader_de_sommet">Le shader de sommet</h3> +Une fois que nous avons mis en place le tableau d'application de la texture, nous l'envoyons dans le tampon, de sorte que WebGL ait ces données prêtes pour son utilisation. -<p>Nous avons besoin de remplacer le shader de sommet de façon à ce qu'au lieu de récupérer des données de couleur, il récupère à la place des données de coordonnées de texture.</p> +## Mise à jour des shaders -<pre><code>const vsSource = ` - attribute vec4 aVertexPosition; - attribute vec2 aTextureCoord; +Le programme shader doit également être mis à jour pour utiliser des textures au lieu de couleurs unies. - uniform mat4 uModelViewMatrix; - uniform mat4 uProjectionMatrix; +### Le shader de sommet - varying highp vec2 vTextureCoord; +Nous avons besoin de remplacer le shader de sommet de façon à ce qu'au lieu de récupérer des données de couleur, il récupère à la place des données de coordonnées de texture. - void main(void) { - gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; - vTextureCoord = aTextureCoord; - } - `;</code></pre> + const vsSource = ` + attribute vec4 aVertexPosition; + attribute vec2 aTextureCoord; -<p>Le changement clé est ici qu'au lieu d'aller chercher la couleur du sommet, nous récupérons les coordonnées de la texture, et nous les transmettons au shader de sommet ; ceci indiquera l'emplacement dans la texture correspondant au sommet.</p> + uniform mat4 uModelViewMatrix; + uniform mat4 uProjectionMatrix; -<h3 id="Le_shader_de_fragment">Le shader de fragment</h3> + varying highp vec2 vTextureCoord; -<p>Le shader de fragment doit également être mis à jour :</p> + void main(void) { + gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; + vTextureCoord = aTextureCoord; + } + `; -<pre><code>const fsSource = ` - varying highp vec2 vTextureCoord; +Le changement clé est ici qu'au lieu d'aller chercher la couleur du sommet, nous récupérons les coordonnées de la texture, et nous les transmettons au shader de sommet ; ceci indiquera l'emplacement dans la texture correspondant au sommet. - uniform sampler2D uSampler; +### Le shader de fragment + +Le shader de fragment doit également être mis à jour : + + const fsSource = ` + varying highp vec2 vTextureCoord; + + uniform sampler2D uSampler; + + void main(void) { + gl_FragColor = texture2D(uSampler, vTextureCoord); + } + `; + +Au lieu d'attribuer une valeur de couleur à la couleur du fragment, la couleur du fragment est calculée en récupérant le **texel** (c'est-à-dire, le pixel dans la texture) sur la base de la valeur de `vTextureCoord`, qui est interpolée comme les sommets. + +### Emplacements des attributs et des uniformes + +Du fait que nous avons changé un attribut et ajouté un uniforme, nous devons rechercher leurs emplacements : + + const programInfo = { + program: shaderProgram, + attribLocations: { + vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), + textureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'), + }, + uniformLocations: { + projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), + modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), + uSampler: gl.getUniformLocation(shaderProgram, 'uSampler'), + }, + }; + +## Dessin du cube texturé + +Les modifications apportées à la fonction `drawScene()` sont simples. + +Tout d'abord, le code pour spécifier le tampon de couleurs a disparu, remplacé par ce qui suit : - void main(void) { - gl_FragColor = texture2D(uSampler, vTextureCoord); + // Indiquer à WebGL comment extraire les coordonnées de texture du tampon + { + const num = 2; // chaque coordonnée est composée de 2 valeurs + const type = gl.FLOAT; // les données dans le tampon sont des flottants 32 bits + const normalize = false; // ne pas normaliser + const stride = 0; // combien d'octets à récupérer entre un jeu et le suivant + const offset = 0; // à combien d'octets du début faut-il commencer + gl.bindBuffer(gl.ARRAY_BUFFER, buffers.textureCoord); + gl.vertexAttribPointer(programInfo.attributeLocations.textureCoord, num, type, normalize, stride, offset); + gl.enableVertexAttribArray(programInfo.attributeLocations.textureCoord); } - `;</code></pre> - -<p>Au lieu d'attribuer une valeur de couleur à la couleur du fragment, la couleur du fragment est calculée en récupérant le <strong>texel</strong> (c'est-à-dire, le pixel dans la texture) sur la base de la valeur de <code>vTextureCoord</code>, qui est interpolée comme les sommets.</p> - -<h3 id="Emplacements_des_attributs_et_des_uniformes">Emplacements des attributs et des uniformes</h3> - -<p>Du fait que nous avons changé un attribut et ajouté un uniforme, nous devons rechercher leurs emplacements :</p> - -<pre><code> const programInfo = { - program: shaderProgram, - attribLocations: { - vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), - textureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'), - }, - uniformLocations: { - projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), - modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), - uSampler: gl.getUniformLocation(shaderProgram, 'uSampler'), - }, - };</code> -</pre> - -<h2 id="Dessin_du_cube_texturé">Dessin du cube texturé</h2> - -<p>Les modifications apportées à la fonction <code>drawScene()</code> sont simples.</p> - -<p>Tout d'abord, le code pour spécifier le tampon de couleurs a disparu, remplacé par ce qui suit :</p> - -<pre><code>// Indiquer à WebGL comment extraire les coordonnées de texture du tampon -{ - const num = 2; // chaque coordonnée est composée de 2 valeurs - const type = gl.FLOAT; // les données dans le tampon sont des flottants 32 bits - const normalize = false; // ne pas normaliser - const stride = 0; // combien d'octets à récupérer entre un jeu et le suivant - const offset = 0; // à combien d'octets du début faut-il commencer - gl.bindBuffer(gl.ARRAY_BUFFER, buffers.textureCoord); - gl.vertexAttribPointer(programInfo.attributeLocations.textureCoord, num, type, normalize, stride, offset); - gl.enableVertexAttribArray(programInfo.attributeLocations.textureCoord); -}</code></pre> -<p>Ajoutez alors le code pour spécifier la texture à appliquer sur les faces, juste avant de dessiner :</p> +Ajoutez alors le code pour spécifier la texture à appliquer sur les faces, juste avant de dessiner : -<pre><code> // Indiquer à WebGL que nous voulons affecter l'unité de texture 0 - gl.activeTexture(gl.TEXTURE0); + // Indiquer à WebGL que nous voulons affecter l'unité de texture 0 + gl.activeTexture(gl.TEXTURE0); - // Lier la texture à l'unité de texture 0 - gl.bindTexture(gl.TEXTURE_2D, texture); + // Lier la texture à l'unité de texture 0 + gl.bindTexture(gl.TEXTURE_2D, texture); - // Indiquer au shader que nous avons lié la texture à l'unité de texture 0 - gl.uniform1i(programInfo.uniformLocations.uSampler, 0);</code></pre> + // Indiquer au shader que nous avons lié la texture à l'unité de texture 0 + gl.uniform1i(programInfo.uniformLocations.uSampler, 0); -<p>WebGL fournit un minimum de 8 unités de texture ; la première d'entre elles est <code>gl.TEXTURE0</code>. Nous indiquons à WebGL que nous voulons affecter l'unité 0. Nous appelons alors {{domxref ("WebGLRenderingContext.bindTexture()", "bindTexture()")}}, qui lie la texture au point de liaison <code>TEXTURE_2D</code> de l'unité de texture 0. Nous indiquons alors au shader que pour l'<code>uSampler</code>, il faut utiliser l'unité de texture 0.</p> +WebGL fournit un minimum de 8 unités de texture ; la première d'entre elles est `gl.TEXTURE0`. Nous indiquons à WebGL que nous voulons affecter l'unité 0. Nous appelons alors {{domxref ("WebGLRenderingContext.bindTexture()", "bindTexture()")}}, qui lie la texture au point de liaison `TEXTURE_2D` de l'unité de texture 0. Nous indiquons alors au shader que pour l'`uSampler`, il faut utiliser l'unité de texture 0. -<p>Finalement, ajoutez <code>texture</code> comme paramètre de la fonction <code>drawScene()</code>, où elle est à la fois définie et appelée.</p> +Finalement, ajoutez `texture` comme paramètre de la fonction `drawScene()`, où elle est à la fois définie et appelée. -<pre><code>drawScene(gl, programInfo, buffers, texture, deltaTime); -... -function drawScene(gl, programInfo, buffers, texture, deltaTime) {</code></pre> + drawScene(gl, programInfo, buffers, texture, deltaTime); + ... + function drawScene(gl, programInfo, buffers, texture, deltaTime) { -<p>Arrivés ce point, le cube en rotation devrait être prêt à fonctionner.</p> +Arrivés ce point, le cube en rotation devrait être prêt à fonctionner. -<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample6/index.html', 670, 510) }}</p> +{{EmbedGHLiveSample('webgl-examples/tutorial/sample6/index.html', 670, 510) }} -<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample6">Voir le code complet</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample6/">Ouvrir cette démo dans une nouvelle page</a></p> +[Voir le code complet](https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample6) | [Ouvrir cette démo dans une nouvelle page](http://mdn.github.io/webgl-examples/tutorial/sample6/) -<h2 id="Textures_inter-domaines">Textures inter-domaines</h2> +## Textures inter-domaines -<p>Le chargement des textures WebGL est soumis aux contrôles d'accès inter-domaines. Pour que votre contenu puisse charger une texture d'un autre domaine, une approbation CORS doit être obtenue. Voir le <a href="/fr/docs/HTTP/Access_control_CORS">Contrôle d'accès HTTP</a> pour plus de détails sur CORS.</p> +Le chargement des textures WebGL est soumis aux contrôles d'accès inter-domaines. Pour que votre contenu puisse charger une texture d'un autre domaine, une approbation CORS doit être obtenue. Voir le [Contrôle d'accès HTTP](/fr/docs/HTTP/Access_control_CORS) pour plus de détails sur CORS. -<p>Voir cet <a href="http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/">article sur hacks.mozilla.org</a> pour une explication de l'utilisation des images approuvées CORS comme textures WebGL, avec <a href="http://people.mozilla.org/~bjacob/webgltexture-cors-js.html">un exemple complet</a>.</p> +Voir cet [article sur hacks.mozilla.org](http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/) pour une explication de l'utilisation des images approuvées CORS comme textures WebGL, avec [un exemple complet](http://people.mozilla.org/~bjacob/webgltexture-cors-js.html). -<div class="note"> -<p><strong>Note :</strong> le support CORS pour les texture WebGL et l'attribut <code>crossOrigin</code> pour les éléments image est implémenté dans {{Gecko("8.0")}}.</p> -</div> +> **Note :** le support CORS pour les texture WebGL et l'attribut `crossOrigin` pour les éléments image est implémenté dans {{Gecko("8.0")}}. -<p>Les canevas 2D dégradés (en écriture seule) ne peuvent pas être utilisés comme des textures WebGL. Un {{HTMLElement ("canvas")}} 2D devient dégradé par exemple lorsqu'il est utilisé pour dessiner une image inter-domaine.</p> +Les canevas 2D dégradés (en écriture seule) ne peuvent pas être utilisés comme des textures WebGL. Un {{HTMLElement ("canvas")}} 2D devient dégradé par exemple lorsqu'il est utilisé pour dessiner une image inter-domaine. -<div class="note"> -<p><strong>Note :</strong> le support CORS pour <code>drawImage</code> de Canvas 2D est implémenté dans {{Gecko ("9.0")}}. Cela signifie que l'utilisation d'une image inter-domaine ayant l'approbation CORS ne dégrade plus le canevas 2D, de sorte que le canevas 2D reste utilisable comme source d'une texture WebGL.</p> -</div> +> **Note :** le support CORS pour `drawImage` de Canvas 2D est implémenté dans {{Gecko ("9.0")}}. Cela signifie que l'utilisation d'une image inter-domaine ayant l'approbation CORS ne dégrade plus le canevas 2D, de sorte que le canevas 2D reste utilisable comme source d'une texture WebGL. -<div class="note"> -<p><strong>Note :</strong> le support CORS pour les vidéos inter-domaines et l'attribut <code>crossorigin</code> pour les éléments {{HTMLElement ("video")}} est implémenté dans {{Gecko ("12.0")}}.</p> -</div> +> **Note :** le support CORS pour les vidéos inter-domaines et l'attribut `crossorigin` pour les éléments {{HTMLElement ("video")}} est implémenté dans {{Gecko ("12.0")}}. -<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> +{{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} |