Créer une texture WebGL à partir d’une photo

Utilisez une photo afin de créer une texture WebGL pour l’exemple Warp.

Chargement de la photo

WebGL utilise des photos pour créer des textures qui rendent les formes plus réalistes ou plus utiles. Bien que vous puissiez utiliser une photo de n’importe quelle taille dans l’exemple Warp, WebGL nécessite que l’image soit dans une taille définie. Pour permettre la mise à l’échelle de l’image de votre choix, l’exemple utilise un processus en trois étapes afin de créer une texture WebGL.

Le code et les étapes qui suivent décrivent la façon dont l’exemple Warp utilise des commandes de zone de dessin 2D pour mettre à l’échelle une image avant de la charger en tant que texture.

Ce code obtient l’image, la met à l’échelle et la place sur une zone de dessin 2D.


// load a the user's image.
this.loadImageX = function (dataURL) {
    var image = new Image();
    
    image.onload = function () {
        renderer.loadImage2(image);
    }

    image.src = dataURL;
}

// This function does the heavy lifting of creating the texture from the image.
this.loadImage2 = function (image) {
    // Convert the image to a square image via the temporary 2d canvas. 
    var canvas = document.getElementById("2dcanvas");
    var ctx = canvas.getContext("2d");
    var canvHeight = document.getElementById("2dcanvas").height;

    var x = 0;
    var y = 0;
    var xx = canvHeight;
    var yy = canvHeight;

    ctx.clearRect(0, 0, canvHeight, canvHeight);
    // If image isn't square, adjust width, height, and origin so it's centered.
       if (image.width < image.height) {
        // Change origin and dimensions if the image isn't square.
        // Change x, xx
        xx = image.width / image.height * canvHeight;
        x = (canvHeight - xx) / 2;
    }
    if (image.width > image.height) {
        // Change y, yy 
      yy = image.height / image.width * canvHeight;
      y = (canvHeight - yy) / 2;
    }

// Put the image on the canvas, scaled using xx & yy.
    ctx.drawImage(image, 0, 0, image.width, image.height, x, y, xx, yy);


  1. Créez un objet Image et un événement pour appeler la fonction loadImage2, une fois le chargement de la photo terminé.
  2. Une fois le chargement de l’image terminé, loadImage2 est appelé.
  3. LoadImage2 obtient la zone de dessin 2D à partir du code HTML via document.getElementById.
  4. À l’aide de la zone de dessin, la fonction obtient alors le contexte 2D de l’élément de zone de dessin via getContext("2d").
  5. Obtenez la hauteur de la zone de dessin et créez quatre variables : origin x, origin y, height et width, qui servent à placer l’image sur la zone de dessin. Dans la mesure où la zone de dessin est carrée, la hauteur est utilisée pour la hauteur et la largeur.
  6. Effacez la zone de dessin via clearRect.
  7. Obtenez la plus grande dimension de l’image. Si l’image n’est pas carrée, calculez une hauteur ou une largeur mise à l’échelle, et un décalage dans la zone de dessin pour le côté le plus court.
  8. Placez l’image sur la zone de dessin à l’aide de drawImage. La méthode drawImage place l’image sur la zone de dessin à une origine spécifique et la met à l’échelle automatiquement en fonction de l’origine, de la hauteur et de la largeur spécifiées pour la zone de dessin.

LoadImage2 crée un objet de texture et charge l’image à partir de la zone de dessin en suivant les étapes ci-après :


// Create a texture object that will contain the image.
var texture = gl.createTexture();

// Bind the texture the target (TEXTURE_2D) of the active texture unit.
gl.bindTexture(gl.TEXTURE_2D, texture);

// Flip the image's Y axis to match the WebGL texture coordinate space.
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    
// Set the parameters so we can render any size image.        
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);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

  // Upload the resized canvas image into the texture.
//    Note: a canvas is used here but can be replaced by an image object. 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);


  1. Obtenir le contexte WebGL (gl) et créer un objet WebGLTexture à l’aide de createTexture. CreateTexture accepte l’objet WebGLTexture et le type de texture à utiliser (TEXTURE_2D ou TEXTURE_CUBE_MAP). L’exemple Warp utilise TEXTURE_2D.
  2. Lier la texture pour la rendre active à l’aide de bindTexture. Le fait de rendre cette texture active entraîne l’utilisation de cette dernière durant les opérations de texture ultérieures.
  3. Modifier le système de coordonnées de la texture afin de faire correspondre le système de coordonnées de texture WebGL à pixelStorei. L’utilisation de l’indicateur UNPACK_FLIP_Y_WEBGL modifie l’axe Y en remplaçant zéro dans le coin supérieur gauche par zéro dans le coin inférieur gauche. Consultez la remarque ci-dessous.
  4. Utilisez texParameteri avec TEXTURE_WRAP_S et TEXTURE_WRAP_T pour spécifier la façon dont WebGL doit gérer l’habillage d’une image. Ces constantes indiquent à WebGL comment remplir les zones sur le côté ou en haut et en bas, durant le remplissage d’une zone plus grande que l’image. Le paramètre CLAMP_TO_EDGE indique à WebGL qu’il faut disposer l’image en mosaïque. Par exemple, si vous échantillonnez l’image à la coordonnée 1.5, cela revient à l’échantillonner à .5.
  5. Utilisez également texParameteri avec les constantes TEXTURE_MIN_FILTER et TEXTURE_MAX_FILTER pour spécifier la façon dont les couleurs sont calculées. L’indicateur LINEAR indique à WebGL qu’il faut utiliser les quatre pixels les plus proches pour calculer la couleur des nouveaux pixels quand la texture dépasse la taille initiale.
  6. L’image est chargée dans la texture à l’aide de texImage2D avec le type de texture cible (TEXTURE_2D), le niveau (toujours 0), le format interne et le format d’image (tous les deux RGBA), le type de données de texture (UNSIGNED_BYTE) et enfin l’image (dans le cas présent, la zone de dessin 2D).
  7. Effacez la zone de dessin avec clearRect.

Remarque  

Les textures utilisent un système appelé système de coordonnées s/t avec comme origine 0,0 dans l’angle inférieur gauche, un axe s horizontal et un axe t vertical. Pour vous en rappeler, pensez aux expressions « Sur le côté » et « Tout en haut », qui correspondent en anglais à « to the side » et « to the top ». Nous y reviendrons plus tard. Le système s/t diffère du système de coordonnées x/y/z normalement associé à WebGL. Durant la copie d’une image dans une texture, vous pouvez définir texImage2D pour retourner l’image en cas de transfert vers l’unité GPU via pixelStorei. Pour passer la photo d’un système de coordonnées où le coin supérieur gauche est l’origine (0,0) au système s/t, où l’origine (0,0) se trouve dans le coin inférieur gauche, appelez pixelStorei avec l’indicateur UNPACK_FLIP_Y_WEBGL. Cela peut avoir une importance durant l’utilisation simultanée de plusieurs textures.

Dans Prise en charge de l’interface utilisateur, vous disposez d’une vue d’ensemble de l’exemple, de l’obtention d’un fichier, du mouvement de la souris et de l’enregistrement des fichiers.

Rubriques connexes

Utiliser GLSL pour écrire des nuanceurs WebGL
Prise en charge de l’interface utilisateur
Démonstrations, références et ressources WebGL

 

 

Afficher:
© 2014 Microsoft