六、WebGL入门,动画

本节将以前的内容整合下,为以后的章节打基础。本节主要内容是让我们绘制的图形动起来。

图形动起来的原理是每一帧都绘制


下面是代码的整体结构:

                //变量
                var webgl  = null;//WebGL对象
		var vertexShaderObject   = null;//vsShader对象
		var fragmentShaderObject = null;//fsShader对象
		var programObject 		 = null;//显卡执行程序对象
		var triangleBuffer 		 = null;//顶点缓冲区对象
		var indexBuffer 		 = null;//索引缓冲区对象
		var v3PositionIndex 	 = 0;//位置输入索引
		var inColor 			 = 1;//颜色输入索引

		var unifromAnim         =   0;//anim索引
                var animTime            =   0;//计数


		//读取shader代码字符串
		function getShaderSource(scritptID)
		{
                  ......
		}


		//初始化工作:完成资源的加载
		/**
		*读shader,编译shader程序,创建显卡程序,链接,向显卡中传输数据。。。
		*/
		function init()
		{
                  ......
		}

		//主程序
		function WebGLStart()
		{
                   ......
		}
 		
 		//渲染
		function renderScene()
		{
                    ......
		}
		//循环
		function tick()
		{
                  ......
		}

		//刷新
		window.requestAnimFrame = (function(){
		  return  window.requestAnimationFrame       ||
		          window.webkitRequestAnimationFrame ||
		          window.mozRequestAnimationFrame    ||
		          function( callback,element ){
		            window.setTimeout(callback, 1000 / 60);
		          };
		})();

我们要做的效果是让矩形向右移动,实际上就是让矩形的横坐标x不断增加。

在shader里面的体现就是v3Position.x+anim(anim是一个增量)

其实是不断的改变anim的值,这就要用到上节提到的uniform变量,在通过webgl.uniform1f(unifromAnim,animTime)每帧改变其值。

shader代码如下:

	<script id="shader-vs" > //顶点着色器vertexShader,处理顶点
		precision lowp float;
		attribute vec3 v3Position;
		attribute vec4 inColor;
		varying  vec4 outColor;
		uniform  float anim;
		void main(void)
		{
			outColor = inColor;
			gl_Position = vec4(v3Position.x+anim,v3Position.y,v3Position.z,1.0);
		}
	</script>

	<script id="shader-fs" >//片段着色器fragmentShader,填充颜色
		precision lowp float;
		varying  vec4 outColor;
		void main(void)
		{

			gl_FragColor = outColor;
		}//两段shader代码都在显卡在执行
	</script>
初始化init()代码如下:

	function init()
		{
			var canvas = document.getElementById("myCanvas");
			webgl = canvas.getContext("webgl");
			webgl.viewport(0,0,canvas.clientWidth,canvas.clientHeight);
			//先将两段shader代码上传到显卡
			vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);//创建一个空的vertexShader对象,里面什么也没有
			fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);//同理创建一个空的fragmentShader对象
			webgl.shaderSource(vertexShaderObject,getShaderSource("shader-vs"));//相当于给vertexShader赋值,使其指向shader-vs里面的代码字符串
			webgl.shaderSource(fragmentShaderObject,getShaderSource("shader-fs"));//相当于给fragmentShader赋值,使其指向shader-fs里面的代码字符串
			//编译两段代码,使其形成能在显卡执行的二进制代码
			webgl.compileShader(vertexShaderObject);
			webgl.compileShader(fragmentShaderObject);
			//检测编译错误
			if(!webgl.getShaderParameter(vertexShaderObject,webgl.COMPILE_STATUS))
			{
				alert("error:vertexShaderObject,info:"+webgl.getShaderInfoLog(vertexShaderObject));
				return;
			}
			if(!webgl.getShaderParameter(fragmentShaderObject,webgl.COMPILE_STATUS))
			{
				alert("error:fragmentShaderObject,info:"+webgl.getShaderInfoLog(fragmentShaderObject));
				return;
			}
			programObject = webgl.createProgram();//创建一个程序,相当于创建一个空的exe文件,前面的shader相当于两个库文件
			//将exe文件与库文件关联在一起
			webgl.attachShader(programObject,vertexShaderObject);
			webgl.attachShader(programObject,fragmentShaderObject);

			webgl.linkProgram(programObject);//链接,形成一个能显卡上执行在可执行程序,通过programObject句柄关联

			//检测链接错误
			if(!webgl.getProgramParameter(programObject,webgl.LINK_STATUS))
			{
				alert("error:programObject");
				return;
			}
			//webgl.useProgram(programObject);//使用刚刚创建好的可执行程序,使用一个程序需要输入输出
            var jsArrayData = 
                [
                    //x     y       z       r       g       b       a
                    -0.5,   +0.5,   0.0,    1.0,    0.0,    0.0,    1.0,
                    +0.5,   +0.5,   0.0,    0.0,    1.0,    0.0,    1.0,
                    +0.5,   -0.5,   0.0,    0.0,    0.0,    1.0,    1.0,
                    -0.5,   -0.5,   0.0,    1.0,    1.0,    0.0,    1.0,
                ];
            var indexDatas = 
                [
                    0,1,2,
                    0,2,3,
                ];    
			webgl.bindAttribLocation(programObject,v3PositionIndex,"v3Position");
			webgl.bindAttribLocation(programObject,inColor,"inColor");
			unifromAnim = webgl.getUniformLocation(programObject,"anim");//获取shader 中 anim 索引
			triangleBuffer = webgl.createBuffer();//在显卡上创建一个缓冲区
			webgl.bindBuffer(webgl.ARRAY_BUFFER,triangleBuffer);//申明缓存区的存储类型为ARRAY_BUFFER
			webgl.bufferData(webgl.ARRAY_BUFFER,new Float32Array(jsArrayData),webgl.STATIC_DRAW);//给缓存区赋值
			//创建索引缓冲区
			indexBuffer = webgl.createBuffer();
			webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER,indexBuffer);
			webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER,new Uint16Array(indexDatas), webgl.STATIC_DRAW);
		}

渲染renderScene(),每帧都会调用一次

function renderScene()
		{
			//绘制
			webgl.clearColor(0.0,0.0,0.0,1.0);
			webgl.clear(webgl.COLOR_BUFFER_BIT);
			webgl.bindBuffer(webgl.ARRAY_BUFFER,triangleBuffer);//使用缓冲区
			webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER,indexBuffer);//使用缓冲区
			animTime+=0.005;//每帧增加0.005
			if(animTime>=1) animTime = 0;
			webgl.useProgram(programObject);
			{
				webgl.uniform1f(unifromAnim,animTime);
				webgl.enableVertexAttribArray(v3PositionIndex);//启用v3PositionIndex
				webgl.enableVertexAttribArray(inColor);//启用inColor
				webgl.vertexAttribPointer(v3PositionIndex,3,webgl.FLOAT,false,4*7,0);//给v3PositionIndex传值
				webgl.vertexAttribPointer(inColor,        4,webgl.FLOAT,false,4*7,4*3);//给inColor传值
				webgl.drawElements(webgl.TRIANGLES,6,webgl.UNSIGNED_SHORT,0);	
			}
			//webgl.useProgram(0);
		}
其他部分:
		//主程序
		function WebGLStart()
		{
			//!初始化
			init();
			//!进入游戏循环
			tick();
		}
 		
		//循环
		function tick()
		{
			requestAnimFrame(tick); //注:这两个程序不能调换位置
			renderScene();
		}

运行后的会看到一个向右移动的矩形


本节完


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值