webGL坐标系
前面提到过webgl坐标系,再来简单回顾下,webgl处理的是三维图形,所以使用的是三维坐标系,笛卡尔坐标系,具有x,y,z轴。 通常,在webgl中,当你面对计算机屏幕时候,x轴是水平的,y轴是垂直的,z轴垂直于屏幕,观察者的眼睛位于原点(0.0, 0.0, 0.0), 视线是朝着z轴的负方向。
动态的绘制一个点
前面绘制一个点,点的坐标是直接写死的硬编码,这种编码缺乏扩展性,这次用js来传递坐标至着色器进行绘制。
有两种方式可以做到这一点:
attribute变量和uniform变量。 使用哪一个变量取决于需传数据的本身。 attribute传递的是那些与顶点相关的数据。uniform传递的是那些对于所有顶点都相同的数据。
attribute变量
attribute 变量是一种GLSL ES变量, 被用来从外部向顶点着色器内传输数据。只有顶点着色器才能使用它。
为了使用attribute变量,示例程序中需要包含以下步骤:
1.在顶点着色器中声明attribute变量
2.将attribute变量赋值给gl_Position变量
3.向attribute变量传递数据
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body onload="main()">
<canvas id="canvas" height="400" width="400">
你的浏览器不支持WebGL,请更换新的浏览器
</canvas>
</body>
<script src="../lib/webgl-util.js" ></script>
<script src="../lib/webgl-debug.js" ></script>
<script src="../lib/cuon-utils.js" ></script>
<script>
//顶点着色器程序
var VSHADER_SOURCE="" +
"attribute vec4 a_Position;\n" +
"void main(){\n" +
" gl_Position = a_Position;\n" +//设置坐标
" gl_PointSize = 10.0;\n" +//设置尺寸
"}\n";
//片元着色器程序
var FSHADER_SOURCE = "" +
"void main(){\n" +
" gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n" +//设置颜色
"}\n";
function main() {
//首先获取到canvas的dom对象
var canvas = document.getElementById("canvas");
//获取到WebGL的上下文
var gl = getWebGLContext(canvas);
//不支持WebGL的浏览器将打印一个错误,并结束代码运行
if (!gl) {
console.log("浏览器不支持WebGL");
return;
}
//初始化着色器
if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log("初始化着色器失败");
return;
}
// 获取attribute变量的存储位置
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
// 将顶点位置传输给attribute变量
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
//指定一个覆盖(清空)canvas的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//执行清空
gl.clear(gl.COLOR_BUFFER_BIT);
//绘制一个点
gl.drawArrays(gl.POINTS,0,1);
}
</script>
</html>
在第37行声明了attribute变量
这一行中,关键词attribute被称为限定符, 它表示接下来的变量是一个attribute变量。 attribute变量必须声明成全局变量。 数据将从着色器外部传给变量, 该变量的声明必须是如下格式
<存储限定符> <类型> <变量名>
attribute vec4 a_Position
attribute变量a_Position的类型是vec4,它将被赋值给gl_Position, 后者的类型也是vec4.
获取attribute变量的存储位置
前面讲到过我们使用initShaders()在webgl系统中建立了顶点着色器。 然后,webgl就会对着色器进行解析。辨识出着色器具有attribute变量,每个变量都具有一个存储地址。 以便通过存储地址向变量传输数据。 我们使用gl.getAttribLocation()来获取attribute变量的地址。
代码第74行
方法的第一个参数是一个程序对象,它包括了顶点着色器和片元着色器。
tips: 必须在调用initShaders()之后再访问gl.program, 因为这个函数创建了这个程序对象。 第二个参数是想要获取存储地址的attribute变量的名称。
方法的返回值是attribute变量的存储地址。 在控制台打印出之后,输出的是0。 这个变量被存储在a_Position中。 以备后续使用。
gl.getAttribLocation()函数的规范如下
参数有两个,program, name
参数 | program | 指定包含顶点着色器和片元着色器对象 |
---|---|---|
name | 指定想要获取其存储地址的attribute变量的名称 | |
返回值 | 大于等于0 | attribute变量的存储地址 |
-1 | 指定attribute变量不存在,或者其命名具有gl或welgl前缀 | |
错误 | INVALID_OPERATION | 程序对象未能成功连接 |
INVALID_VALUE | name参数的长度大于attribute变量名的最大长度 |