WebGL原生API及绘图基础
2015-09-16 15:03
225 查看
WebGL也是HTML5规范的一部分,从本质上讲它是一个增强型的图形绘制库,与HTML5的2D Canvas类似,只是WebGL是一个三维的绘图标准,并且同样使用了canvas元素。使用WebGL进行图形渲染至少要经历以下步骤:
1. 创建一个画布元素。
2. 获取画布的上下文。
3. 初始化视口。
4. 创建一个或多个包含渲染数据的数组(通常是顶点数组)。
5. 创建一个或多个矩阵,将顶点数组变换到屏幕空间。
6. 创建一个或多个着色器来实现绘制算法。
7. 使用参数初始化着色器。
8. 绘制。
一、画布元素与绘制上下文
使用WebGL只需要创建一个canvas元素,通过与该元素关联的DOM对象获取WebGL上下文:
二、视口
获取了WebGL上下文就需要指定在哪里绘制图形,这就称为视口(viewport),调用gl的viewport()函数进行视口的初始化:
其中的四个参数为画布左上角和右下角的坐标。
三、Buffer、ArrayBuffer和类型化数组
WebGL的绘制是由图元组成的,图元的种类包括三角形(三角形数组)、三角形带(triangle strip)、点和线。图元使用的数据数组被称为Buffer,定义了顶点的位置。以下代码定义了一个1×1的正方形顶点数组。
其中vertSize和nVerts分别定义了一个顶点中元素的个数和顶点的个数,此例中表明有4个顶点,每个顶点3个元素。Float32Array是为了WebGL专门引入浏览器的数据类型,称为类型化数组,是ArrayBuffer的一种,用于js中存储二进制数据。
四、矩阵
在绘制之前需要建立两个矩阵——模型视图矩阵(modelview matrix)和投影矩阵(projection martrix)。模型视图矩阵用于定义3D坐标系中正方形相对于相机的位置,投影矩阵用于在着色器中将相机空间中的3D坐标准环卫绘制视口的2D坐标。在本例中对模型的变换是沿-z轴平移3.333个单位,即远离相机3.333个单位,投影矩阵定义了一个45°的相机视野。
在一般开发中,很少有人会自己动手计算投影矩阵,因为一半计算非常复杂,大多都时通过框架来完成。比较有名的框架为glMatrix,专门在js中进行矩阵的运算。
五、着色器
着色器是一小段由类C的高级语言编写的,一般为GLSL ES语言,每个需要绘制的物体都要提供着色器,一个着色器可以应用于多个物体。在实际应用中通常只提供一个着色器,通过不同的参数多次复用。
着色器包括两个部分——顶点着色器(vertex shader)和片元着色器(fragment shader),后者也被称为像素着色器。顶点着色器负责将物体的坐标转换到2D空间去,片元着色器负责将颜色输出到每个转换后的顶点像素。颜色的输出可以为纯色、纹理、光源或者材质。
六、绘制图元
我们定义了一个函数draw()来完成图元的绘制,在该函数中我们将接管上面定义的WebGL上下文以及正方形对象。首先函数会清理一下画布并用黑色填充作为背景色。将顶点数组绑定到上下文中,使用着色器并把顶点数组和矩阵作为输入传给着色器。最后调用WebGL的drawArrays()绘制正方形。
最终的绘制结果如图所示:
1. 创建一个画布元素。
2. 获取画布的上下文。
3. 初始化视口。
4. 创建一个或多个包含渲染数据的数组(通常是顶点数组)。
5. 创建一个或多个矩阵,将顶点数组变换到屏幕空间。
6. 创建一个或多个着色器来实现绘制算法。
7. 使用参数初始化着色器。
8. 绘制。
一、画布元素与绘制上下文
使用WebGL只需要创建一个canvas元素,通过与该元素关联的DOM对象获取WebGL上下文:
function initWebGL(canvas){ var gl; try{ gl=canvas.getContex("expremental-webgl"); } catch(e){ var msg = "Error creating webgl context: "+ e.toString(); alert(msg); throw Error(msg); } return gl; }
二、视口
获取了WebGL上下文就需要指定在哪里绘制图形,这就称为视口(viewport),调用gl的viewport()函数进行视口的初始化:
function initViewport(gl,canvas){ gl.viewport(0,0,canvas.width,canvas.height); }
其中的四个参数为画布左上角和右下角的坐标。
三、Buffer、ArrayBuffer和类型化数组
WebGL的绘制是由图元组成的,图元的种类包括三角形(三角形数组)、三角形带(triangle strip)、点和线。图元使用的数据数组被称为Buffer,定义了顶点的位置。以下代码定义了一个1×1的正方形顶点数组。
function createSquare(gl){ var vertexBuffer; vertexBuffer = gl.createBuffer();//创建顶点缓冲区 gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);//将创建的缓冲区绑定到gl数组 var vertex = [//定义四个顶点的位置 .5, .5, 0.0, -.5,.5, 0.0, .5, -.5, 0.0, -.5, -.5, 0.0 ]; gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertex),gl.STATIC_DRAW);//绑定位置数据到gl数组 var square = {buffer:vertexBuffer,vertSize:3,nVerts:4,primtype:gl.TRIANGLE_TRIP}; return square; }
其中vertSize和nVerts分别定义了一个顶点中元素的个数和顶点的个数,此例中表明有4个顶点,每个顶点3个元素。Float32Array是为了WebGL专门引入浏览器的数据类型,称为类型化数组,是ArrayBuffer的一种,用于js中存储二进制数据。
四、矩阵
在绘制之前需要建立两个矩阵——模型视图矩阵(modelview matrix)和投影矩阵(projection martrix)。模型视图矩阵用于定义3D坐标系中正方形相对于相机的位置,投影矩阵用于在着色器中将相机空间中的3D坐标准环卫绘制视口的2D坐标。在本例中对模型的变换是沿-z轴平移3.333个单位,即远离相机3.333个单位,投影矩阵定义了一个45°的相机视野。
function initMatrices(){ modelViewMatrix = new Float32Array( [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,-3.333,1 ]); projectionMatrix = new Float32Array([ 2.41421,0,0,0, 0,2.41421,0,0, 0,0,-1.002002,-1, 0,0,-0.2002002,0 ]); }
在一般开发中,很少有人会自己动手计算投影矩阵,因为一半计算非常复杂,大多都时通过框架来完成。比较有名的框架为glMatrix,专门在js中进行矩阵的运算。
五、着色器
着色器是一小段由类C的高级语言编写的,一般为GLSL ES语言,每个需要绘制的物体都要提供着色器,一个着色器可以应用于多个物体。在实际应用中通常只提供一个着色器,通过不同的参数多次复用。
着色器包括两个部分——顶点着色器(vertex shader)和片元着色器(fragment shader),后者也被称为像素着色器。顶点着色器负责将物体的坐标转换到2D空间去,片元着色器负责将颜色输出到每个转换后的顶点像素。颜色的输出可以为纯色、纹理、光源或者材质。
var vertexShaderSource = " attribute vec3 vertexPos;\n"+ " uniform mat4 modelViewMatrix;\n"+ " uniform mat4 projectionMatrix;\n"+ " void main(void) {\n"+ " //返回变换并投影后的顶点数据\n"+ " gl_Position = projectionMatrix*modelViewMatrix*\n"+ " vec4(vertexPos,1.0);\n"+ " }\n"; var fragmentShaderSource = " void main(void) {\n"+ " //返回像素颜色,这里为白色\n"+ " gl_FragColor = vec4(1.0,1.0,1.0,1.0);\n"+ " }\n";
六、绘制图元
我们定义了一个函数draw()来完成图元的绘制,在该函数中我们将接管上面定义的WebGL上下文以及正方形对象。首先函数会清理一下画布并用黑色填充作为背景色。将顶点数组绑定到上下文中,使用着色器并把顶点数组和矩阵作为输入传给着色器。最后调用WebGL的drawArrays()绘制正方形。
function draw(gl,obj){ //用黑色清空背景 gl.clearColor(0.0,0.0,0.0,1.0); gl.clear(gl.COLOR_BUFFER_BIT); //设置顶点数组 gl.bindBuffer(gl.ARRAY_BUFFER,obj.buffer); //设置着色器 gl.useProgram(shaderProgram); //设置着色器参数:顶点坐标、投影矩阵和模型视图矩阵 gl.vertexAttribPointer(shaderVertexPositionAttribute,obj.vertSize,gl.FLOAT,false,0,0); gl.uniformMatrix4fv(shaderProjectionMatrixUniform,false,projectionMatrix); gl.uniformMatrix4fv(shaderModelViewMatrixUniform,false,modelViewMatrix); //绘制物体 gl.drawArrays(obj.primtype,0,obj.nVerts); }
最终的绘制结果如图所示:
相关文章推荐
- 页面显示
- ajax无刷新提交
- php的运算符
- iOS 键盘自适应(IQKeyboardManager)使用小结
- 动态sql语句基本语法
- PHP中 HTTP_HOST 和 SERVER_NAME 的区别
- Fuel 7.0介绍
- #import <Cocoa/Cocoa.h> 报错 Lexical or Preprocessor Issue 'Cocoa/Cocoa.h' file not found
- error in invoking target install of makefile
- C++学习笔记之define的多行定义
- Java 类加载与初始化
- Google Protocol Buffers介绍和总结
- JSP:九大内置对象
- 闲谈编程之 Java内部类
- 后台更新(四)
- hdu3639 强连通
- mysql的 函数 group_concat , substring_index 的使用以及 分库分表操作
- 第3周 项目1 - 顺序表的基本运算
- ios中UIActivityIndicatorView使用
- Android 多渠道打包