Bootstrap

webGlL变量的声明与使用

抢先观看:

变量的声明格式:<存储限定符><类型限定符><变量名>

        存储限定符:const, attribute, uniform, varying, buffer。

        类型限定符:void, bool, int, float, double, vec2, vec3, vec4, mat2, mat3, mat4, sampler1D, sampler2D, sampler3D, samplerCube, sampler2DShadow。

        变量名:由字母,数字和下划线组成,不能以数字开头,需见名知意。

                举个栗子:attribute vec4 a_Position

约定:attribute变量名以a_开头,uniform变量名以u_开头,varying变量名以v_开头。

        attribute: 传输的是那些与顶点相关的数据,如顶点坐标,法线,颜色等,局部变量,只能在顶点着色器中使用,在片元着色器中无法访问。

        uniform: 传输的是那些与顶点无关的数据或者是那些对于每个顶点都相同的值,如光照参数,变换矩阵等,全局变量,可以在顶点着色器和片元着色器中共享访问。

        varying: 传输的是那些由顶点着色器计算并传递给片元着色器的插值变量,用于从顶点着色器传递到片元着色器的插值数据。

页面内容:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>测试</title>
  <script src="./lib/webgl-utils.js"></script>
  <script src="./lib/webgl-debug.js"></script>
  <script src="./lib/cuon-utils.js"></script>
  <script src="./js/helloPoints.js"></script>
</head>

<body onload="main()">
  <canvas id="canvas" width="400" height="400"></canvas>
</body>

</html>

脚本内容:


// helloPoints.js
// 如何在JavaScript 和着色器之间传递数据
/**
 * 变量:attribute, uniform, varying
 * attribute: 传输的是那些与顶点相关的数据,如顶点坐标,法线,颜色等
 * uniform: 传输的是那些与顶点无关的数据或者是那些对于每个顶点都相同的值,如光照参数,变换矩阵等
 * varying: 传输的是那些由顶点着色器计算并传递给片元着色器的插值变量
 */
// 存储限定符:const, attribute, uniform, varying, buffer’
// 类型限定符:void, bool, int, float, double, vec2, vec3, vec4, mat2, mat3, mat4, sampler1D, sampler2D, sampler3D, samplerCube, sampler2DShadow
// 变量名:由字母,数字和下划线组成,不能以数字开头,需见名知意
//attribute vec4 a_Position;
// 其中,attribute是存储限定符,vec4是类型限定符,a_Position是变量名
// 变量的声明格式:<存储限定符><类型限定符><变量名>
// 约定:attribute变量名以a_开头,uniform变量名以u_开头,varying变量名以v_开头
var vshader_source = `
// 声明attribute变量
attribute vec4 a_Position;
attribute float a_PointSize;
void main(){
  // 将attribute变量赋值给顶点着色器内建变量gl_Position
  gl_Position = a_Position;
  gl_PointSize = a_PointSize;
}
`
var fshader_source = `
void main(){
  gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`
function main () {
  var canvas = document.getElementById('canvas')
  var gl = getWebGLContext(canvas)

  if (!gl) {
    console.log('获取webGl绘图上下文失败')
    return
  }
  if (!initShaders(gl, vshader_source, fshader_source)) {
    console.log('初始化着色器失败')
    return
  }
  /**
   * 获取attribute变量的存储位置
   * gl.getAttribLocation (program, name)
   * @param program 指定色含顶点着色器和片元着色器的着色器程序对象
   * @param name 指定想要获取其存储地址的attribute变量的名称
   * @returns 大于等于0 attribute变量的存储地址
   * @returns -1 获取失败 指定的attribute变量不存在,或者其命名具有gl或webgl 前缀
   * @err INVALID OPERATION 程序对象未能成功连接
   * @err INVALID VALUE name参数的长度大于attribute变量名的最大长度(默认)256字节
   * 
   */
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position')
  if (a_Position < 0) {
    console.log('获取attribute变量a_Position失败')
    return
  }
  // 将顶点位置传输给attribute变量
  //  a_Position属于vec4类型,gl.vertexAttrib3f()函数只能传输前三个分量(x,y,z),第四个分量默认为1.0
  /**
   * 将数据传输给location参数指定的attribute变量。
   * gl.vertexAttriblf()仅传输一个值,这个值将被填充到attribute变量的第1个分量中,第2、3个分量将相支设为0.0,第4个分量将被设为1.0。
   * 类似地,gl.vertexAttrib2f()将填充前两个分量,第3个分量为0.0,第4个分量为1.0。
   * gl.vertexAttrib4f()填充了所有四个分量。
   * gl.vertexAttriblf (location, v0)
   * gl.vertexAttrib2f(location,v0,v1)
   * gl.vertexAttrib3f(location, v0,v1,v2)
   * gl.vertexAttrib4f(location,v0,v1,v2,v3)
   * @param location 指定attribute变量的存储位置
   * @param v0,v1,v2,v3 指定传输给attribute变量的四个分量的值
   * @error 错误 INVALID VALUE location大于等于attribute变量的最大数目(默认为8)
   */
  gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0); // 也可以使用gl.vertexAttrib4f(a_Position, 0.0, 0.0, 0.0, 1.0);

  /**
   * WebGL相关函数的命名规范
   * WebGL中的函数命名遵循OpenGLES2.0中的函数名,我们都知道后者是前者的基础规范。
   * OpenGL中的函数名由三个部分组成:
   * <基础函数名><参数个数><参数类型>,WebGL的函数命名使用同样的结构,
   * gl.vertexAttrib3f(location, v0, v1, v2)
   * 参数类型
   * gl.vertexAttrib基础函数名
   * 3参数个数
   * f 表示浮点数
   * i 表示整数
  */
  var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize')
  gl.vertexAttrib1f(a_PointSize, 10.0)
  gl.clearColor(0.0, 0.0, 0.0, 1.0)
  gl.clear(gl.COLOR_BUFFER_BIT)
  gl.drawArrays(gl.POINTS, 0, 1)
}

效果:

;