webGL坐标系

前面提到过webgl坐标系,再来简单回顾下,webgl处理的是三维图形,所以使用的是三维坐标系,笛卡尔坐标系,具有x,y,z轴。 通常,在webgl中,当你面对计算机屏幕时候,x轴是水平的,y轴是垂直的,z轴垂直于屏幕,观察者的眼睛位于原点(0.0, 0.0, 0.0), 视线是朝着z轴的负方向。

image.png

动态的绘制一个点

前面绘制一个点,点的坐标是直接写死的硬编码,这种编码缺乏扩展性,这次用js来传递坐标至着色器进行绘制。
有两种方式可以做到这一点:
attribute变量和uniform变量。 使用哪一个变量取决于需传数据的本身。 attribute传递的是那些与顶点相关的数据。uniform传递的是那些对于所有顶点都相同的数据。

attribute变量

attribute 变量是一种GLSL ES变量, 被用来从外部向顶点着色器内传输数据。只有顶点着色器才能使用它。

为了使用attribute变量,示例程序中需要包含以下步骤:
1.在顶点着色器中声明attribute变量
2.将attribute变量赋值给gl_Position变量
3.向attribute变量传递数据

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport"
  6. content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8. <title>Document</title>
  9. </head>
  10. <body onload="main()">
  11. <canvas id="canvas" height="400" width="400">
  12. 你的浏览器不支持WebGL,请更换新的浏览器
  13. </canvas>
  14. </body>
  15. <script src="../lib/webgl-util.js" ></script>
  16. <script src="../lib/webgl-debug.js" ></script>
  17. <script src="../lib/cuon-utils.js" ></script>
  18. <script>
  19. //顶点着色器程序
  20. var VSHADER_SOURCE="" +
  21. "attribute vec4 a_Position;\n" +
  22. "void main(){\n" +
  23. " gl_Position = a_Position;\n" +//设置坐标
  24. " gl_PointSize = 10.0;\n" +//设置尺寸
  25. "}\n";
  26. //片元着色器程序
  27. var FSHADER_SOURCE = "" +
  28. "void main(){\n" +
  29. " gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n" +//设置颜色
  30. "}\n";
  31. function main() {
  32. //首先获取到canvas的dom对象
  33. var canvas = document.getElementById("canvas");
  34. //获取到WebGL的上下文
  35. var gl = getWebGLContext(canvas);
  36. //不支持WebGL的浏览器将打印一个错误,并结束代码运行
  37. if (!gl) {
  38. console.log("浏览器不支持WebGL");
  39. return;
  40. }
  41. //初始化着色器
  42. if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
  43. console.log("初始化着色器失败");
  44. return;
  45. }
  46. // 获取attribute变量的存储位置
  47. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  48. // 将顶点位置传输给attribute变量
  49. gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
  50. //指定一个覆盖(清空)canvas的颜色
  51. gl.clearColor(0.0, 0.0, 0.0, 1.0);
  52. //执行清空
  53. gl.clear(gl.COLOR_BUFFER_BIT);
  54. //绘制一个点
  55. gl.drawArrays(gl.POINTS,0,1);
  56. }
  57. </script>
  58. </html>

在第37行声明了attribute变量
image.png

这一行中,关键词attribute被称为限定符, 它表示接下来的变量是一个attribute变量。 attribute变量必须声明成全局变量。 数据将从着色器外部传给变量, 该变量的声明必须是如下格式
<存储限定符> <类型> <变量名>
attribute vec4 a_Position

attribute变量a_Position的类型是vec4,它将被赋值给gl_Position, 后者的类型也是vec4.

获取attribute变量的存储位置

前面讲到过我们使用initShaders()在webgl系统中建立了顶点着色器。 然后,webgl就会对着色器进行解析。辨识出着色器具有attribute变量,每个变量都具有一个存储地址。 以便通过存储地址向变量传输数据。 我们使用gl.getAttribLocation()来获取attribute变量的地址。

代码第74行

image.png

方法的第一个参数是一个程序对象,它包括了顶点着色器和片元着色器。
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变量名的最大长度