衔接上一篇文章代码

基础矩形绘制

本次绘制随机50个矩形,能够更加深刻理解到webgl只是一个光栅化api的概念。

增加了两个uniform变量,分别在顶点和片元着色器中。

顶点着色器u_resolution是为了在传入屏幕坐标时转换成裁剪空间坐标

vec4(clipSpace * vec2(1, -1), 0, 1)

y轴*-1是为了倒转坐标,y轴起点从左下角变为左上角

uniform变量不需要像attribute一样需要调用启用enableVertexAttribArray api,只需要寻找到属性位置后通过uniform4f进行赋值即可,我目前理解的uniform在一次着色器绘制时是属于不可变的常量,进行下一次绘制前可更改。

代码

主要代码是这样的

 // 绘制50个颜色不一的矩形
 for (let i = 0; i < 50; i++) {
    setRectangle(gl, randomInt(600), randomInt(600), randomInt(600), randomInt(600));
    gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1);
    // 绘制矩形
    gl.drawArrays(gl.TRIANGLES, 0, 6);
}
function setRectangle(gl, x, y, width, height) {
    const x1 = x;
    const x2 = x + width;
    const y1 = y;
    const y2 = y + height;
    const positions = [x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
}

// 返回 0 到 range 范围内的随机整数
function randomInt(range) {
    return Math.floor(Math.random() * range);
}

缓冲区数据读取规则已经在上一篇文章中包含了

简单再提一下

// 告诉属性怎么从positionBuffer中读取数据 (ARRAY_BUFFER)
const size = 2; // 每次迭代运行提取两个单位数据
const type = gl.FLOAT; // 每个单位的数据类型是32位浮点型
const normalize = false; // 不需要归一化数据
const stride = 0; // 0 = 移动单位数量 * 每个单位占用内存(sizeof(type))
// 每次迭代运行运动多少内存到下一个数据开始点
const offset = 0; // 从缓冲起始位置开始读取
gl.vertexAttribPointer(
    positionAttributeLocation,
    size,
    type,
    normalize,
    stride,
    offset
);
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐