《WebGL编程指南》笔记之第三章绘制正方形

这里首先贴出其第三章绘制正方形代码的简化版本(为了阅读流畅性,去除了一些错误判断):

var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  '  gl_Position = a_Position;\n' +
  '}\n';

var FSHADER_SOURCE =
  'void main() {\n' +
  '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
  '}\n';

function main() {
  var canvas = document.getElementById('webgl');
  var gl = getWebGLContext(canvas);
  initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE);
  var n = initVertexBuffers(gl);

  gl.clearColor(0, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}

function initVertexBuffers(gl) {
  var vertices = new Float32Array([-0.5,0.5,-0.5,-0.5,0.5,0.5,0.5,-0.5]);
  var n = 4;
  var vertexBuffer = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(a_Position);
  return n;
}

下面对代码中的一些关键点做个解释:

//-------------------------------------------------------------------------------------------------------------------------------

gl.clear(gl.COLOR_BUFFER_BIT);

这行代码的意思是清除缓冲区,参数可以是一下三种

        gl.COLOR_BUFFER_BIT        指定颜色缓存

        gl.DEPTH_BUFFER_BIT        指定深度缓冲区

        gl.STENCIL_BUFFER_BIT        指定模板缓冲区

使用位操作符or(|)可用来清空多个缓冲区。

//-------------------------------------------------------------------------------------------------------------------------------
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);

这行代码的意思是从向量数组中绘制图元。其原型是:void gl.drawArrays(mode,first,count)。其参数说明如下:

        mode  指定绘图的方式,可接受以下常量的符号:

                gl.POINTS                        //绘制点

                gl.LINES                           //绘制一个线段

                gl.LINE_STRIP                 //绘制多点线条

                gl.LINE_LOOP                  //绘制多点封闭线条

                gl.TRIANGLES                  //绘制单个三角形

                gl.TRIANGLE_STRIP      //绘制三角形条带

                gl.TRIANGLE_FAN          //绘制三角形扇面

        first  指定从那个顶点开始绘制(整数型)

        count  指定绘制需要用到多少个顶点(整数型)

//-------------------------------------------------------------------------------------------------------------------------------

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

这行代码的意思是绑定缓冲区,函数原型是gl.bindBuffer(target,buffer)。

其中target可以是下面两种:

        gl.ARRAY_BUFFER  表示缓冲区对象包含了顶点的数据。

        gl.ELEMENT_ARRAY_BUFFER   表示缓冲区对象中包含顶点的索引值。

buffer指定之前由gl.creareBuffer返回的待绑定的缓冲区对象,如果指定为null,则禁用对target的绑定。

//-------------------------------------------------------------------------------------------------------------------------------

 gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

这行代码的意思是向已经绑定的缓冲区中写入数据,函数的原型是l.bufferData(target,data,usage)

其中target的值可以是gl.ARRAY_BUFFER或gl.ELEMENT_ARRAY_BUFFER,data是写入缓冲区对象的数据,usage表示程序如何处理写入的数据,其值可以是以下三种:

        gl.STATIC_DRAM  只会向缓冲区写入一次数据,但需要绘制很多次

  gl.STREAM_DARM  只会向缓冲区对象写入一次数据,然后需要绘制若干次

  gl.DYNAMIC_DRAM  会向缓冲区对象中写入多次数据,并绘制很多次

 //-------------------------------------------------------------------------------------------------------------------------------

 var a_Position = gl.getAttribLocation(gl.program, 'a_Position');

这行代码的意思是获取字符串'a_Position'参数指定的gl.program着色器对象中的attribute变量存储地址。与此类似的是下面这行代码:

var u_FragColor=gl.getUniformLocation(gl.program,'u_FragColor');

它的意思是获取字符串'au_FragColor参数指定的gl.program着色器对象中的uniform变量存储地址。

需要说明的是在shader中有三种变量类型,分别是attribute、uniform和varying。分别介绍如下:

 1.attribute变量是只能在vertex着色器中使用的变量。(它不能在fragment着色器中声明attribute变量,也不能被fragment着色器中使用),一般用attribute变量来表示一些顶点的数据,如:顶点坐标,法线,纹理坐标,顶点颜色等。在application中,一般用函数glBindAttribLocation()来绑定每个attribute变量的位置,然后用函数glVertexAttribPointer()为每个attribute变量赋值。使用参考如下:

uniform mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord;
void main(void)
{
    gl_Position = u_matViewProjection * a_position;
    v_texCoord = a_texCoord0;
}

2.uniform变量在vertex着色器和fragment着色器两者之间声明方式完全一样,则它可以在vertex着色器和fragment着色器共享使用(相当于一个被vertex着色器和fragment着色器共享的全局变量),uniform变量一般用来表示:变换矩阵,材质,光照参数和颜色等信息。使用参考如下: 

uniform mat4 viewProjMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

3.varying变量
varying变量是vertex着色器和fragment着色器之间做数据传递用的。一般vertex shader修改varying变量的值,然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。其在Vertex着色器中使用参考如下:

uniform mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord;
void main(void)
{
    gl_Position = u_matViewProjection * a_position;
    v_texCoord = a_texCoord0;
}

其在Fragment着色器中使用参考如下:

precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_baseMap;
uniform sampler2D s_lightMap;
void main()
{
    vec4 baseColor;
    vec4 lightColor;
    baseColor = texture2D(s_baseMap, v_texCoord);
    lightColor = texture2D(s_lightMap, v_texCoord);
    gl_FragColor = baseColor * (lightColor + 0.25);
}

//-------------------------------------------------------------------------------------------------------------------------------

gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

这行代码的意思是将绑定到gl.ARRY_BUFFER的缓冲区对象分配给location指定的attribute变量。其函数原型是void gl.vertexAttribPointer(index, size, type, normalized, stride, offset)。其参数说明如下:

        location  指定待分配attribute变量存储位置

  size    指定缓冲区中每个顶点的分量个数

  type    用以下类型之一来指定数据格式

          gl.UNSIGNED_BYTE  无符号字节 Uint8Array

          gl.SHORT       短整型  Int16Array

          gl.UNSIGNED_SHORT  无符号短整型  Uint16Array

          gl.INT          整型  Int32Array

          gl.UNSIGNED_INT  无符号整型  Uint32Array

          gl.FLOAT       浮点型  Float32Array

  normalized  传入true或false,表明是否将非浮点型的数据归一化到[0,1]或[-1,1]之间

  stride  指定相邻的两个顶点间的字节数,默认为0

  offset  指定缓冲区对象的偏移量,即attribute变量从缓冲区中的何处开始储存。

//-------------------------------------------------------------------------------------------------------------------------------

gl.enableVertexAttribArray(a_Position);

这行代码的意思是打开(或者说激活)属性数组列表中指定索引处的通用顶点属性数组。函数的原型是void gl.enableVertexAttribArray(index);

你可以通过以下方法关闭顶点属性数组 disableVertexAttribArray()。

在WebGL中,作用于顶点的数据会先储存在attributes。这些数据仅对JavaScript代码和顶点着色器可用。属性由索引号引用到GPU维护的属性列表中。在不同的平台或GPU上,某些顶点属性索引可能具有预定义的值。创建属性时,WebGL层会分配其他属性。

无论怎样,都需要你使用enableVertexAttribArray()方法,来激活每一个属性以便使用,不被激活的属性是不会被使用的。一旦激活,以下其他方法就可以获取到属性的值了,包括vertexAttribPointer(),vertexAttrib*(),和 getVertexAttrib()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值