webgl 视锥体剔除不可见的物体

这里新的东西就是 包围盒,就是把物体用盒子装起来,这样只需要计算面到这个是否相交,在外边,减少了很多计算量;

这个其实就是计算问题,

视锥体求的那个几个面的公式,自己用就可以了,不要问为什么,推导很麻烦;能用就行

相机的旋转,使用相机的up,lookat 两个向量的叉积 的到第三个向量 所形成的坐标系,旋转就通过第三向量的移动完成,就这么简单;

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第三人称</title>
    <script src="glMatrix-0.9.6.min.js"></script>
    <script src="../lib/my-webgl-utils.js"></script>
    <script id="vs" type="x-shader/x-vertex">
        attribute vec3 a_Position;
        attribute vec4 a_Color;
        attribute vec2 a_TexCoord;
        uniform mat4 u_Proj;
        varying vec4 v_Color;
        varying vec2 v_texCoord;
        void main(){
            gl_Position = u_Proj * vec4(a_Position,1.0);
            v_Color = a_Color;
            v_texCoord = a_TexCoord;
        }


    </script>
    <script id="fs" type="x-shader/x-fragment">
         precision mediump float;
         varying vec4 v_Color;
         varying vec2 v_texCoord;
         uniform sampler2D u_Texture;
          void main(void){
            gl_FragColor = texture2D(u_Texture,v_texCoord);
          }


    </script>
</head>
<body>
<canvas id="webgl" width="500px" height="500px"></canvas>
<script>
    var gl;
    var viewPortW;
    var viewPortH;

    var triangleBuffer = null;

    var textureHandle;//纹理对象
    var textureGround;
    var projectMat = mat4.create();//投影矩阵
    var viewMat = mat4.create();//视图矩阵
    var cameraEye = new Float32Array(3);//相机位置
    var cameraTrag = new Float32Array(3);//观看目标位置
    var cameraLookAt = new Float32Array(3);
    var cameraUp = new Float32Array(3);

    var fbo;
    var textureDynamic;

    var times = (new Date()).valueOf();

    var role = {};//角色对象
    role._position = new Float32Array(3);
    role._target = new Float32Array(3);
    role._speed = 5;//速度

    var varRotFBOX = 0;
    var varRotFBOY = 0;
    var mouseDown = false;
    var rButtonDown = false;
    var lastMouseX = 0;
    var lastMouseY = 0;

    var radius = 40;
    var loadTextureNum = 0;
    onload = function () {
        var canvas = document.getElementById("webgl");
        gl = canvas.getContext("webgl");
        viewPortW = canvas.clientWidth;
        viewPortH = canvas.clientHeight;
        gl.viewport(0, 0, canvas.clientWidth, viewPortH);

        if (!initShaders(gl, "vs", "fs")) {
            console.log('Failed to intialize shaders.');
            return;
        }
        initLocation();//初始化,获取着色器中的变量地址
        initCamera();
        initModelData();
        canvas.onmousedown = handleMouseDown;
        canvas.onmouseup = handleMouseUp;
        canvas.onmousemove = handleMouseMove;
        canvas.onmousewheel = handleMouseWheel;
        document.onkeydown = handleKeyDown;
        document.onkeyup = handleKeyup;

        tick();
    }

    function tick() {
        requestAnimFrame(tick);
            renderScene();

    }

    function renderScene() {
        renderToFBO();

        var elspsed = (new Date()).valueOf() - times;
        times = (new Date()).valueOf();

        updateTarget(elspsed);
        cameraTrag = role._position;
        updateCamera();//更新相机位置

        varRotFBOX += 1;
        //使用fbo
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        gl.viewport(0, 0, viewPortW, viewPortH);

        //! 设置重绘背景的颜色
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        //! 执行绘制,即将背景清空成制定的颜色(clearColor)
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        gl.enable(gl.DEPTH_TEST);
        //! 指定绘制所使用的顶点数据 从 该缓冲区中获取
        gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);

        var mvp = mat4.create();
        var matTrans = mat4.create();
        var matModel = mat4.create();
        var matRotX = mat4.create();
        var matROtY = mat4.create();
        var matRot = mat4.create();
        var matTemp = mat4.create();

        mat4.identity(matRot);
        mat4.identity(matRotX);
        mat4.identity(matROtY);
        mat4.identity(matTrans);
        mat4.identity(matModel);
        mat4.identity(mvp);
        mat4.identity(matTemp);

        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, textureDynamic);
        gl.uniform1i(gl.uniformTexture, 0);

        mat4.translate(matTrans, [role._position[0], 0.0, role._position[2]]);
        //varRot += 1;

        mat4.rotate(matROtY, degToRad(varRotFBOY), [0.0, 1.0, 0.0]);

        mat4.rotate(matRotX, degToRad(varRotFBOX), [1.0, 0.0, 0.0]);

        mat4.multiply(matROtY, matRotX, matRot);

        mat4.multiply(matTrans, matRot, matModel);

        mat4.multiply(projectMat, viewMat, matTemp);

        mat4.multiply(matTemp, matTrans, mvp);

        gl.uniformMatrix4fv(gl.uniformProj, false, mvp);

        gl.enableVertexAttribArray(gl.a_Position);
        gl.enableVertexAttribArray(gl.a_TexCoord);
        gl.enableVertexAttribArray(gl.a_Color);

        gl.vertexAttribPointer(gl.a_Position, 3, gl.FLOAT, false, 4 * 9, 0);
        gl.vertexAttribPointer(gl.a_TexCoord, 2, gl.FLOAT, false, 4 * 9, 4 * 3);
        gl.vertexAttribPointer(gl.a_Color, 4, gl.FLOAT, false, 4 * 9, 4 * 5);

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

        mat4.multiply(projectMat, viewMat, mvp);

        gl.uniformMatrix4fv(gl.uniformProj, false, mvp);
        gl.bindTexture(gl.TEXTURE_2D, textureGround);
        gl.drawArrays(gl.TRIANGLES, 36, 6);
    }

    //计算相机位置
    function updateCamera() {
        //反向推导,知道目标位置,和相机与目标位置的距离,求相机位置
        //camerD 是 目标位置减去相机位置的向量,并归一化,没归一化前,其实就相当于camerD * radius
        //camerD归一化,类似于单位向量,乘以 长,就是它们相减得到的向量
        cameraEye[0] = cameraTrag[0] - cameraLookAt[0] * radius;
        cameraEye[1] = cameraTrag[1] - cameraLookAt[1] * radius;
        cameraEye[2] = cameraTrag[2] - cameraLookAt[2] * radius;
        //规格化up坐标
        var upDir = vec3.normalize(cameraUp);

        mat4.lookAt(cameraEye, cameraTrag, upDir, viewMat);

    }

    //更新目标
    function updateTarget(elapsed) {
        if (role._target[0] == role._position[0]
            && role._target[1] == role._position[1]
            && role._target[2] == role._position[2]) {
            return;
        }

        var offset = new Float32Array(3);
        var dir = new Float32Array(3);
        offset[0] = role._target[0] - role._position[0];
        offset[1] = role._target[1] - role._position[1];
        offset[2] = role._target[2] - role._position[2];

        vec3.normalize(offset, dir);
        var dist = vec3.length(offset);
        if (dist > role._speed * elapsed / 1000.0 * 2) {
            var dist = role._speed * elapsed / 1000.0;
            role._position[0] += dir[0] * dist;
            role._position[2] += dir[2] * dist;
        } else {
            role._position[0] = role._target[0];
            role._position[1] = role._target[1];
            role._position[2] = role._target[2];
        }
    }

    function renderToFBO() {
        //使用fbo
        gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
        gl.viewport(0, 0, viewPortW, viewPortH);

        //设置重绘背景的颜色
        gl.clearColor(1.0, 1.0, 1.0, 1.0);
        //执行绘制,即将背景清空成制定的颜色
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        gl.enable(gl.DEPTH_TEST);
        //指定绘制使用的顶点数据
        gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);

        var mvp = mat4.create();//MVP矩阵
        var matTrans = mat4.create();//移动矩阵
        var matModel = mat4.create();//模型矩阵
        var matRotX = mat4.create();//X旋转矩阵
        var matRotY = mat4.create();//Y 旋转矩阵
        var matRot = mat4.create();//旋转矩阵

        //初始化成单位向量
        mat4.identity(matRot);
        mat4.identity(matRotX);
        mat4.identity(matRotY);
        mat4.identity(matTrans);
        mat4.identity(matModel);
        mat4.identity(mvp);

        gl.activeTexture(gl.TEXTURE0);//开启纹理
        gl.bindTexture(gl.TEXTURE_2D, textureHandle);
        gl.uniform1i(gl.uniformTexture, 0);

        mat4.translate(matTrans, [0, 0.0, -4]);
        mat4.rotate(matRotY, degToRad(varRotFBOY), [0.0, 1.0, 0.0]);
        mat4.rotate(matRotX, degToRad(varRotFBOX), [1.0, 0.0, 0.0]);
        mat4.multiply(matRotY, matRotX, matRot);
        mat4.multiply(matTrans, matRot, matModel);
        mat4.multiply(projectMat, matModel, mvp);//得到mvp 矩阵

        gl.uniformMatrix4fv(gl.uniformProj, false, mvp);

        gl.enableVertexAttribArray(gl.a_Position);
        gl.enableVertexAttribArray(gl.a_Color);
        gl.enableVertexAttribArray(gl.a_TexCoord);

        gl.vertexAttribPointer(gl.a_Position, 3, gl.FLOAT, false, 4 * 9, 0);
        gl.vertexAttribPointer(gl.a_TexCoord, 2, gl.FLOAT, false, 4 * 9, 4 * 3);
        gl.vertexAttribPointer(gl.a_Color, 4, gl.FLOAT, false, 4 * 9, 4 * 5);

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

    function degToRad(degrees) {
        return degrees * Math.PI / 180;
    }

    function handleKeyup(event) {

    }

    function handleKeyDown(event) {

    }

    /**
     * 将屏幕坐标转化成世界坐标
     * @param screen
     * @returns {*}
     */
    function screenToWorld(screen) {
        var v = new Float32Array(4);
        var world = new Float32Array(4);

        v[0] = screen[0];
        v[1] = screen[1];
        v[2] = screen[2];
        v[3] = 1.0;//w分量

        //转换成 0 - 1 的坐标
        v[0] = (v[0])/viewPortW;
        v[1] = (viewPortH - v[1])/viewPortH;

        //转换成 -1 到 1 之间的坐标
        v[0] = v[0] * 2.0 - 1.0;
        v[1] = v[1] * 2.0 - 1.0;
        v[2] = v[2] * 2.0 - 1.0;

        var mvp = mat4.create();
        var mvpInvert = mat4.create();
        //计算MVP矩阵
        mat4.multiply(projectMat,viewMat,mvp);
        //求mvp的逆矩阵
        inverseEx(mvp,mvpInvert);
        world[0] = v[0];
        world[1] = v[1];
        world[2] = v[2];
        world[3] = v[3];

        multiply(mvpInvert,v,world);//得到世界坐标

        if (world[3] == 0.0)
        {
            return world;
        }
        world[0]    /=  world[3];
        world[1]    /=  world[3];
        world[2]    /=  world[3];

        return  world;
    }
    function multiply(mat,v,outv) {
        outv[0] =   mat[0] * v[0] + mat[1] * v[1] + mat[2] * v[2] + mat[3] * v[3];
        outv[1] = mat[4] * v[0] + mat[5] * v[1] + mat[6] * v[2] + mat[7] * v[3];
        outv[2] = mat[8] * v[0] + mat[9] * v[1] + mat[10] * v[2] + mat[11] * v[3];
        outv[3] = mat[12] * v[0] + mat[13] * v[1] + mat[14] * v[2] + mat[15] * v[3];
    }
    //逆矩阵
    function inverseEx(pData,resData) {
        var subFactor00 = pData[10] * pData[15] - pData[14] * pData[11];
        var subFactor01 = pData[9] * pData[15] - pData[13] * pData[11];
        var subFactor02 = pData[9] * pData[14] - pData[13] * pData[10];
        var subFactor03 = pData[8] * pData[15] - pData[12] * pData[11];
        var subFactor04 = pData[8] * pData[14] - pData[12] * pData[10];
        var subFactor05 = pData[8] * pData[13] - pData[12] * pData[9];
        var subFactor06 = pData[6] * pData[15] - pData[14] * pData[7];
        var subFactor07 = pData[5] * pData[15] - pData[13] * pData[7];
        var subFactor08 = pData[5] * pData[14] - pData[13] * pData[6];
        var subFactor09 = pData[4] * pData[15] - pData[12] * pData[7];
        var subFactor10 = pData[4] * pData[14] - pData[12] * pData[6];
        var subFactor11 = pData[5] * pData[15] - pData[13] * pData[7];
        var SubFactor12 = pData[4] * pData[13] - pData[12] * pData[5];
        var subFactor13 = pData[6] * pData[11] - pData[10] * pData[7];
        var subFactor14 = pData[5] * pData[11] - pData[9] * pData[7];
        var subFactor15 = pData[5] * pData[10] - pData[9] * pData[6];
        var subFactor16 = pData[4] * pData[11] - pData[8] * pData[7];
        var subFactor17 = pData[4] * pData[10] - pData[8] * pData[6];
        var subFactor18 = pData[4] * pData[9] - pData[8] * pData[5];

        resData[0]  = + pData[5] * subFactor00 - pData[6] * subFactor01 + pData[7] * subFactor02;
        resData[1]  = - pData[4] * subFactor00 + pData[6] * subFactor03 - pData[7] * subFactor04;
        resData[2]  = + pData[4] * subFactor01 - pData[5] * subFactor03 + pData[7] * subFactor05;
        resData[3]  = - pData[4] * subFactor02 + pData[5] * subFactor04 - pData[6] * subFactor05;

        resData[4]  = - pData[1] * subFactor00 + pData[2] * subFactor01 - pData[3] * subFactor02;
        resData[5]  = + pData[0] * subFactor00 - pData[2] * subFactor03 + pData[3] * subFactor04;
        resData[6]  = - pData[0] * subFactor01 + pData[1] * subFactor03 - pData[3] * subFactor05;
        resData[7]  = + pData[0] * subFactor02 - pData[1] * subFactor04 + pData[2] * subFactor05;

        resData[8]  = + pData[1] * subFactor06 - pData[2] * subFactor07 + pData[3] * subFactor08;
        resData[9]  = - pData[0] * subFactor06 + pData[2] * subFactor09 - pData[3] * subFactor10;
        resData[10]  = + pData[0] * subFactor11 - pData[1] * subFactor09 + pData[3] * SubFactor12;
        resData[11]  = - pData[0] * subFactor08 + pData[1] * subFactor10 - pData[2] * SubFactor12;

        resData[12]  = - pData[1] * subFactor13 + pData[2] * subFactor14 - pData[3] * subFactor15;
        resData[13]  = + pData[0] * subFactor13 - pData[2] * subFactor16 + pData[3] * subFactor17;
        resData[14]  = - pData[0] * subFactor14 + pData[1] * subFactor16 - pData[3] * subFactor18;
        resData[15]  = + pData[0] * subFactor15 - pData[1] * subFactor17 + pData[2] * subFactor18;

        var determinant =
            + pData[0] * resData[0]
            + pData[1] * resData[4]
            + pData[2] * resData[8]
            + pData[3] * resData[12];

        for( var i = 0 ;i < 16 ; ++ i)
            resData[i]  /=  determinant;
    }
    function handleMouseDown(event) {

        if (event.button == 0){
            //计算射线
            var minWorld = new Float32Array(3);
            var maxWorld = new Float32Array(3);

            var screen = new Float32Array(3);
            screen[0] = event.offsetX;
            screen[1] = event.offsetY;
            screen[2] = 0.0;

            var screen1 = new Float32Array(3);
            screen[0] = event.offsetX;
            screen[1] = event.offsetY;
            screen[2] = 1.0;

            var minWorld = screenToWorld(screen);
            var maxWorld = screenToWorld(screen1);

            //射线向量
            var dir = new Float32Array(3);
            dir[0] = maxWorld[0] - minWorld[0];
            dir[1] = maxWorld[1] - minWorld[1];
            dir[2] = maxWorld[2] - minWorld[2];
            vec3.normalize(dir);

            //计算交点:
            //计算方式:因为地面的y=0;射线的起点y轴减去地面的y轴得到高,然后用射线的单位向量除以高,minWorld[1]/dir[1],得到速度(步长,)
            //射线的起点位置 加上 tm(步长,相当于时间,走了多长,)乘以 射线的单位向量,得到交点
            //计算时间
            var tm = Math.abs(minWorld[1]/dir[1]);
            var target = new Float32Array(3);
            target[0] = minWorld[0] + tm * dir[0];
            target[1] = minWorld[1] + tm * dir[1];
            target[2] = minWorld[2] + tm * dir[2];

            moveTo(target);
        }else {
            rButtonDown = true;
            lastMouseX = event.offsetX;
            console.log("rButtonDown = true;");
        }
    }
    function moveTo(targetPos) {
        role._target = targetPos;
        role._target[1] = 0;//没有高度
    }
    function handleMouseUp(event) {

    }

    function handleMouseMove(event) {

    }

    function handleMouseWheel(event) {

    }

    function initModelData() {
        var gSize = 100;//大小
        var gPos = -10;//高度
        var rept = 20;//重复

        var boxVertex = [
            //x     y     z     u    v      r    g    b    a
            -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
            1.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, 1.0, 1.0, 1.0,

            -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
            1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.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, 0.0, 1.0, 0.0, 0.0, 1.0,
            -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0,
            1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,

            -1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0,
            1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
            1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,

            -1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
            -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0,
            1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,

            -1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
            1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
            1.0, 1.0, -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0,

            -1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
            1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
            1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,

            -1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
            1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,
            -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0,

            1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
            1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
            1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,

            1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
            1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,
            1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0,

            -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
            -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0,
            -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0,

            -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
            -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0,
            -1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0,


            -gSize, gPos, -gSize, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
            gSize, gPos, -gSize, rept, 0.0, 1.0, 1.0, 1.0, 1.0,
            gSize, gPos, gSize, rept, rept, 1.0, 1.0, 1.0, 1.0,

            -gSize, gPos, -gSize, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
            gSize, gPos, gSize, rept, rept, 1.0, 1.0, 1.0, 1.0,
            -gSize, gPos, gSize, 0.0, rept, 1.0, 1.0, 1.0, 1.0,
        ]
        triangleBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxVertex), gl.STATIC_DRAW);

        textureHandle = initTextures("test.gif");
        textureGround = initTextures("1.jpg");

        fbo = createFOB(viewPortW, viewPortH);

    }

    //离屏渲染,创建帧缓冲区
    function createFOB(width, height) {
        var obj = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, obj);

        //创建深度缓冲区
        var depthObj = gl.createRenderbuffer();
        gl.bindRenderbuffer(gl.RENDERBUFFER, depthObj);
        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);

        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthObj);//把深度缓冲区绑定到帧缓冲区

        textureDynamic = createDynamicTexture(width, height);//动态纹理

        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureDynamic, 0);

        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        gl.bindTexture(gl.TEXTURE_2D, null);
        return obj;
    }

    function createDynamicTexture(width, height) {
        var texture = gl.createTexture();

        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

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

        return texture;
    }

    function initTextures(imageFile) {
        var texture;
        //创建一个纹理
        texture = gl.createTexture();
        //创建一个图片
        texture.image = new Image();
        //指定图片的路径
        texture.image.src = imageFile;
        texture.image.onload = function () {
            handleLoadedTexture(texture);
        }
        return texture;
    }

    function handleLoadedTexture(texture) {
        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);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);

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

    function initCamera() {
        cameraEye[0] = 28.017817;
        cameraEye[1] = 29.867514;
        cameraEye[2] = 29.429590;

        cameraTrag[0] = -0.84969789;
        cameraTrag[1] = 1;
        cameraTrag[2] = 0.56207591;

        cameraUp[0] = 0;
        cameraUp[1] = 1;
        cameraUp[2] = 0;

        role._position[0] = 0;
        role._position[1] = 0;
        role._position[2] = 0;

        role._target[0] = 0;
        role._target[1] = 1;
        role._target[2] = 2;

        calcDir();

        mat4.perspective(45, viewPortW / viewPortH, 0.1, 10000.0, projectMat);//设置投影矩阵

        mat4.lookAt(cameraEye, cameraTrag, cameraUp, viewMat);//设置视图矩阵


    }

    //求的lookAt方向 单位向量
    function calcDir() {
        //相机看向位置 减 去 眼睛位置,得到 一个向量, D坐标
        vec3.subtract(cameraTrag, cameraEye, cameraLookAt);

        var d = new Float32Array(3);
        d[0] = cameraTrag[0] - cameraEye[0];
        d[1] = cameraTrag[1] - cameraEye[1];
        d[2] = cameraTrag[2] - cameraEye[2];

        vec3.normalize(d, cameraLookAt);
    }

    function initLocation() {
        gl.uniformProj = gl.getUniformLocation(gl.program, "u_Proj");
        gl.uniformTexture = gl.getUniformLocation(gl.program, "u_Texture");
        gl.a_Position = gl.getAttribLocation(gl.program, "a_Position");
        gl.a_Color = gl.getAttribLocation(gl.program, "a_Color");
        gl.a_TexCoord = gl.getAttribLocation(gl.program, "a_TexCoord");
        if (!gl.uniformProj && !gl.uniformTexture) {
            console.log("err 001:获取地址变量错误!");
        }
        if (gl.a_Position < 0 || gl.a_TexCoord < 0
            || gl.a_Color < 0) {
            console.log("err 002:获取地址变量错误!");
        }
    }

    window.requestAnimFrame = (function () {
        return window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function (callback, element) {
                window.setTimeout(callback, 10);
            };
    })();
    function inverseEx(pData,resData)
    {
        var subFactor00 = pData[10] * pData[15] - pData[14] * pData[11];
        var subFactor01 = pData[9] * pData[15] - pData[13] * pData[11];
        var subFactor02 = pData[9] * pData[14] - pData[13] * pData[10];
        var subFactor03 = pData[8] * pData[15] - pData[12] * pData[11];
        var subFactor04 = pData[8] * pData[14] - pData[12] * pData[10];
        var subFactor05 = pData[8] * pData[13] - pData[12] * pData[9];
        var subFactor06 = pData[6] * pData[15] - pData[14] * pData[7];
        var subFactor07 = pData[5] * pData[15] - pData[13] * pData[7];
        var subFactor08 = pData[5] * pData[14] - pData[13] * pData[6];
        var subFactor09 = pData[4] * pData[15] - pData[12] * pData[7];
        var subFactor10 = pData[4] * pData[14] - pData[12] * pData[6];
        var subFactor11 = pData[5] * pData[15] - pData[13] * pData[7];
        var SubFactor12 = pData[4] * pData[13] - pData[12] * pData[5];
        var subFactor13 = pData[6] * pData[11] - pData[10] * pData[7];
        var subFactor14 = pData[5] * pData[11] - pData[9] * pData[7];
        var subFactor15 = pData[5] * pData[10] - pData[9] * pData[6];
        var subFactor16 = pData[4] * pData[11] - pData[8] * pData[7];
        var subFactor17 = pData[4] * pData[10] - pData[8] * pData[6];
        var subFactor18 = pData[4] * pData[9] - pData[8] * pData[5];

        resData[0]  = + pData[5] * subFactor00 - pData[6] * subFactor01 + pData[7] * subFactor02;
        resData[1]  = - pData[4] * subFactor00 + pData[6] * subFactor03 - pData[7] * subFactor04;
        resData[2]  = + pData[4] * subFactor01 - pData[5] * subFactor03 + pData[7] * subFactor05;
        resData[3]  = - pData[4] * subFactor02 + pData[5] * subFactor04 - pData[6] * subFactor05;

        resData[4]  = - pData[1] * subFactor00 + pData[2] * subFactor01 - pData[3] * subFactor02;
        resData[5]  = + pData[0] * subFactor00 - pData[2] * subFactor03 + pData[3] * subFactor04;
        resData[6]  = - pData[0] * subFactor01 + pData[1] * subFactor03 - pData[3] * subFactor05;
        resData[7]  = + pData[0] * subFactor02 - pData[1] * subFactor04 + pData[2] * subFactor05;

        resData[8]  = + pData[1] * subFactor06 - pData[2] * subFactor07 + pData[3] * subFactor08;
        resData[9]  = - pData[0] * subFactor06 + pData[2] * subFactor09 - pData[3] * subFactor10;
        resData[10]  = + pData[0] * subFactor11 - pData[1] * subFactor09 + pData[3] * SubFactor12;
        resData[11]  = - pData[0] * subFactor08 + pData[1] * subFactor10 - pData[2] * SubFactor12;

        resData[12]  = - pData[1] * subFactor13 + pData[2] * subFactor14 - pData[3] * subFactor15;
        resData[13]  = + pData[0] * subFactor13 - pData[2] * subFactor16 + pData[3] * subFactor17;
        resData[14]  = - pData[0] * subFactor14 + pData[1] * subFactor16 - pData[3] * subFactor18;
        resData[15]  = + pData[0] * subFactor15 - pData[1] * subFactor17 + pData[2] * subFactor18;

        var determinant =
            + pData[0] * resData[0]
            + pData[1] * resData[4]
            + pData[2] * resData[8]
            + pData[3] * resData[12];

        for( var i = 0 ;i < 16 ; ++ i)
            resData[i]  /=  determinant;
    }
    function multiply(mat,v,outv) {
        outv[0] =   mat[0] * v[0] + mat[1] * v[1] + mat[2] * v[2] + mat[3] * v[3];
        outv[1] = mat[4] * v[0] + mat[5] * v[1] + mat[6] * v[2] + mat[7] * v[3];
        outv[2] = mat[8] * v[0] + mat[9] * v[1] + mat[10] * v[2] + mat[11] * v[3];
        outv[3] = mat[12] * v[0] + mat[13] * v[1] + mat[14] * v[2] + mat[15] * v[3];
    }
</script>
</body>
</html>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值