线段图元的三种类型
WebGL提供了三种不同的线段绘制模式,每种都有其独特的用途和特点:
1. 基本线段(LINES)
每条线段都需要明确指定两个端点,线段之间相互独立。
// 每两个点构成一条独立线段
// [v1, v2] 构成第一条线段
// [v3, v4] 构成第二条线段
gl.drawArrays(gl.LINES, 0, 4); // 绘制2条线段
特点: 每次需要2个顶点来绘制1条线段,线段之间不相连。
2. 带状线段(LINE_STRIP)
线段首尾相连,形成连续的线条。
// [v1, v2] 第一条线段
// [v2, v3] 第二条线段(使用前一线段的终点作为起点)
// [v3, v4] 第三条线段
gl.drawArrays(gl.LINE_STRIP, 0, 4); // 绘制3条相连的线段
特点: 除了第一条线段需要2个点,后续每个点都会与前一个点形成新线段。
3. 环状线段(LINE_LOOP)
在带状线段的基础上,自动连接最后一个点和第一个点。
// [v1, v2], [v2, v3], [v3, v4], [v4, v1] 形成闭合环
gl.drawArrays(gl.LINE_LOOP, 0, 4); // 绘制闭合的四边形边框
特点: 形成闭合的环状线条,非常适合绘制轮廓。
交互式线段绘制实现
让我们通过一个鼠标点击绘制线段的示例来理解这些概念:
JavaScript交互代码
// 存储点击位置的数组
var positions = [];
// 监听鼠标点击事件
canvas.addEventListener('mouseup', function(e) {
var x = e.offsetX; // 获取相对于canvas的X坐标
var y = e.offsetY; // 获取相对于canvas的Y坐标
// 将点击坐标添加到数组
positions.push(x);
positions.push(y);
// 更新缓冲区数据
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(positions),
gl.DYNAMIC_DRAW
);
// 重新绘制
render();
});
// 渲染函数
function render() {
// 清空画布
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// 根据需要选择不同的线段模式
// 绘制基本线段(每次需要2个点绘制1条线)
gl.drawArrays(gl.LINES, 0, positions.length / 2);
// 或绘制带状线段(连续连接所有点)
// gl.drawArrays(gl.LINE_STRIP, 0, positions.length / 2);
// 或绘制环状线段(连接所有点并闭合)
// gl.drawArrays(gl.LINE_LOOP, 0, positions.length / 2);
}
着色器程序
顶点着色器和片元着色器与之前三角形的例子类似,只是处理的顶点数据用于绘制线段:
// 顶点着色器
precision mediump float;
attribute vec2 a_Position;
attribute vec2 a_Screen_Size;
void main() {
// 将屏幕坐标转换为WebGL坐标系统
vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0;
position.y = -position.y; // 翻转Y轴
gl_Position = vec4(position, 0.0, 1.0);
}
// 片元着色器
precision mediump float;
uniform vec4 u_Color;
void main() {
gl_FragColor = u_Color;
}
三种线段模式的实际应用
基本线段(LINES)适用场景
- 绘制独立的直线段
- 连接特定的点对
- 路径规划中的独立路段
带状线段(LINE_STRIP)适用场景
- 绘制连续的路径
- 手写轨迹绘制
- 曲线轮廓绘制
环状线段(LINE_LOOP)适用场景
- 绘制封闭图形的边框
- 凸多边形轮廓
- 环形路径
性能考虑
// 使用STATIC_DRAW适用于不经常改变的数据
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// 使用DYNAMIC_DRAW适用于经常改变的数据
gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
STATIC_DRAW:数据只设置一次,多次使用DYNAMIC_DRAW:数据多次更新,多次使用STREAM_DRAW:数据少量修改,少量使用
实践建议
- LINES模式:每次点击两个点后才能看到一条线段,适合绘制独立的线段对
- LINE_STRIP模式:每次点击都会延续之前的线条,适合连续绘制
- LINE_LOOP模式:在LINE_STRIP基础上自动闭合,适合绘制封闭形状
掌握了这三种线段绘制模式,你就可以创建各种线条效果,从简单的几何图形到复杂的路径可视化都能轻松实现!