07、给正方体六个面贴图

创建日期:2024-07-08
更新日期:2025-01-12
<!DOCTYPE html>

<html lang="zh-CN">

<head>
    <meta charset="UTF-8" />
    <title>07_给正方体六个面贴图</title>
    <script src="../js/three.js"></script>

    <!-- 顶点着色器 -->
    <script id="shader-vs" type="x-shader/x-vertex">
        attribute vec3 aVertexPosition;
        attribute vec2 aTextureCoord;

        uniform mat4 uMVMatrix;

        varying vec2 vTextureCoord;

        void main(void) {
        gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;
        }
    </script>

    <!-- 片源着色器 -->
    <script id="shader-fs" type="x-shader/x-fragment">
        precision mediump float;

        uniform sampler2D uSampler;

        varying vec2 vTextureCoord;

        void main(void) {
        gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
        }
    </script>

    <script type="text/javascript">
        var start = function () {
            // 上下文环境
            var canvas = document.getElementById("mycanvas");
            var gl = canvas.getContext("experimental-webgl");
            gl.viewportWidth = canvas.width;
            gl.viewportHeight = canvas.height;
            gl.viewport(0, 0, gl.viewportWidth, gl.viewportWidth);
            gl.enable(gl.DEPTH_TEST);

            // 顶点着色器
            var shader = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(shader, document.getElementById('shader-vs').textContent);
            gl.compileShader(shader);
            var vertexShader = shader;

            // 片源着色器
            var shader = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(shader, document.getElementById('shader-fs').textContent);
            gl.compileShader(shader);
            var fragmentShader = shader;

            // 着色器程序
            var shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);
            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);

            // 获取参数地址
            var vertexPositionAttr = gl.getAttribLocation(shaderProgram, 'aVertexPosition');
            gl.enableVertexAttribArray(vertexPositionAttr);
            var textureCoordAttr = gl.getAttribLocation(shaderProgram, 'aTextureCoord');
            gl.enableVertexAttribArray(textureCoordAttr);
            var mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
            var samplerUniform = gl.getUniformLocation(shaderProgram, 'uSampler');

            // 顶点位置
            var vertices = [
                // 前面
                 -0.5, -0.5, -0.5,
                 0.5, -0.5, -0.5,
                 0.5, 0.5, -0.5,
                 -0.5, 0.5, -0.5,

                 // 后面
                 -0.5, -0.5, 0.5,
                 0.5, -0.5, 0.5,
                 0.5, 0.5, 0.5,
                 -0.5, 0.5, 0.5,

                 // 左面
                 -0.5, -0.5, 0.5,
                 -0.5, -0.5, -0.5,
                 -0.5, 0.5, -0.5,
                 -0.5, 0.5, 0.5,

                 // 右面
                 0.5, -0.5, -0.5,
                 0.5, -0.5, 0.5,
                 0.5, 0.5, 0.5,
                 0.5, 0.5, -0.5,

                 // 上面
                 -0.5, 0.5, -0.5,
                 0.5, 0.5, -0.5,
                 0.5, 0.5, 0.5,
                 -0.5, 0.5, 0.5,

                 // 下面
                 -0.5, -0.5, -0.5,
                 0.5, -0.5, -0.5,
                 0.5, -0.5, 0.5,
                 -0.5, -0.5, 0.5,
            ];
            var vertexPositionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

            // 顶点索引
            var vertexIndices = [
                // 前面
                0, 1, 2,
                0, 2, 3,

                // 后面
                4, 5, 6,
                4, 6, 7,

                // 左面
                8, 9, 10,
                8, 10, 11,

                // 右面
                12, 13, 14,
                12, 14, 15,

                // 上面
                16, 17, 18,
                16, 18, 19,

                // 下面
                20, 21, 22,
                20, 22, 23
            ];
            var vertexIndexBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndices), gl.STATIC_DRAW);

            // 纹理坐标
            var textureCoords = [
                // 前面
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,

                // 后面
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,

                // 左面
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,

                // 右面
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,

                // 上面
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,

                // 下面
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0
            ];
            var vertexTextureCoordBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexTextureCoordBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);

            // 纹理
            var texture = gl.createTexture();
            texture.image = new Image();
            texture.image.onload = function () {
                gl.bindTexture(gl.TEXTURE_2D, texture);
                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
                gl.bindTexture(gl.TEXTURE_2D, null);

            }
            texture.image.src = "../image/nehe.gif";

            // 渲染循环
            var x = 0, y = 0, z = 0;
            var render = function () {
                // 清屏
                gl.clearColor(0.0, 0.0, 0.0, 1.0);
                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

                // 顶点坐标
                gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
                gl.vertexAttribPointer(vertexPositionAttr, 3, gl.FLOAT, false, 0, 0);

                // 纹理坐标
                gl.bindBuffer(gl.ARRAY_BUFFER, vertexTextureCoordBuffer);
                gl.vertexAttribPointer(textureCoordAttr, 2, gl.FLOAT, false, 0, 0);

                // 纹理
                gl.activeTexture(gl.TEXTURE0);
                gl.bindTexture(gl.TEXTURE_2D, texture);
                gl.uniform1i(samplerUniform, 0);

                // 位移矩阵
                var euler = new THREE.Euler(x, y, z);
                var mat = new THREE.Matrix4();
                mat.makeRotationFromEuler(euler);
                gl.uniformMatrix4fv(mvMatrixUniform, false, mat.toArray());

                // 绘制
                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
                gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);

                x += 0.01;
                y += 0.01;
                z += 0.01;
                requestAnimationFrame(render);
            }
            render();
        }
    </script>
</head>

<body onload="start();">
    <canvas id="mycanvas" style="border: none;" width="500" height="500"></canvas>
</body>

</html>