baobao
3/22/2018 - 3:39 PM

textureMapping.html

<!DOCTYPE html>
<html>
<head>
<title>Texture Mapping</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="minMatrix.js"></script>
<script src="textureMapping.js"></script>
<script id="vs" type="x-shader/vertex">
attribute vec3 pos;
attribute vec2 uv;
uniform mat4 mvpMatrix;
varying vec2 vUv;

void main()
{
    vUv = uv;
    gl_Position = mvpMatrix * vec4(pos, 1.0);
}
</script>
<script id="fs" type="x-shader/fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 vUv;

void main()
{
//    gl_FragColor = vec4(1.0);
//    return;
    vec4 texColor = texture2D(tex, vUv);
    gl_FragColor = vec4(texColor.xyz, 1.0);
}

</script>
</head>
<body>
    <canvas id="canvas"></canvas>
</body>
</html>
window.onload = function()
{
    console.log("entry");
    var canvas = document.getElementById('canvas');
    canvas.width = canvas.height = 300;
    var gl = canvas.getContext('webgl');
    
    // Load Texture
    var img = new Image();
    img.onload = function()
    {
        console.log("load complete texture.");
        gl.activeTexture(gl.TEXTURE0);
        var tex = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, tex);
        gl.texImage2D(
            // target
            gl.TEXTURE_2D, 
            // Mipmap Level
            0,
            // internal format
            // テクスチャ内のカラーコンポーネント
            gl.RGBA,
            // format
            // テクセルデータの形式指定
            // internal formatと同じにする必要あり
            gl.RGBA,
            // type
            // テクセルデータのデータ型
            // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D
            gl.UNSIGNED_BYTE,
            // ImageクラスはHTMLImageElement
            // https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement
            img);
        // これ必要らしい
        gl.generateMipmap(gl.TEXTURE_2D);
        gl.bindTexture(gl.TEXTURE_2D, null);
        
        start(tex);
    };
    img.src = "img.png";
    
    function start (tex)
    {
        console.log(tex);
        var vs = gl.createShader(gl.VERTEX_SHADER);
        var fs = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(vs, document.getElementById('vs').text);
        gl.shaderSource(fs, document.getElementById('fs').text);
        gl.compileShader(vs);
        gl.compileShader(fs);
        var prog = gl.createProgram();
        gl.attachShader(prog, vs);
        gl.attachShader(prog, fs);
        gl.linkProgram(prog);
        if (gl.getProgramParameter(prog, gl.LINK_STATUS))
        {
            gl.useProgram(prog);
        }else{
            console.error(gl.getProgramInfoLog(prog));
            return;
        }
        
        var len = 0.5;
        var vertex = [
            -len, len, 0,
            len, len, 0,
            len, -len, 0,
            -len, -len, 0
        ];
        var index = [
            0, 1, 3,
            2, 3, 1
        ];
        var uv = [
            0.0, 0.0,
            1.0, 0.0,
            1.0, 1.0,
            0.0, 1.0
        ];
        
        var attrList = [];
        var strideList = [];
        var uniformList = [];
        
        attrList[0] = gl.getAttribLocation(prog, 'pos');
        attrList[1] = gl.getAttribLocation(prog, 'uv');
        strideList[0] = 3;
        strideList[1] = 2;
        uniformList[0] = gl.getUniformLocation(prog, 'mvpMatrix');
        uniformList[1] = gl.getUniformLocation(prog, 'tex');
        
        console.log(attrList);
        console.log(uniformList);
        
        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertex), gl.STATIC_DRAW);
        gl.enableVertexAttribArray(attrList[0]);
        gl.vertexAttribPointer(attrList[0], strideList[0], gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
        
        vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(uv), gl.STATIC_DRAW);
        gl.enableVertexAttribArray(attrList[1]);
        gl.vertexAttribPointer(attrList[1], strideList[1], gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
        
        var ibo = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array(index), gl.STATIC_DRAW);
        
        // matrix
        var m = new matIV();
        var mMatrix = m.identity(m.create());
        var vMatrix = m.identity(m.create());
        var pMatrix = m.identity(m.create());
        var vpMatrix = m.identity(m.create());
        var mvpMatrix = m.identity(m.create());
        
        m.lookAt([0,0,3],[0,0,0],[0,1,0],vMatrix);
        m.perspective(60, 1, 0.1, 1000, pMatrix);
        
        m.multiply(pMatrix, vMatrix, vpMatrix);
        
        gl.enable(gl.DEPTH_TEST);
        
        var count = 0;
        draw();
        function draw()
        {
            gl.clearColor(0.2,0.2,0.2,1);
            gl.clear(gl.COLOR_BUFFER_BIT);
            
            m.identity(mMatrix);
            m.rotate(mMatrix, 2*count++*Math.PI/180, [0,1,0], mMatrix);
            m.multiply(vpMatrix, mMatrix, mvpMatrix);
            gl.uniformMatrix4fv(uniformList[0], false, mvpMatrix);
            
            gl.bindTexture(gl.TEXTURE_2D, tex);
            gl.uniform1i(uniformList[1], 0);
            
            // void gl.drawElements(mode, count, type, offset);
            gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, false, 0);
            
            gl.bindTexture(gl.TEXTURE_2D, null);
            
            setTimeout(draw, 1000/30);
        }
    }
};