WebGL自学课程(2):使用自定义glTranslate与glRotate

来源:互联网 发布:php trim无效 编辑:程序博客网 时间:2024/05/09 17:53

OpenGL中可以直接使用glTranslate与glRotate,但是WebGL1.0规范中并没有包含该函数,如果想使用,需要自己进行实现。以下是示例代码:

<!doctype html><html><head><title>World</title>        <meta http-equiv="Content-Type" content="text/html" />        <meta name="charset" content="utf-8"/>        <style type="text/css">            html,body,div{margin:0;padding:0}        </style>        <script id="shader-vs" type="x-shader/x-vertex">            attribute vec3 aPosition;            uniform mat4 uModelView;            uniform mat4 uProj;            void main()            {                gl_Position = uProj * uModelView * vec4(aPosition,1.0);            }        </script>        <script id="shader-fs" type="x-shader/x-fragment">            void main()            {                gl_FragColor = vec4(0.5,0.5,0,1.0);            }        </script><script type="text/javascript" src="http://localhost/arcgis_js_api/library/2.7/jsapi/"></script>        <script type="text/javascript">            var canvas = null;            var gl = null;            var shaderProgram = null;            var aPositionLocation;            var uModelViewLocation;            var uProjLocation;            var vertexPositionBuffer = null;var mvMatrix = null;            var projMatrix = null;            var mvMatrixStack = [];var angle=0;            function mvPushMatrix(){                var array = [];                for(i=0;i<mvMatrix.length;i++){                    array.push(mvMatrix[i]);                }                var matrix = new Float32Array(array);                mvMatrixStack.push(matrix);            }            function mvPopMatrix(){                if(mvMatrixStack.length==0){                    throw "Invalid PopMatrix";                }                mvMatrix = mvMatrixStack.pop();            }            function initWebGL(canvas){                try{                    gl = canvas.getContext("experimental-webgl",{antialias:true});                }                catch(e){                    alert("浏览器不支持WebGL!");                }                if(!gl)                    alert("浏览器不支持WebGL!");            }            function getShader(gl,id){                var shaderScript = document.getElementById(id);                if(!shaderScript)                    return null;                var shader = null;                if(shaderScript.type=="x-shader/x-vertex"){                    shader = gl.createShader(gl.VERTEX_SHADER);                }                else if(shaderScript.type=="x-shader/x-fragment"){                    shader = gl.createShader(gl.FRAGMENT_SHADER);                }                else{                    return null;                }                gl.shaderSource(shader,shaderScript.text);                gl.compileShader(shader);                if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)){                    alert(gl.getShaderInfoLog(shader));                    gl.deleteShader(shader);                    return null;                }                return shader;            }            function initShaders(){                var vertexShader = getShader(gl,"shader-vs");                var fragmentShader = getShader(gl,"shader-fs");                shaderProgram = gl.createProgram();                gl.attachShader(shaderProgram,vertexShader);                gl.attachShader(shaderProgram,fragmentShader);                gl.linkProgram(shaderProgram);                if(!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS)){                    alert("Could not link program");                    gl.deleteProgram(shaderProgram);                    gl.deleteShader(vertexShader);                    gl.deleteShader(fragmentShader);                    return;                }                gl.useProgram(shaderProgram);                aPositionLocation = gl.getAttribLocation(shaderProgram,"aPosition");                gl.enableVertexAttribArray(aPositionLocation);                uModelViewLocation = gl.getUniformLocation(shaderProgram,"uModelView");                uProjLocation = gl.getUniformLocation(shaderProgram,"uProj");            }            function initBuffer(){                vertexPositionBuffer = gl.createBuffer();                gl.bindBuffer(gl.ARRAY_BUFFER,vertexPositionBuffer);                var vertices = [ 0.0,  1.0,  0.0,                                -1.0, -1.0,  0.0,                                 1.0, -1.0,  0.0];                gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);            }function getPerspectiveMatrix(fov,aspect,near,far){                var a = 1.0/Math.tan(fov / 2 * Math.PI / 180);                var b = far/(far-near);                var c = -near*far/(far-near);                                var perspectiveMatrix = new Float32Array([                    a/aspect, 0, 0, 0,                    0, a, 0, 0,                    0, 0, b, c,                    0, 0, 1, 0                ]);                return perspectiveMatrix;            }            function drawScene(){                var width = dojo.style(canvas,"width");                var height = dojo.style(canvas,"height");                gl.viewport(0,0,width,height);                gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);                projMatrix = getPerspectiveMatrix(90,width/height,1.0,100.0);                mvMatrix = new Float32Array([1.0,0.0,0.0,0.0,                                             0.0,1.0,0.0,0.0,                                             0.0,0.0,1.0,0.0,                                             0.0,0.0,0.0,1.0]);                mvPushMatrix();translate(mvMatrix,0,0,-5);angle++;rotateMatrix44(mvMatrix,angle*Math.PI/180,0,1,0);                    gl.bindBuffer(gl.ARRAY_BUFFER,vertexPositionBuffer);                    gl.vertexAttribPointer(aPositionLocation,3,gl.FLOAT,false,0,0);                    gl.uniformMatrix4fv(uModelViewLocation,false,mvMatrix);                    gl.uniformMatrix4fv(uProjLocation,false,projMatrix);                    gl.drawArrays(gl.TRIANGLES,0,3);                mvPopMatrix();            }function loadIdentity(){mvMatrix = new Float32Array([1.0,0.0,0.0,0.0,                                             0.0,1.0,0.0,0.0,                                             0.0,0.0,1.0,0.0,                                             0.0,0.0,0.0,1.0]);}function translate(M16,x,y,z){M16[12] += x;M16[13] += y;M16[14] += z;return M16;}function rotateMatrix44(M16, angle, x, y, z) {var length, s, c;var xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;s = Math.sin(angle);c = Math.cos(angle);length = Math.sqrt( x*x + y*y + z*z );// Rotation matrix is normalizedx /= length;y /= length;z /= length;//#define M(row,col)  m[col*4+row]xx = x * x;yy = y * y;zz = z * z;xy = x * y;yz = y * z;zx = z * x;xs = x * s;ys = y * s;zs = z * s;one_c = 1.0 - c;M16[0] = (one_c * xx) + c;//M(0,0)M16[4] = (one_c * xy) - zs;//M(0,1)M16[8] = (one_c * zx) + ys;//M(0,2)//M16[12] = 0.0;//M(0,3) 表示平移XM16[1] = (one_c * xy) + zs;//M(1,0)M16[5] = (one_c * yy) + c;//M(1,1)M16[9] = (one_c * yz) - xs;//M(1,2)//M16[13] = 0.0;//M(1,3)  表示平移YM16[2] = (one_c * zx) - ys;//M(2,0)M16[6] = (one_c * yz) + xs;//M(2,1)M16[10] = (one_c * zz) + c;//M(2,2)//M16[14] = 0.0;//M(2,3)  表示平移ZM16[3] = 0.0;//M(3,0)M16[7] = 0.0;//M(3,1)M16[11] = 0.0;//M(3,2)M16[15] = 1.0;//M(3,3)return M16;}function initRequestAnimationFrame(){window.requestAnimationFrame = window.requestAnimationFrame|| window.mozRequestAnimationFrame|| window.webkitRequestAnimationFrame|| window.msRequestAnimationFrame|| window.oRequestAnimationFrame|| function(callback) {setTimeout(callback, 1000 / 60);};}function tick() {                window.requestAnimationFrame(tick);                drawScene();            }            function startWebGL(){                canvas = document.getElementById("iCanvas");                initWebGL(canvas);                initShaders();                initBuffer();                gl.clearColor(0.0,0.0,1.0,1.0);                gl.enable(gl.DEPTH_TEST);//gl.clearDepth(1.0);                //gl.depthFunc(gl.LEQUAL);initRequestAnimationFrame();                tick();            }        </script></head><body onload="startWebGL();"><canvas id="iCanvas" style="border: 1px solid #000;width:800px;height: 600px;"></canvas></body></html>


原创粉丝点击