用webgl绘制一个彩色旋转立方体
来源:互联网 发布:中国电信it研发中心 编辑:程序博客网 时间:2024/04/30 13:11
用webgl绘制一个旋转立方体
今天给大家分享一个用webgl写的简单的三维场景:转动的交互式彩色立方体,其六个面的颜色都不一样。
上次绘制二维彩色矩形时讲到,二维是三维场景的特殊情况,所以由二维向三维拓展也并不难,webgl里面提供了画三角形的方法,立方体有6个面,一个面由两个三角形组成,共计需要12个三角形,每个三角形又有3个顶点,故绘制立方体需要36个点,而实际上立方体只有8个顶点,这8个顶点有序组合成6个矩形面,如下图所示:
在程序里面有一个quad(a,b,c,d),表示一个矩形面,例如quad(v0,v1,v2,v3),表示第一个矩形面,其实为两个三角形构成,分别为(v1,v0,v3), (v1, v3,v2),按照这样的顶点索引顺序来画三角形,并最终构成整个立方体。
最终程序运行如下图:在最底下的三个按钮是用于控制立方体绕坐标轴旋转的交互式按钮。
下面是本例的代码:(如果大家需本例完整文件,可联系我,完全开源,用于交流学习)
cube.js:
/** * Created by wjh on 2017/6/27. */"use strict";var canvas;var gl;var points = [];//顶点容器var colors = [];//颜色容器var control;var u_control=[0,0,0];var xAxis = 0;var yAxis = 1;var zAxis = 2;var axis = 0;umVertices = 36;//立方体需要12个三角形,共36个顶点function init(){ canvas = document.getElementById("cube"); gl=WebGLUtils.setupWebGL(canvas); if(!gl){alert("您的浏览器不支持WebGL!");} gl.viewport(0,0,canvas.width,canvas.height);//设置视口大小 gl.clearColor(0.0,0.0,0.0,1.0);//设置背景颜色 colorCube();//彩色立方体 gl.enable(gl.DEPTH_TEST);//消除隐藏面 //初始化着色器 var program = initShaders(gl,"v-shader","f-shader"); gl.useProgram(program); //创建缓冲区,并向缓冲区写入立方体每个面的颜色信息 var cBuffer = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer ); gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW ); //获取着色器中a_Color变量,并向其传递数据 var a_Color = gl.getAttribLocation( program, "a_Color" ); gl.vertexAttribPointer( a_Color, 4, gl.FLOAT, false, 0, 0 ); gl.enableVertexAttribArray( a_Color ); //创建缓冲区,并向缓冲区写入立方体的顶点左边信息 var vBuffer = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer ); gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW ); //获取着色器中a_Position变量,并向其传递数据 var a_Position = gl.getAttribLocation(program,"a_Position"); gl.vertexAttribPointer(a_Position,4,gl.FLOAT,false,0,0); gl.enableVertexAttribArray(a_Position); //设置正射投影,即盒状空间,获取着色器变量u_Matrix,并传递数据 var u_Matrix = gl.getUniformLocation(program,"u_Matrix"); if(!u_Matrix){alert("获取u_Matrix位置失败!")} var iMatrix = new Matrix4(); iMatrix.setOrtho(3,-3,-3,3,5,-5); gl.uniformMatrix4fv(u_Matrix,false,iMatrix.elements); control = gl.getUniformLocation(program,"u_control"); //添加窗口监听事件,在窗口底下的三个按钮,用于控制立方体绕坐标轴转动 document.getElementById( "xButton" ).onclick = function () { axis = xAxis; }; document.getElementById( "yButton" ).onclick = function () { axis = yAxis; }; document.getElementById( "zButton" ).onclick = function () { axis = zAxis; }; render();//执行绘图函数}//彩色立方体的顶点索引function colorCube(){ quad( 1, 0, 3, 2 );//第一个面 quad( 2, 3, 7, 6 );//第二个面 quad( 3, 0, 4, 7 );//第三个面 quad( 6, 5, 1, 2 );//第四个面 quad( 4, 5, 6, 7 );//第五个面 quad( 5, 4, 0, 1 );//第六个面}function quad(a,b,c,d){ //立方体的八个顶点(x,y,z,a) var vertices=[ vec4( -1.0, -1.0, 1.0, 1.0 ), vec4( -1.0, 1.0, 1.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ), vec4( 1.0, -1.0, 1.0, 1.0 ), vec4( -1.0, -1.0, -1.0, 1.0 ), vec4( -1.0, 1.0, -1.0, 1.0 ), vec4( 1.0, 1.0, -1.0, 1.0 ), vec4( 1.0, -1.0, -1.0, 1.0 ) ]; //立方体面的颜色信息(r,g,b,a) var cubeColors = [ [ 0.0, 0.0, 0.0, 1.0 ], // 黑 [ 1.0, 0.0, 0.0, 1.0 ], // 红 [ 1.0, 1.0, 0.0, 1.0 ], // 黄 [ 0.0, 1.0, 0.0, 1.0 ], // 绿 [ 0.0, 0.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 ] //白色 ]; var indices = [ a, b, c, a, c, d ];//顶点索引顺序 //存取顶点余顶点索引信息算法 for ( var i = 0; i < indices.length; ++i ) { points.push( vertices[indices[i]] ); //quad(1,0,3,2)按照indice的索引,另points.push(vertices[1],vertices[0], // vertices[3],vertices[1],vertices[3],vertices[2]); //再执行quad()......,直到六个quad()全执行完 colors.push(cubeColors[a]); }}//绘制立方体function render(){ //清除缓存和深度清除 gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT); //控制立方体旋转 u_control[axis] += 2.0; //获取顶点着色器中u_control的位置 gl.uniform3fv(control, u_control); //画立方体 gl.drawArrays(gl.TRIANGLES,0,NumVertices); //循环函数,用于无限执行和渲染动画,让立方体一直转动 requestAnimationFrame(render);}window.onload = init;//窗口加载init函数,使立方体最终显示在屏幕上
cube.html:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>cube</title> <!--顶点着色器--> <script id="v-shader" type="x-shader/x-vertex"> attribute vec4 a_Position; attribute vec4 a_Color; uniform mat4 u_Matrix; uniform vec3 u_control; varying vec4 v_Color; void main() { vec3 angles = radians(u_control); vec3 c = cos(angles); vec3 s = sin(angles); <!--旋转矩阵--> mat4 rx = mat4 (1.0,0.0,0.0,0.0, 0.0,c.x,s.x,0.0, 0.0,-s.x,c.x,0.0, 0.0,0.0,0.0,1.0); mat4 ry = mat4(c.y,0.0,-s.y,0.0, 0.0,1.0, 0.0,0.0, s.y,0.0,c.y,0.0, 0.0,0.0,0.0,1.0); mat4 rz = mat4(c.z,s.z,0.0,0.0, -s.z,c.z,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0); gl_Position = u_Matrix * rz * ry * rx * a_Position; gl_Position.z = -gl_Position.z; v_Color = a_Color; } </script> <!--片元着色器--> <script id="f-shader" type="x-shader/x-fragment"> precision mediump float; varying vec4 v_Color; void main() { gl_FragColor = v_Color; } </script> <!--调用js文件--> <script type="text/javascript" src="../../libs/webgl-utils.js"></script> <script type="text/javascript" src="../../libs/MV.js"></script> <script type="text/javascript" src="../../libs/initShaders.js"></script> <script type="text/javascript" src="../../libs/cuon-matrix.js"></script> <script type="text/javascript" src="cube.js"></script></head><body><canvas id="cube" width="618" height="618"></canvas><br/><!--在界面添加操作按钮--><button id="xButton">Rotate X</button><button id="yButton">Rotate Y</button><button id="zButton">Rotate Z</button></body></html>
好了,今天就给大家分享到这里,请大家多多支持和交流。
阅读全文
1 0
- 用webgl绘制一个彩色旋转立方体
- 43 WebGL绘制一个自动旋转的立方体盒子,点击获取点击位置颜色
- 28 WebGL绘制立方体
- D3D绘制彩色立方体
- 41 WebGL绘制一个具有交互的立方体
- 绘制一个自动旋转的彩色圆盘
- OpenGL-绘制旋转立方体
- OpenGL入门示例5——黑色背景绘制彩色旋转立方体
- OpenGL绘制旋转立方体实例
- OpenGL绘制旋转立方体实例
- OpenGL绘制旋转立方体实例
- OpenGL4-绘制旋转的立方体
- WebGL画一个彩色矩形
- 详解用CSS绘制3D旋转立方体
- WebGL之旅(十二)IBO绘制立方体
- 使用opengl绘制一个立方体
- Direct3D 12 尝鲜(四): 旋转的彩色立方体
- 【Qt for Android】OpenGL ES 绘制彩色立方体
- 广告赚钱之道
- (19)构造函数、构造代码块、this用法
- Java实现URI参数签名算法,确保应用与REST服务器之间的安全通信,防止Secret Key盗用、数据篡改等恶意攻击行为
- oracle中字段类型长度
- Manacher算法求最长回文串(HDU-3068)
- 用webgl绘制一个彩色旋转立方体
- hdu1279
- OkHttp 封装
- 静态库编译inline函数后,该函数是不可见的
- 产品经理该如何做用户增长?
- JAVA学习之路--线程同步
- [C++]:A*——A Star算法简介
- java---线程池
- 浅谈数据仓库、商业智能、数据挖掘、大数据、云技术的前世今生。