作者:心叶
时间:2018-05-16 10:55
绘制三个点
前一篇文章我们绘制了一个点,现在想绘制三个点,怎么办?
当然,你可以按照绘制一个点的方法,绘制三次,不过我们这里来说说如何一次绘制三个点。
在前面代码的基础上,我们只需要修改传递点的个数,然后修改绘画方法就可以了。
传递三个点
之前【传递点的位置】处的代码的传递方法只可以传递一个点,如果想传递三个点,需要使用缓冲区。
因此,我们第一步要创建一个缓冲区,并且把点的数据写入缓冲区,代码如下(注释调原来【传递点的位置】的代码,在相同位置添加):
//1.创建缓冲区对象
var vertexBuffer = gl.createBuffer();
// 2.绑定缓冲区对象(表明了缓冲区对象的用途)
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 3.向缓冲区对象中写入数据
var tempData=new Float32Array([
0.0, 0.5,
-0.5, -0.5,
-0.5, 0.5
]);
gl.bufferData(gl.ARRAY_BUFFER, tempData, gl.STATIC_DRAW);
这样,缓冲区就准备好了,接着,把缓冲区和着色器联系起来:
// 4.获取变量存储位置
var a_Position = gl.getAttribLocation(glProgram, 'a_Position');
// 5.把缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 6.连接缓冲区对象和a_Position变量
gl.enableVertexAttribArray(a_Position);
这样,点的位置就传递好了。
修改绘图方法
现在,修改一下绘图方法:
gl.drawArrays(gl.POINTS, 0, 3);
刷新页面,应该可以看见下图:
绘制三个不同大小的点
数据修改
首先,我们要在缓冲区或准备一下数据,表示每个点的大小,对应代码修改如下:
var tempData=new Float32Array([
0.0, 0.5, 10.0,
-0.5, -0.5, 20.0,
-0.5, 0.5,30.0
]);
//这个是每个数据大小,辅助用的
var FSIZE = tempData.BYTES_PER_ELEMENT;
传递点位置的方法修改
由于数据重新调整了,缓冲区分配给点位置的变量也要对应调整:
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE*3, 0);
不清楚的可以去百度一个vertexAttribPointer这个方法,后面我们会统一说明一些常用方法,这里就不说了。
现在,你刷新页面,应该和之前的一样。
传递点大小的方法修改
和上面类似,之前传递一个点大小,现在传递三个就可以了:
//【传递点的大小】
var a_PointSize=gl.getAttribLocation(glProgram,'a_PointSize');
//之前传递一个的方法注释调了
// gl.vertexAttrib1f(a_PointSize,30.0);
gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, FSIZE*3, FSIZE*2);
gl.enableVertexAttribArray(a_PointSize);
现在刷新页面,应该就可以了:
绘制三角形
普通三角形
到目前为止,传递多个点应该没有问题了吧,如果想绘制复杂图形,调用对应api就可以了,比如绘制三角形,修改最后一个绘制方法(绘制三角形的话,点的大小就没有意义了,可以删除,留着也没事):
// gl.drawArrays(gl.POINTS, 0, 3);
gl.drawArrays(gl.TRIANGLES, 0, 3);
结果如下:
彩色三角形
既然位置可以传递多个,是不是颜色也可以,是的,也可以。
同样的,我们先添加颜色数据:
var tempData=new Float32Array([
0.0, 0.5, 10.0,1.0,0.0,1.0,
-0.5, -0.5, 20.0,0.0,1.0,0.0,
-0.5, 0.5,30.0,0.0,0.0,1.0
]);
修改缓冲区绑定位置的方法:
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE*6, 0);
由于要传递三个点,uniform只可以传递一致的数据,因此我们需要用attribute,可是attribute有只可以用在顶点着色器,因此,需要先传递改顶点着色器,然后借助varying传递给片段着色器,着色器修改如下(点的大小代码就没有删除了):
<!-- 顶点着色器 -->
<script type='x-shader/x-vertex' id='shader-vs'>
attribute vec4 a_Position;
attribute float a_PointSize;
attribute vec4 a_Color;
varying vec4 v_FragColor;
void main(){
gl_Position=a_Position;
gl_PointSize=a_PointSize;
v_FragColor=a_Color;
}
</script>
<!-- 片段着色器 -->
<script type='x-shader/x-fragment' id='shader-fs'>
precision lowp float;
varying vec4 v_FragColor;
void main(){
gl_FragColor=v_FragColor;
}
</script>
然后,和点的位置一样,修改传递色彩的代码:
// 【传递点的颜色】
var a_Color = gl.getAttribLocation(glProgram, 'a_Color');
// gl.uniform4f(u_FragColor,1.0,0.0,0.0,1.0);
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
gl.enableVertexAttribArray(a_Color);
显示效果如下:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。