- 采用JavaScript循环的方式。
使用二维数组的方式定义点的位置。然后通过for循环以此绘制点。
var points = [
[0.0,0.0,],
[-0.5,-0.5,],
[0.5,-0.5,],
[0.0,0.5]
];
for(var i = 0;i<points.length;i++){
ctx.vertexAttrib2f(pLocation,points[i][0],points[i][1]);
ctx.drawArrays(ctx.POINTS,0,1);
}
- vertexAttrib4f
- drawArrays(ctx.POINTS,0,1);
gl.vertexAttrib4f(location,v1,v2,v3,v4);
将数据传给由location参数指定的attribute变量。还有同族函数,gl_vertexAttrib1f、gl_vertexAttrib2f、gl_vertexAttrib3f,分别对应1个变量,2个变量,3个变量。
- 采用webgl缓冲区对象的方式。
定义结构化数组Float32Array。
var data1 = new Float32Array([0.0,0.0, 0.2,0.3, -0.3,0.4]);
var buffer = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER,buffer);
ctx.bufferData(ctx.ARRAY_BUFFER,data1,ctx.STATIC_DRAW);
var pLocation = ctx.getAttribLocation(program,'aPos');
ctx.vertexAttribPointer(pLocation,2,ctx.FLOAT,false,0,0);
ctx.enableVertexAttribArray(pLocation);
ctx.drawArrays(ctx.POINTS,0,3);
这个方式比较繁琐,引入了很多新的感念。
- 创建缓冲区对象buffer,createBuffer。
- 绑定buffer,bindBuffer。
- 数据写入到缓冲区对象,bufferData。
- 获取attribute地址,getAttribLocation。
- 将缓冲区对象分配给一个attribute对象,vertexAttribPointer。
- 开启缓冲区对象,enableVertexAttribArray。
- 执行顶点着色器,drawArrays。
ctx.enableVertexAttribArray(pLocation);开启attribute变量。也可以使用diableVertexAttribArray()来关闭分配。
在开启后,就不能够通过gl.vertexAttrib4f()向attribute变量赋值了。
下面的案例说明这个问题。
var aposLocation = ctx.getAttribLocation(program,'aPos');
function dian(){
ctx.vertexAttrib4f(aposLocation,0.5,0.5,0.0,1.0);
ctx.drawArrays(ctx.POINTS,0,1);
}
function dianarray(){
var data = new Float32Array([
-0.5,0.0,
0.0,-0.5,
0.5,0.0,
]);
var buffer = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER,buffer);
ctx.bufferData(ctx.ARRAY_BUFFER,data,ctx.STATIC_DRAW);
ctx.vertexAttribPointer(aposLocation,2,ctx.FLOAT,false,0,0);
ctx.enableVertexAttribArray(aposLocation);
ctx.drawArrays(ctx.POINTS,0,3);
ctx.disableVertexAttribArray(aposLocation);//关闭分配
}
如果不关闭分配,再去执行dian()函数的时候,ctx.vertexAttrib4f(aposLocation,0.5,0.5,0.0,1.0);将不会起作用。绘制出来的点依然会是dianarray()函数中定义的缓冲区中的点的值。
我们不能也同时使用这两个方法对attribute赋值,当然在开启attribute后,我们就没必要在使用vertexAttrib4f方式赋值了。这里只是演示。
点绘制.png
网友评论