WEBGL学习【九】立方体贴不同的纹理

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78503759 ...
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78503759
<html>
<!--开始实现一个三维街景的渲染效果-->
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>NeHeWebGL----环境光(光照模型)</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

    <script type="text/javascript" src="Oak3D_v_0_5.js"></script>

    <script id="shader-fs" type="x-shader/x-fragment">

    precision mediump float;


    varying vec2 vTextureCoord;
    varying vec3 vLightWeighting;

    uniform sampler2D uSampler;

    void main(void) {
        vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
        gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
    }

    </script>

    <script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;
    attribute vec3 aVertexNormal;
    attribute vec2 aTextureCoord;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;
    uniform mat4 uNMatrix;

    uniform vec3 uAmbientColor;

    uniform vec3 uLightingDirection;
    uniform vec3 uDirectionalColor;

    uniform bool uUseLighting;

    varying vec2 vTextureCoord;
    varying vec3 vLightWeighting;

    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;

        if (!uUseLighting) {
            vLightWeighting = vec3(1.0, 1.0, 1.0);
        } else {
            vec3 transformedNormal = (uNMatrix * vec4(aVertexNormal, 1.0)).xyz;
            float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
            vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
        }
    }

    </script>


    <script type="text/javascript">

        var gl;

        //初始化WEBGL上下文
        function initGL(canvas) {
            try {
                gl = canvas.getContext("experimental-webgl");
                gl.viewportWidth = canvas.width;
                gl.viewportHeight = canvas.height;
            } catch (e) {
            }
            if (!gl) {
                alert("Could not initialise WebGL, sorry :-(");
            }
        }


        //获取着色器
        function getShader(gl, id) {
            var shaderScript = document.getElementById(id);
            if (!shaderScript) {
                return null;
            }

            var str = "";
            var k = shaderScript.firstChild;
            while (k) {
                if (k.nodeType == 3) {
                    str += k.textContent;
                }
                k = k.nextSibling;
            }

            var shader;
            if (shaderScript.type == "x-shader/x-fragment") {
                shader = gl.createShader(gl.FRAGMENT_SHADER);
            } else if (shaderScript.type == "x-shader/x-vertex") {
                shader = gl.createShader(gl.VERTEX_SHADER);
            } else {
                return null;
            }

            gl.shaderSource(shader, str);
            gl.compileShader(shader);

            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                alert(gl.getShaderInfoLog(shader));
                return null;
            }

            return shader;
        }


        //初始化着色器
        var shaderProgram;

        function initShaders() {
            var fragmentShader = getShader(gl, "shader-fs");
            var vertexShader = getShader(gl, "shader-vs");

            shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);
            gl.linkProgram(shaderProgram);

            if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                alert("Could not initialise shaders");
            }

            gl.useProgram(shaderProgram);


            //获取顶点着色器中的aVertexPosition变量,并开启
            shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
            gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

            //获取顶点着色器中的aVertexNormal法向量变量,并开启
            shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
            gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);

            //获取顶点着色器中的aTextureCoord纹理坐标的存储位置,并且开启
            shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
            gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);

            //获取模型居住,取样器,光照等参数信息的存储位置
            shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
            shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
            shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
            shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
            shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
            shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
            shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
            shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");
        }


        //处理已经加载的纹理图片
        /*function handleLoadedTexture(texture) {
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

            gl.bindTexture(gl.TEXTURE_2D, texture);
            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.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
            gl.generateMipmap(gl.TEXTURE_2D);

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


        //从本地文件中加载一张纹理图片并且初始化
       /* var crateTexture;

        function initTexture() {
            crateTexture = gl.createTexture();
            crateTexture.image = new Image();
            crateTexture.image.onload = function () {
                handleLoadedTexture(crateTexture)
            }

            //设置我的纹理图片
            crateTexture.image.src = "./resources/woodbox.bmp";
        }*/


        //创建我的模型视图矩阵
        var mvMatrix;
        var mvMatrixStack = [];
        var pMatrix;

        //矩阵入栈
        function mvPushMatrix() {
            var copy = new okMat4();
            mvMatrix.clone(copy);
            mvMatrixStack.push(copy);
        }

        //矩阵出栈
        function mvPopMatrix() {
            if (mvMatrixStack.length == 0) {
                throw "Invalid popMatrix!";
            }
            mvMatrix = mvMatrixStack.pop();
        }


        //该函数主要是吧我当前的模型视图投影矩阵及时更新到顶点着色器
        function setMatrixUniforms() {
            gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix.toArray());
            gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix.toArray());

            //计算模型视图矩阵的逆转置矩阵(运动物体的法向量不断在改变)
            var normalMatrix = mvMatrix.inverse().transpose();
            gl.uniformMatrix4fv(shaderProgram.nMatrixUniform, false, normalMatrix.toArray());
        }


        //处理物体运动的一些基本参数
        var xRot = 0;
        var xSpeed = 3;

        var yRot = 0;
        var ySpeed = -3;

        var z = -5.0;


        //可以处理多个按键同时按下的情形
        var currentlyPressedKeys = {};

        function handleKeyDown(event) {
            currentlyPressedKeys[event.keyCode] = true;
        }

        function handleKeyUp(event) {
            currentlyPressedKeys[event.keyCode] = false;
        }


        //根据不同的按键做出不同的反应
        function handleKeys() {
            if (currentlyPressedKeys[33]) {
                // Page Up
                z -= 0.05;
            }
            if (currentlyPressedKeys[34]) {
                // Page Down
                z += 0.05;
            }
            if (currentlyPressedKeys[37]) {
                // Left cursor key
                ySpeed -= 1;
            }
            if (currentlyPressedKeys[39]) {
                // Right cursor key
                ySpeed += 1;
            }
            if (currentlyPressedKeys[38]) {
                // Up cursor key
                xSpeed -= 1;
            }
            if (currentlyPressedKeys[40]) {
                // Down cursor key
                xSpeed += 1;
            }
        }


        //初始化我的顶点缓冲区参数(包括位置、法向量、纹理坐标、位置索引)
        var cubeVertexPositionBuffer;
        var cubeVertexNormalBuffer;
        var cubeVertexTextureCoordBuffer;
        var cubeVertexIndexBuffer;

        //立方体的索引
        var cubeVertexTextureIndex0;
        var cubeVertexTextureIndex1;
        var cubeVertexTextureIndex2;
        var cubeVertexTextureIndex3;
        var cubeVertexTextureIndex4;
        var cubeVertexTextureIndex5;

        //利用这个全局变量来保存所有的属性信息
        var pwgl = {};
        // Keep track of ongoing image loads to be able to handle lost context
        pwgl.ongoingImageLoads = [];


        function initBuffers() {
            cubeVertexPositionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
            var vertices = [
                // Front face
                -1.0, -1.0, 1.0,
                1.0, -1.0, 1.0,
                1.0, 1.0, 1.0,
                -1.0, 1.0, 1.0,

                // Back face
                -1.0, -1.0, -1.0,
                -1.0, 1.0, -1.0,
                1.0, 1.0, -1.0,
                1.0, -1.0, -1.0,

                // Top face
                -1.0, 1.0, -1.0,
                -1.0, 1.0, 1.0,
                1.0, 1.0, 1.0,
                1.0, 1.0, -1.0,

                // Bottom face
                -1.0, -1.0, -1.0,
                1.0, -1.0, -1.0,
                1.0, -1.0, 1.0,
                -1.0, -1.0, 1.0,

                // Right face
                1.0, -1.0, -1.0,
                1.0, 1.0, -1.0,
                1.0, 1.0, 1.0,
                1.0, -1.0, 1.0,

                // Left face
                -1.0, -1.0, -1.0,
                -1.0, -1.0, 1.0,
                -1.0, 1.0, 1.0,
                -1.0, 1.0, -1.0,
            ];
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
            cubeVertexPositionBuffer.itemSize = 3;
            cubeVertexPositionBuffer.numItems = 24;


            //设置我的立方体各个方向的法向量
            cubeVertexNormalBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
            var vertexNormals = [
                // Front face
                0.0, 0.0, 1.0,
                0.0, 0.0, 1.0,
                0.0, 0.0, 1.0,
                0.0, 0.0, 1.0,

                // Back face
                0.0, 0.0, -1.0,
                0.0, 0.0, -1.0,
                0.0, 0.0, -1.0,
                0.0, 0.0, -1.0,

                // Top face
                0.0, 1.0, 0.0,
                0.0, 1.0, 0.0,
                0.0, 1.0, 0.0,
                0.0, 1.0, 0.0,

                // Bottom face
                0.0, -1.0, 0.0,
                0.0, -1.0, 0.0,
                0.0, -1.0, 0.0,
                0.0, -1.0, 0.0,

                // Right face
                1.0, 0.0, 0.0,
                1.0, 0.0, 0.0,
                1.0, 0.0, 0.0,
                1.0, 0.0, 0.0,

                // Left face
                -1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0
            ];
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW);
            cubeVertexNormalBuffer.itemSize = 3;
            cubeVertexNormalBuffer.numItems = 24;


            //纹理坐标的创建
            cubeVertexTextureCoordBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
            var textureCoords = [
                // Front face
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,

                // Back face
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,
                0.0, 0.0,

                // Top face
                0.0, 1.0,
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,

                // Bottom face
                1.0, 1.0,
                0.0, 1.0,
                0.0, 0.0,
                1.0, 0.0,

                // Right face
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0,
                0.0, 0.0,

                // Left face
                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0,
                0.0, 1.0
            ];
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
            cubeVertexTextureCoordBuffer.itemSize = 2;
            cubeVertexTextureCoordBuffer.numItems = 24;

            //顶点索引坐标的初始化
            /*cubeVertexIndexBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
            var cubeVertexIndices = [
                0, 1, 2, 0, 2, 3,    // Front face
                4, 5, 6, 4, 6, 7,    // Back face
                8, 9, 10, 8, 10, 11,  // Top face
                12, 13, 14, 12, 14, 15, // Bottom face
                16, 17, 18, 16, 18, 19, // Right face
                20, 21, 22, 20, 22, 23  // Left face
            ];
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
            cubeVertexIndexBuffer.itemSize = 1;
            cubeVertexIndexBuffer.numItems = 36;*/


            //对立方体的六个面建立索引,为后面的渲染做准备
            //对立方体的每一个面分别建立缓冲区,以实现对不同的面实现不同的纹理
            //前面
            cubeVertexTextureIndex0 = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex0);
            var Indices0 = [0, 1, 2,      0, 2, 3];
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices0), gl.STATIC_DRAW);
            cubeVertexTextureIndex0.itemSize = 1;
            cubeVertexTextureIndex0.numItems = 6;

            //后面
            cubeVertexTextureIndex1 = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex1);
            var Indices1 = [4, 5, 6,      4, 6, 7];
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices1), gl.STATIC_DRAW);
            cubeVertexTextureIndex1.itemSize = 1;
            cubeVertexTextureIndex1.numItems = 6;

            //上面
            cubeVertexTextureIndex2 = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex2);
            var Indices2 = [8, 9, 10,     8, 10, 11];
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices2), gl.STATIC_DRAW);
            cubeVertexTextureIndex2.itemSize = 1;
            cubeVertexTextureIndex2.numItems = 6;

            //下面
            cubeVertexTextureIndex3 = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex3);
            var Indices3 = [12, 13, 14,   12, 14, 15];
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices3), gl.STATIC_DRAW);
            cubeVertexTextureIndex3.itemSize = 1;
            cubeVertexTextureIndex3.numItems = 6;

            //右边
            cubeVertexTextureIndex4 = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex4);
            var Indices4 = [16, 17, 18,   16, 18, 19];
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices4), gl.STATIC_DRAW);
            cubeVertexTextureIndex4.itemSize = 1;
            cubeVertexTextureIndex4.numItems = 6;

            //左边
            cubeVertexTextureIndex5 = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex5);
            var Indices5 = [20, 21, 22,   20, 22, 23];
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices5), gl.STATIC_DRAW);
            cubeVertexTextureIndex5.itemSize = 1;
            cubeVertexTextureIndex5.numItems = 6;

        }

        //纹理加载完成之后的处理
        function textureFinishedLoading(image, texture) {
            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,
                image);
            //Mip映射纹理(会自动生成Mip映射纹理链)---会提高纹理的分辨率
            gl.generateMipmap(gl.TEXTURE_2D);


            //设置我的纹理滤波方式
            //拉伸纹理
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            //纹理收缩
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

            //对于所有的纹理坐标的S,T方向应用镜面映射
            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.bindTexture(gl.TEXTURE_2D, null);
        }

        //开始从本地加载图片作为纹理图片
        function loadImageForTexture(url, texture) {
            //创建一个类似javascriptDOM对象的图片对象【< img src="" id=""/>            var image = new Image();
            //图片在如完成之后
            image.onload = function() {
                //删除当前数组中的这张图片
                pwgl.ongoingImageLoads.splice(pwgl.ongoingImageLoads.indexOf(image), 1);
                textureFinishedLoading(image, texture);
            }
            pwgl.ongoingImageLoads.push(image);
            image.crossOrigin = "anonymous";
            image.src = url;
        }

        //在这里我设置了三张纹理图片
        function setupTextures() {
            // Texture for the table
            pwgl.woodTexture = gl.createTexture();
            loadImageForTexture("./resources/wood_128x128.jpg", pwgl.woodTexture);

            // Texture for the floor
            pwgl.groundTexture = gl.createTexture();
            loadImageForTexture("./resources/wood_floor_256.jpg", pwgl.groundTexture);

            // Texture for the box on the table
            pwgl.boxTexture = gl.createTexture();
            loadImageForTexture("./resources/xiuxiuba.bmp", pwgl.boxTexture);
            //这里会出现错误的跨域请求
            //has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
            //loadImageForTexture("127.0.0.1:8080/webgl/images/xiuxiu.bmp", pwgl.boxTexture);
            pwgl.mofangTexture = gl.createTexture();
            loadImageForTexture("./resources/xiuxiu.bmp", pwgl.mofangTexture);


            //再次循环创建六个立方体纹理图片
            pwgl.cube1 = gl.createTexture();
            pwgl.cube2 = gl.createTexture();
            pwgl.cube3 = gl.createTexture();
            pwgl.cube4 = gl.createTexture();
            pwgl.cube5 = gl.createTexture();
            pwgl.cube6 = gl.createTexture();
            loadImageForTexture("./resources/cube/01.bmp", pwgl.cube1);
            loadImageForTexture("./resources/cube/02.bmp", pwgl.cube2);
            loadImageForTexture("./resources/cube/03.bmp", pwgl.cube3);
            loadImageForTexture("./resources/cube/04.bmp", pwgl.cube4);
            loadImageForTexture("./resources/cube/05.bmp", pwgl.cube5);
            loadImageForTexture("./resources/cube/06.bmp", pwgl.cube6);

        }

        //绘制场景
        function drawScene() {
            gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            //设置我的投影矩阵
            pMatrix = okMat4Proj(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);

            //模型视图矩阵
            mvMatrix = okMat4Trans(0.0, 0.0, z);

            mvMatrix.rotX(OAK.SPACE_LOCAL, xRot, true);
            mvMatrix.rotY(OAK.SPACE_LOCAL, yRot, true);


            //开始向顶点着色器中的相应参数传值
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
            gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
            gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, cubeVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);

            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
            gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
            setMatrixUniforms();

           /* gl.activeTexture(gl.TEXTURE0);
            //绑定纹理坐标到目标对象
            gl.bindTexture(gl.TEXTURE_2D, crateTexture);
            gl.uniform1i(shaderProgram.samplerUniform, 0);
            var lighting = document.getElementById("lighting").checked;
            //console.log(lighting);
            //这里就只是把光照是否勾选的状态传给顶点着色器
            gl.uniform1i(shaderProgram.useLightingUniform, lighting);*/

            var lighting = document.getElementById("lighting").checked;
            //console.log(lighting);
            //这里就只是把光照是否勾选的状态传给顶点着色器
            gl.uniform1i(shaderProgram.useLightingUniform, lighting);



            //在这里重复执行六次赋值纹理的操作
            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, pwgl.cube1);
            gl.uniform1i(shaderProgram.samplerUniform, 0);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex0);
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, pwgl.cube2);
            gl.uniform1i(shaderProgram.samplerUniform, 0);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex1);
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, pwgl.cube3);
            gl.uniform1i(shaderProgram.samplerUniform, 0);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex2);                          //
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, pwgl.cube4);
            gl.uniform1i(shaderProgram.samplerUniform, 0);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex3);
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, pwgl.cube5);
            gl.uniform1i(shaderProgram.samplerUniform, 0);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex4);
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, pwgl.cube6);
            gl.uniform1i(shaderProgram.samplerUniform, 0);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex5);
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

            setMatrixUniforms();


            //判断光照选项框是否被选中
            if (lighting) {
                //读出用户在输入框中键入的环境光的红、绿、蓝的颜色值,并传递给着色器
                gl.uniform3f(
                    shaderProgram.ambientColorUniform,
                    parseFloat(document.getElementById("ambientR").value),
                    parseFloat(document.getElementById("ambientG").value),
                    parseFloat(document.getElementById("ambientB").value)
                );

                //传递光线方向给着色器
                var lightingDirection = new okVec3(
                    parseFloat(document.getElementById("lightDirectionX").value),
                    parseFloat(document.getElementById("lightDirectionY").value),
                    parseFloat(document.getElementById("lightDirectionZ").value)
                );

                //光线方向的归一化(实时胴体地在物体运动的每一个时刻,把环境光的相应参数传给顶点着色器)
                var adjustedLD = lightingDirection.normalize(false);
                //将光线方向向量乘以一个标量-1,用于调转向量的方向
                adjustedLD = okVec3MulVal(adjustedLD, -1.0);
                gl.uniform3fv(shaderProgram.lightingDirectionUniform, adjustedLD.toArray());

                gl.uniform3f(
                    shaderProgram.directionalColorUniform,
                    parseFloat(document.getElementById("directionalR").value),
                    parseFloat(document.getElementById("directionalG").value),
                    parseFloat(document.getElementById("directionalB").value)
                );
            }

            //开始把顶点位置 传给顶点着色器(通过索引方式绘图)
            /*gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
            setMatrixUniforms();
            //gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);*/
        }


        var lastTime = 0;

        //实时更新旋转角度
        function animate() {
            var timeNow = new Date().getTime();
            if (lastTime != 0) {
                var elapsed = timeNow - lastTime;

                xRot += (xSpeed * elapsed) / 1000.0;
                yRot += (ySpeed * elapsed) / 1000.0;
            }
            lastTime = timeNow;
        }

        //不断重绘场景
        function tick() {
            okRequestAnimationFrame(tick);
            handleKeys();
            drawScene();
            animate();
        }


        //主函数
        function webGLStart() {
            var canvas = document.getElementById("lesson07-canvas");
            initGL(canvas);
            initShaders();
            initBuffers();
            //initTexture();

            //设置纹理
            setupTextures();
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.enable(gl.DEPTH_TEST);

            document.onkeydown = handleKeyDown;
            document.onkeyup = handleKeyUp;

            tick();
        }

    </script>


</head>


<body onload="webGLStart();">
<br>
<canvas id="lesson07-canvas" style="border: none;" width="500" height="500"></canvas>

<br/>
<input type="checkbox" id="lighting" checked/> 开启光照<br/>
(使用<code>Page Up</code><code>Page Down</code>键来进行缩放)

<br/>
<h2>平行光:</h2>

<table style="border: 0; padding: 10px;">
    <tr>
        <td><b>方向:</b>
        <td>X: <input type="text" id="lightDirectionX" value="-0.25"/>
        <td>Y: <input type="text" id="lightDirectionY" value="-0.25"/>
        <td>Z: <input type="text" id="lightDirectionZ" value="-1.0"/>
    </tr>
    <tr>
        <td><b>颜色:</b>
        <td>R: <input type="text" id="directionalR" value="0.8"/>
        <td>G: <input type="text" id="directionalG" value="0.8"/>
        <td>B: <input type="text" id="directionalB" value="0.8"/>
    </tr>
</table>

<h2>环境光:</h2>
<table style="border: 0; padding: 10px;">
    <tr>
        <td><b>颜色:</b>
        <td>R: <input type="text" id="ambientR" value="0.2"/>
        <td>G: <input type="text" id="ambientG" value="0.2"/>
        <td>B: <input type="text" id="ambientB" value="0.2"/>
    </tr>
</table>

</body>

<!--
 注释:简单记录一下吧,经过前期的百般尝试;终于实现了在立方体的六个面贴上不同的纹理图片的功能;
 但是使用的额仍然是2D纹理贴图方式,虽然功能实现了, 但是代码中仍然有待进一步改善哈@@@webmaster@xiuxiu.space  2017 11/9/
-->

</html>

相关文章
|
4月前
|
监控 vr&ar Swift
visionOS空间计算实战开发教程Day 5 纹理和材质
本文中我们会通过纹理和材质对这个立方体的六个面分别进行不同的绘制。首先我们将ImmersiveView分拆出来,先新建一个ImmersiveView.swift文件,这是一个视图文件,所以请选择User Interface下的Swift View完成创建,其中的内容待我们编写完ViewModel中的代码后再进行修改。
23 0
|
10月前
|
API
webgl图形变换、投影与摄像机
入坑webgl,从图形变换、投影与摄像机开始,基操学得好,以后才能怎么炫酷怎么来~快快快,点进来~~
webgl图形变换、投影与摄像机
|
10月前
|
存储 异构计算
threejs实战_3d纹理
threejs加载3d纹理
164 0
threejs实战_3d纹理
|
10月前
|
前端开发 JavaScript
threejs实战_canvans纹理
threejs加载canvas纹理
107 0
threejs实战_canvans纹理
|
10月前
【Three.js入门】标准网格材质、置换贴图、粗糙度贴图、金属贴图、法线贴图
【Three.js入门】标准网格材质、置换贴图、粗糙度贴图、金属贴图、法线贴图
282 0
|
缓存 JavaScript 前端开发
【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
264 0
【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
从0开发游戏引擎之使用OpenGL绘制三维球体
绘制球体的难点主要在于 要在遍历循环中 根据经纬度反复的使用Cos、Sin函数算出球面上的XYZ三个顶点坐标,一直反复计算,最终三角面多的形成了一个球的形状。
|
算法 前端开发 异构计算
webgl径向模糊实现体积光
webgl径向模糊实现体积光
webgl径向模糊实现体积光
|
前端开发 算法 图形学
webgl实现径向模糊
webgl实现径向模糊
webgl实现径向模糊
|
缓存 数据可视化 算法
WebGL着色器偏导数dFdx和dFdy介绍
本文适合对webgl、计算机图形学、前端可视化感兴趣的读者。
WebGL着色器偏导数dFdx和dFdy介绍