2017-04-20 6 views
0

Je suis donc à la recherche d'aide sur les textures WebGL/rendu 3D. Le but de mon code (ce que j'ai fait jusqu'à présent) est de créer un labyrinthe 3D de blocs/cubes texturés que l'utilisateur peut parcourir via les touches fléchées ou WASD. Le problème que j'ai est juste avec texImage2d() je crois.Problèmes WebGL texImage2D: Comment obtenir une texture sur une unité/un objet?

J'ai essayé des choses comme

var stonePic = document.getElementById("stoneTex"); 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, stonePic)); 

qui ne fonctionne pas et a donné lieu à this.

J'ai essayé aussi

var stonePic = new Image(); 
stonePic.src = "stoneWall2.png"; 

qui a abouti à la même erreur.

Qu'est-ce que je fais mal? Est-ce que je peux le réparer?

<HTML> 
    <HEAD> 
     <TITLE>Brick Wall Maze</TITLE> 
    <SCRIPT> 

    //VERTEX SHADER TEXT 
    var vertexShaderText = 
    [ 
     'precision mediump float;', 
     '', 
     'attribute vec3 vertPosition;', 
     'attribute vec2 vertTexCoord;', 
     'varying vec2 fragTexCoord;', 
     'uniform vec3 theta;', 
     'uniform vec3 trans;', 
     'uniform float thetaC;', 
     'uniform vec3 camLoc;', 
     'void main()', 
     '{', 
     'fragTexCoord = vertTexCoord;', 
     'vec3 c = cos(theta);', 
     'vec3 s = sin(theta);', 
     '', 
     'mat4 ry = mat4(c.y,0.0,-1.0*s.y,0.0, 0.0,1.0,0.0,0.0, s.y,0.0,c.y,0.0, 0.0,0.0,0.0,1.0);', 
     'mat4 translate = mat4(1,0,0,0, 0,1,0,0, 0,0,1,0, trans.x,trans.y,trans.z,1);', 
     'vec4 tempLoc = vec4(vertPosition, 1.0);', 

     'float l = -1.0;', 
     'float r = 1.0;', 
     'float t = 1.0;', 
     'float b = -1.0;', 
     'float f = 100.0;', 
     'float n = 1.0;', 
     'mat4 perspective = mat4(2.0*n/(r-l),0,0,0, 0,2.0*n/(t-b),0,0, (r+l)/(r-l),(t+b)/(t-b),-1.0*(f+n)/(f-n),-1.0, 0,0,-2.0*f*n/(f-n),0);', 

     'float tempc = cos(thetaC);', 
     'float temps = sin(thetaC);', 
     'mat4 camRY = mat4(tempc,0,-1.0*temps,0, 0,1,0,0, temps,0,tempc,0, 0,0,0,1);', 
     'mat4 viewM = mat4(1.0,0,0,0, 0,1.0,0,0, 0,0,1.0,0, camLoc.x,camLoc.y,camLoc.z,1.0);', 
     'gl_Position = perspective * camRY * viewM * translate * ry * tempLoc;', 
     '}' 
    ].join("\n"); 

    // FRAGMENT SHADER TEXT 
    var fragmentShaderText = 
    [ 
     'precision mediump float;', 
     'varying vec2 fragTexCoord;', 
     'uniform sampler2D sampler;', 
     'void main()', 
     '{', 
     'gl_FragColor = texture2D(sampler, fragTexCoord);', 
     '}' 
    ].join('\n'); 

    // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 

    function initializeGL() 
    { 
     var canvas = document.getElementById("screen"); 
     var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); 
     if (!gl) { alert("WEBGL IS NOT AVAILABLE"); } 

     gl.viewport(0, 0, canvas.width, canvas.height); 
     gl.clearColor(0.5, 0.7, 0.6 ,1.0); 
     gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT); 
     gl.enable(gl.DEPTH_TEST); 

     return gl; 
    } 

    function initializeShaders(gl) 
    { 
     // VERTEX SHADER 
     var vertexShader = gl.createShader(gl.VERTEX_SHADER); 
     gl.shaderSource(vertexShader, vertexShaderText); 
     gl.compileShader(vertexShader); 
     if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { 
      console.log("ERROR: ",gl.getShaderInfoLog(vertexShader)); 
     } 

     // FRAGMENT SHADER 
     var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); 
     gl.shaderSource(fragmentShader,fragmentShaderText); 
     gl.compileShader(fragmentShader); 
     if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { 
      console.log("ERROR: ",gl.getShaderInfoLog(fragmentShader)); 
     } 

     // PROGRAM 
     var program = gl.createProgram(); 
     gl.attachShader(program, vertexShader); 
     gl.attachShader(program, fragmentShader); 

     gl.linkProgram(program); 
     if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 
      console.error("ERROR", gl.getShaderInfoLog(program)); 
     } 

     gl.validateProgram(program); 
     if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) { 
      console.error("ERROR", gl.getShaderInfoLog(program)); 
     } 

     return program; 
    } 

    // var brickTexture; 
    var stoneTexture; 

    function setupIndBuffers(gl, program, buffer) 
    { 
     gl.bindBuffer(gl.ARRAY_BUFFER, buffer);  
     positionAttributeLocation = gl.getAttribLocation(program, "vertPosition"); 
     texCoordAttributeLocation = gl.getAttribLocation(program, "vertTexCoord"); 
     gl.vertexAttribPointer(
     positionAttributeLocation, //ATTRIBUTE LOCATION 
     3, //NUMBER of elements per attribute 
     gl.FLOAT, //TYPES OF ELEMENTS 
     gl.FALSE, 
     5*Float32Array.BYTES_PER_ELEMENT, //SIZE OF AN INDIVIDUAL VERTEX 
     0 //OFFSET 
     ); 


     gl.vertexAttribPointer(
     texCoordAttributeLocation, //ATTRIBUTE LOCATION 
     2, //NUMBER of elements per attribute 
     gl.FLOAT, //TYPES OF ELEMENTS 
     gl.FALSE, 
     5*Float32Array.BYTES_PER_ELEMENT, //SIZE OF AN INDIVIDUAL VERTEX 
     3*Float32Array.BYTES_PER_ELEMENT //OFFSET 
     ); 

     gl.enableVertexAttribArray(positionAttributeLocation); 
     gl.enableVertexAttribArray(texCoordAttributeLocation); 
    } 

    function setupVertices(gl, program) 
    { 
     /* 
     // Brick Texture 
     brickTexture = gl.createTexture(); 
     gl.bindTexture(gl.TEXTURE_2D, brickTexture); 

     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT); 

     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 

     var brickArray = []; 

     for (i = 0; i < 16; i++) { 
      for (j = 0; j < 16; j++) { 
       if (i == 0 || j == 0) { 
        // Push Black 
        brickArray.push(0, 0, 255); 
       } 
       else { 
        // Push Red 
        brickArray.push(220, 30, 30, 255); 
       } 
      } 
     } 

     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(brickArray)); 
     gl.bindTexture(gl.TEXTURE_2D, null); 
     */ 

     // ~ ~ ~ ~ ~ 
     // STONE TEXTURE 
     stoneTexture = gl.createTexture(); 
     gl.bindTexture(gl.TEXTURE_2D, stoneTexture); 

     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.NEAREST); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 

     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, stonePic); 

     gl.bindTexture(gl.TEXTURE_2D, null); 
    } 

    /* 
    brickVertices = 
    [ 
     // X, Y, Z  U, V,    

     // Top 
     -1.0, 1.0, -1.0, 0.0, 0.0, 
     -1.0, 1.0, 1.0, 0.0, 10, 
     1.0, 1.0, 1.0,  10, 10, 
     1.0, 1.0, -1.0, 10, 0.0, 

     // Left 
     -1.0, 1.0, 1.0, 10,10, 
     -1.0, -1.0, 1.0, 0,10, 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, 1.0, -1.0, 10,0, 

     // Right 
     1.0, 1.0, 1.0, 10,10, 
     1.0, -1.0, 1.0, 0,10, 
     1.0, -1.0, -1.0, 0,0, 
     1.0, 1.0, -1.0, 10,0, 

     // Front 
     1.0, 1.0, 1.0,  10,10, 
     1.0, -1.0, 1.0, 10,0, 
     -1.0, -1.0, 1.0, 0,0, 
     -1.0, 1.0, 1.0, 0,10, 

     // Back 
     1.0, 1.0, -1.0,  10,10, 
     1.0, -1.0, -1.0, 10,0, 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, 1.0, -1.0, 0,10, 

     // Bottom 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, -1.0, 1.0, 0,10, 
     1.0, -1.0, 1.0,  10,10, 
     1.0, -1.0, -1.0, 10,0, 
    ]; 
    */ 

    stoneVertices = 
    [ 
     // X, Y, Z  U, V, 

     // Top 
     -1.0, 1.0, -1.0, 0.0, 0.0, 
     -1.0, 1.0, 1.0, 0.0, 1.0, 
     1.0, 1.0, 1.0,  1.0, 1.0, 
     1.0, 1.0, -1.0, 1.0, 0.0, 

     // Left 
     -1.0, 1.0, 1.0, 1,1, 
     -1.0, -1.0, 1.0, 0,1, 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, 1.0, -1.0, 1,0, 

     // Right 
     1.0, 1.0, 1.0, 1,1, 
     1.0, -1.0, 1.0, 0,1, 
     1.0, -1.0, -1.0, 0,0, 
     1.0, 1.0, -1.0, 1,0, 

     // Front 
     1.0, 1.0, 1.0,  1,1, 
     1.0, -1.0, 1.0, 1,0, 
     -1.0, -1.0, 1.0, 0,0, 
     -1.0, 1.0, 1.0, 0,1, 

     // Back 
     1.0, 1.0, -1.0,  1,1, 
     1.0, -1.0, -1.0, 1,0, 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, 1.0, -1.0, 0,1, 

     // Bottom 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, -1.0, 1.0, 0,1, 
     1.0, -1.0, 1.0,  1,1, 
     1.0, -1.0, -1.0, 1,0, 
     ]; 

    /* 
    stoneVertices = 
    [ 
     // X, Y, Z  U, V,    

     // Top 
     -1.0, 1.0, -1.0, 0.0, 0.0, 
     -1.0, 1.0, 1.0, 0.0, 1.0, 
     1.0, 1.0, 1.0,  1.0, 1.0, 
     1.0, 1.0, -1.0, 1.0, 0.0, 

     // Left 
     -1.0, 1.0, 1.0, 1,1, 
     -1.0, -1.0, 1.0, 0,1, 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, 1.0, -1.0, 1,0, 

     // Right 
     1.0, 1.0, 1.0, 1,1, 
     1.0, -1.0, 1.0, 0,1, 
     1.0, -1.0, -1.0, 0,0, 
     1.0, 1.0, -1.0, 1,0, 

     // Front 
     1.0, 1.0, 1.0,  1,1, 
     1.0, -1.0, 1.0, 1,0, 
     -1.0, -1.0, 1.0, 0,0, 
     -1.0, 1.0, 1.0, 0,1, 

     // Back 
     1.0, 1.0, -1.0,  1,1, 
     1.0, -1.0, -1.0, 1,0, 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, 1.0, -1.0, 0,1, 

     // Bottom 
     -1.0, -1.0, -1.0, 0,0, 
     -1.0, -1.0, 1.0, 0,1, 
     1.0, -1.0, 1.0,  1,1, 
     1.0, -1.0, -1.0, 1,0, 
     ]; 
     */ 

     class Cube 
     { 
      constructor(test) 
      { 
       this.tranLoc = gl.getUniformLocation(program, "trans"); 
       this.thetaLoc = gl.getUniformLocation(program, "theta"); 
       this.loc = [0, 0, 0]; 

       if(test) { 
        this.verts = stoneBuffer; 
        this.texture = stoneTexture; 
       } 
       /*else { 
        this.verts = stoneBuffer; 
        this.texture = stoneTexture; 
       }*/ 

       this.boxIndices = 
       [ 
        // Top 
        0, 1, 2, 
        0, 2, 3, 
        // Left 
        5, 4, 6, 
        6, 4, 7, 
        // Right 
        8, 9, 10, 
        8, 10, 11, 
        // Front 
        13, 12, 14, 
        15, 14, 12, 
        // Back 
        16, 17, 18, 
        16, 18, 19, 
        // Bottom 
        21, 20, 22, 
        22, 20, 23 
       ]; 

       this.iBuffer = gl.createBuffer(); 

       gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.iBuffer); 
       gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(this.boxIndices), gl.STATIC_DRAW); 
       gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 
      } 

      render() 
      { 
       if (this.texture == stoneTexture) { 
        //gl.bindBuffer(gl.ARRAY_BUFFER,brickBuffer); 
        setupIndBuffers(gl, program, stoneBuffer); 
       } 
       /*else { 
        //gl.bindBuffer(gl.ARRAY_BUFFER,this.crateBuffer); 
        setupIndBuffers(gl, program, brickBuffer); 
       }*/ 

       gl.bindTexture(gl.TEXTURE_2D, this.texture); 
       gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.iBuffer); 
       var thetaV = [0, 0, 0]; 
       gl.uniform3fv(this.tranLoc, new Float32Array(this.loc)); 
       gl.uniform3fv(this.thetaLoc, new Float32Array(thetaV)); 
       gl.drawElements(gl.TRIANGLES, this.boxIndices.length, gl.UNSIGNED_BYTE, 0); 
       gl.bindTexture(gl.TEXTURE_2D, null);  
       gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 
       gl.bindBuffer(gl.ARRAY_BUFFER, null); 
      } 
     } 

    </SCRIPT> 
    </HEAD> 

    <BODY> 
     <CANVAS ID = "screen" WIDTH = "800" HEIGHT = "600" ALT = "Your browser does not support canvas."/> 
     <IMG ID = "stoneTex" SRC = "stoneWall2.png" WIDTH = "50" HEIGHT = "50" ALT = "tex"/> 

    <SCRIPT> 
    //Init GL System 
    var gl = initializeGL(); 
    var program = initializeShaders(gl); 
    setupVertices(gl, program); 
    gl.useProgram(program); 
    //var stonePic = document.getElementById("stoneTex"); 

    // SETUP BRICK BUFFER 
    /*var brickBuffer = gl.createBuffer(); 
    setupIndBuffers(gl, program, brickBuffer); 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(brickVertices), gl.STATIC_DRAW); 
    gl.bindBuffer(gl.ARRAY_BUFFER, null); 
    */ 

    // SETUP STONE BUFFER 
    var stoneBuffer = gl.createBuffer(); 
    setupIndBuffers(gl, program, stoneBuffer); 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(stoneVertices), gl.STATIC_DRAW); 
    gl.bindBuffer(gl.ARRAY_BUFFER, null); 

    // Initialize and render actual objects. 
    var x = new Cube(true); 
    x.loc = [-5, 0, -10]; 
    //var y = new Cube(false); 
    //y.loc = [5, 0, -10]; 

    var loop = function() 
    { 
     gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT); 
     x.render(); 
     requestAnimationFrame(loop); 
    } 

    requestAnimationFrame(loop); 
    </SCRIPT> 
    </BODY> 
    </HTML> 
+0

Ajouter code extrait, s'il vous plaît –

Répondre

0

Ce que vous faites mal n'attend pas le chargement des images. Les images dans les navigateurs Web sont téléchargées de manière asynchrone. Cela signifie que vous devez attendre pour télécharger avant d'appeler gl.texImage2D

Normalement, je ferais quelque chose comme ça

// Create a texture. 
 
var texture = gl.createTexture(); 
 
gl.bindTexture(gl.TEXTURE_2D, texture); 
 
    
 
// Fill the texture with a 1x1 blue pixel. 
 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, 
 
       new Uint8Array([0, 0, 255, 255])); 
 
    
 
// Asynchronously load an image 
 
var image = new Image(); 
 
image.src = "resources/f-texture.png"; 
 
image.addEventListener('load', function() { 
 
    // Now that the image has loaded make copy it to the texture. 
 
    gl.bindTexture(gl.TEXTURE_2D, texture); 
 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, image); 
 
    // if it's a power of 2 in both dimensions then 
 
    // we can generate mips, otherwise we'd have to do other things 
 
    gl.generateMipmap(gl.TEXTURE_2D); 
 
});

texture est maintenant une texture et vous pouvez commencer à rendre avec elle immédiatement. Lorsque l'image a fini de télécharger, son contenu sera copié sur la texture. À ce moment-là, vous devez soit de rendre à nouveau ou, si comme la plupart des applications de WebGL, et celui de la question, vous rendant en continu alors il apparaîtra automatiquement la prochaine fois que votre application rend

See these articles