SOURCE

console 命令行工具 X clear

                    
>
console
var gl = null;
var defaultProgram = null;
var squareBuffer = null;
var canvasSize = { width: 0, height: 0};
var perspectiveMatrix = null;
var viewMatrix = null;
var modelMatrix = null;
var woodTexture = null;
var canvasId = null;

function setupGLEnv(canvasID) {
    canvasId = canvasID
    var canvas = document.getElementById(canvasID);
    canvasSize.width = canvas.width;
    canvasSize.height = canvas.height;
    gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
    if (!gl) {
      alert('Unable to initialize WebGL. Your browser may not support it.');
    }

    defaultProgram = makeProgram();
    makeBuffer();
    makeMatrix();
    makeTexture();
}

function makeShader(shaderSrc, shaderType) {
    shader = gl.createShader(shaderType);
    gl.shaderSource(shader, shaderSrc);
    gl.compileShader(shader);
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {  
        console.log('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));  
        gl.deleteShader(shader);
        return null;  
    } 
    return shader;
}

function resize(newWidth, newHeight) {
    var canvas = document.getElementById(canvasId);
    canvas.width = newWidth;
    canvas.height = newHeight;
    canvasSize.width = newWidth;
    canvasSize.height = newHeight;
    perspectiveMatrix = mat4.create();
    aspect = canvasSize.width / canvasSize.height;
    mat4.perspective(perspectiveMatrix, 90 / 180.0 * 3.1415, aspect, 0.01, 1000);
}

function makeProgram() {
    program = gl.createProgram();

    vertexShaderNode = document.getElementById("shader-vs");
    vertexShader = makeShader(vertexShaderNode.textContent, gl.VERTEX_SHADER);
    fragmentShaderNode = document.getElementById("shader-fs");
    fragmentShader = makeShader(fragmentShaderNode.textContent, gl.FRAGMENT_SHADER);
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);

    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
       console.log('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program));
    }
    return program;
}

function makeBuffer() {
    var square = [
    // X轴0.5处的平面
               0.5, -0.5, 0.5, 1, 0, 0, 0, 0,
               0.5, -0.5, -0.5, 1, 0, 0, 0, 1,
               0.5, 0.5, -0.5, 1, 0, 0, 1, 1,
               0.5, 0.5, -0.5, 1, 0, 0, 1, 1,
               0.5, 0.5, 0.5, 1, 0, 0, 1, 0,
               0.5, -0.5, 0.5, 1, 0, 0, 0, 0,
               // X轴-0.5处的平面
               -0.5, -0.5, 0.5, -1, 0, 0, 0, 0,
               -0.5, -0.5, -0.5, -1, 0, 0, 0, 1,
               -0.5, 0.5, -0.5, -1, 0, 0, 1, 1,
               -0.5, 0.5, -0.5, -1, 0, 0, 1, 1,
               -0.5, 0.5, 0.5, -1, 0, 0, 1, 0,
               -0.5, -0.5, 0.5, -1, 0, 0, 0, 0,

               -0.5, 0.5, 0.5, 0, 1, 0, 0, 0,
               -0.5, 0.5, -0.5, 0, 1, 0, 0, 1,
               0.5, 0.5, -0.5, 0, 1, 0, 1, 1,
               0.5, 0.5, -0.5, 0, 1, 0, 1, 1,
               0.5, 0.5, 0.5, 0, 1, 0, 1, 0,
               -0.5, 0.5, 0.5, 0, 1, 0, 0, 0,
               -0.5, -0.5, 0.5, 0, -1, 0, 0, 0,
               -0.5, -0.5, -0.5, 0, -1, 0, 0, 1,
               0.5, -0.5, -0.5, 0, -1, 0, 1, 1,
               0.5, -0.5, -0.5, 0, -1, 0, 1, 1,
               0.5, -0.5, 0.5, 0, -1, 0, 1, 0,
               -0.5, -0.5, 0.5, 0, -1, 0, 0, 0,

               -0.5, 0.5, 0.5, 0, 0, 1, 0, 0,
               -0.5, -0.5, 0.5, 0, 0, 1, 0, 1,
               0.5, -0.5, 0.5, 0, 0, 1, 1, 1,
               0.5, -0.5, 0.5, 0, 0, 1, 1, 1,
               0.5, 0.5, 0.5, 0, 0, 1, 1, 0,
               -0.5, 0.5, 0.5, 0, 0, 1, 0, 0,
               -0.5, 0.5, -0.5, 0, 0, -1, 0, 0,
               -0.5, -0.5, -0.5, 0, 0, -1, 0, 1,
               0.5, -0.5, -0.5, 0, 0, -1, 1, 1,
               0.5, -0.5, -0.5, 0, 0, -1, 1, 1,
               0.5, 0.5, -0.5, 0, 0, -1, 1, 0,
               -0.5, 0.5, -0.5, 0, 0, -1, 0, 0,
    ];
    squareBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(square), gl.STATIC_DRAW);
    return squareBuffer;
}

function makeMatrix() {
    perspectiveMatrix = mat4.create();
    aspect = canvasSize.width / canvasSize.height;
    mat4.perspective(perspectiveMatrix, 90 / 180.0 * 3.1415, aspect, 0.01, 1000);

    viewMatrix = mat4.create();
    mat4.lookAt(viewMatrix, vec3.fromValues(0.0, 1, 2), vec3.fromValues(0, 0, 0), vec3.fromValues(0, 1, 0));

    modelMatrix = mat4.create();
    mat4.rotate(modelMatrix, modelMatrix, 3.14 * 0.2, vec3.fromValues(1, 1, 1));
}

function makeTexture() {
    woodTexture = gl.createTexture();
    woodImage = new Image();
    woodImage.crossOrigin = "";
    woodImage.onload = function () {
        gl.bindTexture(gl.TEXTURE_2D, woodTexture);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, woodImage);
        gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
        gl.generateMipmap(gl.TEXTURE_2D);
        gl.bindTexture(gl.TEXTURE_2D, null);
    }
    woodImage.src = "https://squarepants1991.github.io/public/webgl-experiment/wood.jpeg";
}

function render(deltaTime, elapsedTime) {
    gl.viewport(0, 0, canvasSize.width, canvasSize.height);
    gl.clearColor(.0, .0, .0, 0.0);
    gl.enable(gl.DEPTH_TEST);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    // update model matrix by elapsedTime
    modelMatrix = mat4.create();
    mat4.rotate(modelMatrix, modelMatrix, elapsedTime / 1000.0 , vec3.fromValues(1, 1, 1));

    if (defaultProgram) {
        gl.useProgram(defaultProgram);
        gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);

        posLoc = gl.getAttribLocation(defaultProgram, "position");
        gl.enableVertexAttribArray(posLoc);
        gl.vertexAttribPointer(posLoc, 3, gl.FLOAT, false, 4 * 8, 0);

        normalLoc = gl.getAttribLocation(defaultProgram, "normal");
        gl.enableVertexAttribArray(normalLoc);
        gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 4 * 8, 4 * 3);

        uvLoc = gl.getAttribLocation(defaultProgram, "uv");
        gl.enableVertexAttribArray(uvLoc);
        gl.vertexAttribPointer(uvLoc, 2, gl.FLOAT, false, 4 * 8, 4 * 6);

        perspectiveMatrixLoc = gl.getUniformLocation(defaultProgram, "perspectiveMatrix");
        gl.uniformMatrix4fv(perspectiveMatrixLoc, false, perspectiveMatrix);

        viewMatrixLoc = gl.getUniformLocation(defaultProgram, "viewMatrix");
        gl.uniformMatrix4fv(viewMatrixLoc, false, viewMatrix);

        modelMatrixLoc = gl.getUniformLocation(defaultProgram, "modelMatrix");
        gl.uniformMatrix4fv(modelMatrixLoc, false, modelMatrix);

        diffuseLoc = gl.getUniformLocation(defaultProgram, "diffuse");
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, woodTexture);
        gl.uniform1i(diffuseLoc, 0);

        gl.drawArrays(gl.TRIANGLES, 0, 36);
    }
}


var lastRenderTime = (new Date()).getTime(); // 上次渲染的时间
var elapsedTime = 0; // 经过的总时间
var glInfoNode = null;
var collectedFrameCount = 0;
var collectedFrameDuration = 0;
var canvas = null;
window.onresize = function() {
  resize(canvas.parentElement.clientWidth, canvas.parentElement.clientHeight - 1);
}
window.onload = function() {
  glInfoNode = document.getElementById("glInfo");
  setupGLEnv('glCanvas');
  canvas = document.getElementById("glCanvas");
  resize(canvas.parentElement.clientWidth, canvas.parentElement.clientHeight - 1);
  renderLoop();
}
function renderLoop() {
  now = (new Date()).getTime();
  deltaTime = now - lastRenderTime;
  lastRenderTime = now;
  elapsedTime += deltaTime;
  render(deltaTime, elapsedTime);
  collectedFrameDuration += deltaTime;
  collectedFrameCount++;
  if (collectedFrameCount >= 10) {
    fps = parseInt(1000.0 * collectedFrameCount / collectedFrameDuration);
    if (isNaN(fps) == false || fps < 1000) {
      glInfoNode.textContent = "FPS: " + fps;
    }
    collectedFrameCount = 0;
    collectedFrameDuration = 0;
  }
  requestAnimationFrame(renderLoop);
}
requestAnimationFrame(renderLoop);
<script type="x-shader/vertex-shader" id="shader-vs">
            attribute vec3 position;
            attribute vec3 normal;
            attribute vec2 uv;
            varying vec3 frag_position;
            varying vec3 frag_normal;
            varying vec2 frag_uv; 
            uniform mat4 perspectiveMatrix;
            uniform mat4 viewMatrix;
            uniform mat4 modelMatrix;
            void main() {
                frag_position = position;
                frag_normal = normal;
                frag_uv = uv;
                mat4 mvp = perspectiveMatrix * viewMatrix * modelMatrix;
                gl_Position = mvp * vec4(position, 1.0);
            }
</script>
<script type="x-shader/fragment-shader" id="shader-fs">
            precision highp float;
            varying vec3 frag_position;
            varying vec3 frag_normal;
            varying vec2 frag_uv;
            uniform sampler2D diffuse; 
            void main() {
                vec4 texColor = texture2D(diffuse, frag_uv);
                gl_FragColor = texColor;
            }
</script>
<div style="width: 100%; height: 300px; position:relative; background:rgba(0,0,0,0);">
  <canvas id="glCanvas" width="400" height="300">
    Your browser doesn't appear to support the 
    <code>&lt;canvas&gt;</code> element.
  </canvas>
  <div id="glInfo" style=""></div>
</div>
* {
  margin: 0px;
  padding: 0px;
}
#glInfo {
  font-size: 13px;
  color: #ffffff;
  position:absolute;
  top:8px; 
  left:10px;
}

本项目引用的自定义外部资源