2019年在浏览器用原生js写WebGL,绘制图形;

因为JavaScript高级程序设计(第三版)中的运行书上15.3WebGL部分的代码时在chrome和firefox浏览器下报错,在后面我网上初步找了一圈,好像没人做出真正可以用的代码;所以我就自己重写了一下:
书上代码有些错误,错误原因应该是书出了太久,WebGL的规则已经有些改变了.并且,可能浏览器也有一些相关的规则改变了;
新的代码如下:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>使用WebGL上下文对象绘图</title>
</head>
<body>
	<canvas id="drawing" width="800" height="800">您的浏览器不支持canvas标签;</canvas>
	
	<!--开始04.使用脚本script标签编写着色器文本;-->
		<!--开始使用脚本script标签编写顶点着色器文本;-->
			<script type="x-webgl/x-shader" id="vertex-shader">
				#ifdef GL_ES
				precision mediump float;
				#endif
				attribute vec2 aVertexPosition;
				void main() {
					gl_Position = vec4(aVertexPosition, 0.0, 1.0);
				}

			</script>
		<!--结束使用脚本script标签编写顶点着色器文本;-->
		<!--开始使用脚本script标签编写片段着色器文本;-->
			<script type="x-webgl/x-shader" id="fragment-shader">
				#ifdef GL_ES
				precision mediump float;
				#endif
				uniform vec4 uColor;
				void main() {
					gl_FragColor = uColor;
				}

			</script>
		<!--结束使用脚本script标签编写片段着色器文本;-->
	<!--结束04.使用脚本script标签编写着色器文本;-->
	<script>
		var drawing = document.getElementById("drawing");
		var theContextSetting;
		var gl;
		var buffer;
		var vertices;
		var thisProgram;
		var vertexShader;
		var fragmentShader;
		var node;
		
		if (drawing.getContext){

			try {
				theContextSetting = {
					alpha: true,
					depth: true,
					stencil: false,
					antialias: true,
					premultipliedAlpha: true,
					preserveDrawingBuffer: false
				}

				gl = drawing.getContext("experimental-webgl",theContextSetting);
			} catch (ex) {
				console.log("浏览器无法创建WebGL上下文并抛出错误,此时抛出的错误参数ex--->",ex);
			}

			if (gl){
			
				//开始01.准备绘图;
					gl.clearColor(1.0,0.0,1.0,1.0); //首先必须使用clearColor()方法来指定要使用的颜色值,该方法接收4个参数: 红、绿、蓝和透明度;每个参数必须是一个0到1之间的数值,表示每种分量在最终颜色中的强度;
					gl.clear(gl.COLOR_BUFFER_BIT); //调用了clear()方法,传入的参数gl.COLOR_BUFFER_BIT告诉WebGL上下文对象使用之前定义的颜色来填充相应区域;
				//结束01.准备绘图;

				//开始02.定义WebGL上下文对象的视口;
					gl.viewport(0,0,drawing.width,drawing.height);
				//结束02.定义WebGL上下文对象的视口;

				//开始03.设置缓冲区;
					buffer = gl.createBuffer();
					vertices = new Float32Array([0,1,1,-1,-1,-1]);
					//开始将数据放入缓冲区;
						gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
						gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
					//结束将数据放入缓冲区;
				//结束03.设置缓冲区;

				//开始05.编写着色器对象并链接到着色器程序中;
					//开始编写顶点着色器对象;
						node = document.getElementById("vertex-shader");
						vertexShader = gl.createShader(gl.VERTEX_SHADER);
						gl.shaderSource(vertexShader, node.text);
						gl.compileShader(vertexShader);
					//结束编写顶点着色器对象;
					
					//开始编写片段着色器对象;
						node = document.getElementById("fragment-shader");
						fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
						gl.shaderSource(fragmentShader, node.text);
						gl.compileShader(fragmentShader);
					//结束编写片段着色器对象;

					//开始创建着色器程序并把两个着色器对象链接到到着色器程序中;
						thisProgram = gl.createProgram();
						gl.attachShader(thisProgram, vertexShader);
						gl.attachShader(thisProgram, fragmentShader);
						gl.linkProgram(thisProgram);
						gl.useProgram(thisProgram);
					//结束创建着色器程序并把两个着色器对象链接到到着色器程序中;
				//结束05.编写着色器对象并链接到着色器程序中;
				
				//开始06.为着色器传入值;

					var vertexSetSize = 2;
					var vertexSetCount = vertices.length/vertexSetSize;
					var uColor;
					var aVertexPosition;

					//开始为片段着色器进行赋值;
						uColor = gl.getUniformLocation(thisProgram, "uColor");
						var uColorValue = [1.0,1.0,0.0,1.0];
						gl.uniform4fv(uColor,uColorValue);
					//结束为片段着色器进行赋值;

					//开始为顶点着色器进行赋值;
						aVertexPosition = gl.getAttribLocation(thisProgram, "aVertexPosition");
						gl.enableVertexAttribArray(aVertexPosition);
						gl.vertexAttribPointer(aVertexPosition, vertexSetSize, gl.FLOAT, false, 0, 0);
					//结束为顶点着色器进行赋值;
				//结束06.为着色器传入值;

				//开始07.绘图;
					gl.drawArrays(gl.TRIANGLES,0,vertexSetCount);
				//结束07.绘图;
				
			} else {
				console.log("您的浏览器不支持WebGL画图;");
			}
		}
	</script>
</body>
</html>

如果有兴趣,可以自己对比两者代码,了解到底有那些部份改变了;了解原书作者在写那书时,可能没考虑到那些东西;
原书代码如下:

<!DOCTYPE html>
<html>
<head>
	<title>WebGL Example</title>
</head>
<body>
	<canvas id="drawing" width="1200" height="1200">Your browser doesn't suppor the canvas tag.(您的浏览器不支持canvas标签;)</canvas>
	<script type="x-webgl/x-shader" id="vertex-shader">
		attribute vec2 aVertexPosition;
		
		void main() {
			gl_Position = vec4(aVertexPosition, 0.0, 1.0);
		}
	</script>
	<script type="x-webgl/x-shader" id="fragment-shader">
		uniform vec4 uColor;
		
		void main() {
			gl_FragColor = uColor;
		}
	</script>
	<script>
	window.onload = function(){
		var drawing = document.getElementById("drawing");
		var gl;
		var program;
		var vertexShader;
		var fragmentShader;
		var node;
		
		if (drawing.getContext){

			try {

				var theContextSetting = {
					alpha: true,
					depth: true,
					stencil: false,
					antialias: true,
					premultipliedAlpha: true,
					preserveDrawingBuffer: false
				}

				gl = drawing.getContext("experimental-webgl",theContextSetting);
				*/
			} catch (ex) {
				//noop;
			}


			if (gl){
				gl.clearColor(0, 0, 0, 1);
				gl.clear(gl.COLOR_BUFFER_BIT);
				gl.viewport(0, drawing.height, drawing.width, drawing.height); 

				//create the vertex shader
				node = document.getElementById("vertex-shader");
				vertexShader = gl.createShader(gl.VERTEX_SHADER);
				gl.shaderSource(vertexShader, node.text);
				gl.compileShader(vertexShader);
				
				//create the fragment shader
				node = document.getElementById("fragment-shader");
				fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
				gl.shaderSource(fragmentShader, node.text);
				gl.compileShader(fragmentShader);
				
				//create the shader program
				program = gl.createProgram();
				gl.attachShader(program, vertexShader);
				gl.attachShader(program, fragmentShader);
				gl.linkProgram(program);
				
				//debugging
				if(!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)){
					console.log(gl.getShaderInfoLog(vertexShader));
				}
						
				if(!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)){
					console.log(gl.getShaderInfoLog(fragmentShader));
				}
						
				if(!gl.getProgramParameter(program, gl.LINK_STATUS)){
					console.log(gl.getProgramInfoLog(program));
				}
				
				//define three vertices, x and y for each
				var vertices = new Float32Array([ 0, 1, 1, -1, -1, -1 ]),
					buffer = gl.createBuffer(),
					vertexSetSize = 2,
					vertexSetCount = vertices.length/vertexSetSize,
					uColor, aVertexPosition;

				//put data into the buffer
				gl.bindBuffer(gl.ARRAY_BUFFER, buffer);					
				gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

				//pass color to fragment shader
				uColor = gl.getUniformLocation(program, "uColor");
				gl.uniform4fv(uColor, [ 0, 0, 0, 1 ]);

				//pass vertex information to shader
				aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
				gl.enableVertexAttribArray(aVertexPosition);
				gl.vertexAttribPointer(aVertexPosition, vertexSetSize, gl.FLOAT, false, 0, 0);

				//draw the triangle
				gl.drawArrays(gl.TRIANGLES, 0, vertexSetCount);
				
			} else {
				alert("Your browser doesn't support WebGL;");
			}
		}
	};    
	</script>
</body>
</html>

注:以上代码我修改过,但没多大改变,和原书作者的意思差不多;如果有兴趣,可以结合两份代码进行对比;不懂的话,到2019年6年前可以问我,有时间尽量回答;过了时间,可能我就不作回答了;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值