WebGL缓冲区
一、缓冲区对象
缓冲区对象时WebGL系统中的一块内存区域,可以一次性地向缓冲区对象中填充大量的顶点数据,然后将这些数据保存其中,供顶点着色器使用。
类型化数组
这样程序可以预知数组中的类型,提高性能
类型 | 描述 |
---|---|
Int8Array | 8位整型 |
UInt8Array | 8位无符号整型 |
Int16Array | 16位整型 |
UInt16Array | 16位无符号整型 |
Int32Array | 32位整型 |
UInt32Array | 32位无符号整型 |
Float32Array | 单精度32位浮点型 |
Float64Array | 双精度64位浮点型 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用缓冲区对象</title>
<script src="../../lib/index.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
canvas {
margin: 50px auto 0;
display: block;
background: yellow;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持webGL
</canvas>
</body>
</html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl');
//着色器
//创建着色器源码
const VERTEX_SHADER_SOURCE = `
attribute vec4 aPosition;
void main(){
//要绘制的坐标
gl_Position = aPosition;
//要绘制的大小(着色器变量使用的是浮点型)
gl_PointSize = 10.0;
}
`; //顶点着色器
const FRAGMENT_SHADER_SOURCE = `
void main(){
//要绘制的颜色
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; //片元着色器
const program = initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition')
const points = new Float32Array([
-0.5,-0.5,
0.5,-0.5,
0.0,0.5
])
//创建缓冲区
const buffer = gl.createBuffer();
//绑定缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
//向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER,points,gl.STATIC_DRAW)
//指定顶点变量
gl.vertexAttribPointer(aPosition,2,gl.FLOAT,false,0,0);
//激活
gl.enableVertexAttribArray(aPosition)
//使用gl.disableVertexAttribArray禁用
gl.drawArrays(gl.POINTS,0,3)
</script>
gl.bufferData(target,data,type)
target表示缓冲区对象:
- gl.ARRAY_BUFFER:表示缓冲区存储的是顶点数据
- gl.ELEMENT_ARRAY_BUFFER:表示缓冲区存储的是顶点的索引值
data表示需要写入到缓冲区的顶点数据,如程序中的points
type表示如何使用缓冲区的数据分为如下几类:
- gl.STATIC_DRAW:写入一次,多次绘制
- gl.STREAM_DRAW:写入一次,绘制若干次
- gl.DYNAMIC_DRAW:写入多次,绘制多次
gl.vertexAttribPointer(location,size,type,normalized,stride,offset)
location : attribute变量存储位置
size: 指定每个顶点所使用数据的个数
type: 指定数据格式:
- gl.FLOAT:浮点型
- gl.UNSIGNED_BYTE:无符号字节
- gl.SHORT:短整型
- gl.UNSIGNED_SHORT:无符号短整型
- gl.INT 整型
- gl.UNSIGNED_INT:无符号整型
normalized:表示是否将数据归一化
stride: 两个相邻顶点之间的字节数
offset: 数据偏移量
缓冲区对象使用流程
缓冲区对象执行过程
二、多缓冲区和数据偏移
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多缓冲区与数据偏移</title>
<script src="../../lib/index.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
canvas {
margin: 50px auto 0;
display: block;
background: yellow;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持webGL
</canvas>
</body>
</html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl');
//着色器
//创建着色器源码
const VERTEX_SHADER_SOURCE = `
attribute vec4 aPosition;
attribute float aPointSize;
void main(){
//要绘制的坐标
gl_Position = aPosition;
//要绘制的大小(着色器变量使用的是浮点型)
gl_PointSize = aPointSize;
}
`; //顶点着色器
const FRAGMENT_SHADER_SOURCE = `
void main(){
//要绘制的颜色
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; //片元着色器
const program = initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition')
const aPointSize = gl.getAttribLocation(program, 'aPointSize')
const points = new Float32Array([
-0.5,-0.5,10.0,//点的大小10.0
0.5,-0.5,20.0,//点的大小20.0
0.0,0.5,30.0//点的大小30.0
])
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,points,gl.STATIC_DRAW)
const BYTES = points.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(aPosition,2,gl.FLOAT,false,BYTES*3,0);
gl.enableVertexAttribArray(aPosition)
//BYTES*3,BYTES*2 就是数据偏移量
gl.vertexAttribPointer(aPointSize,1,gl.FLOAT,false,BYTES*3,BYTES*2);
gl.enableVertexAttribArray(aPointSize)
gl.drawArrays(gl.POINTS,0,3)
</script>
多缓冲区流程
三、多种图形的绘制
可绘制的图形
值 | 作用 | 说明 |
---|---|---|
gl.POINTS | 点 | 一系列点 |
gl.LINES | 线段 | 一系列单独的线段,如果顶点是奇数,最后一个点会被忽略 |
gl.LINE_LOOP | 闭合线 | 一系列连续的线段,结束时,会闭合起点和终点 |
gl.LINE_STRIP | 线条 | 一系列连接的线段,不会闭合终点和起点 |
gl.TRIANGLES | 三角形 | 一系列单独的三角形 |
gl.TRIANGLES_STRIP | 三角带 | 一系列条带状的三角形 |
gl.TRIANGLES_FAN | 三角形 | 飘带状三角形 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多种图形绘制</title>
<script src="../../lib/index.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
canvas {
margin: 50px auto 0;
display: block;
background: yellow;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持webGL
</canvas>
</body>
</html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl');
//着色器
//创建着色器源码
const VERTEX_SHADER_SOURCE = `
attribute vec4 aPosition;
void main(){
//要绘制的坐标
gl_Position = aPosition;
//要绘制的大小(着色器变量使用的是浮点型)
gl_PointSize = 10.0;
}
`; //顶点着色器
const FRAGMENT_SHADER_SOURCE = `
void main(){
//要绘制的颜色
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; //片元着色器
const program = initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition')
const points = new Float32Array([
-0.5,-0.5,
0.5,-0.5,
0.0,0.5,
-0.5,0.0
])
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,points,gl.STATIC_DRAW)
gl.vertexAttribPointer(aPosition,2,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(aPosition)
gl.drawArrays(gl.TRIANGLE_STRIP,0,4)
</script>
四、矩阵组合实现图形的复合变换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>复合变化</title>
<script src="../../lib/index.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
canvas {
margin: 50px auto 0;
display: block;
background: yellow;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持webGL
</canvas>
</body>
</html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl');
//着色器
//创建着色器源码
const VERTEX_SHADER_SOURCE = `
attribute vec4 aPosition;
//为什么要用uniform-因为要对所有的顶点实现同样的变换
uniform mat4 translateMatrix;
uniform mat4 scaleMatrix;
uniform mat4 rotateMatrix;
void main(){
//要绘制的坐标
gl_Position = translateMatrix * scaleMatrix * rotateMatrix * aPosition;
//要绘制的大小(着色器变量使用的是浮点型)
gl_PointSize = 10.0;
}
`; //顶点着色器
const FRAGMENT_SHADER_SOURCE = `
void main(){
//要绘制的颜色
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; //片元着色器
const program = initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition')
const translateMatrix = gl.getUniformLocation(program, 'translateMatrix')
const scaleMatrix = gl.getUniformLocation(program, 'scaleMatrix')
const rotateMatrix = gl.getUniformLocation(program, 'rotateMatrix')
const points = new Float32Array([
-0.5,-0.5,
0.5,-0.5,
0.0,0.5,
])
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,points,gl.STATIC_DRAW)
gl.vertexAttribPointer(aPosition,2,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(aPosition)
let deg = 0;
let translateX = -1;
let scaleX = 0.1;
function animation(){
deg += 0.1
translateX += 0.1;
scaleX += 0.1;
if(translateX > 1){translateX = -1;}
if(scaleX > 1.5) {scaleX = 0.1;}
const translate = getTranslateMatrix(translateX);
const scale = getScaleMatrix(scaleX);
const rotate = getRotateMatrix(deg);
gl.uniformMatrix4fv(translateMatrix,false,translate)
gl.uniformMatrix4fv(scaleMatrix,false,scale)
gl.uniformMatrix4fv(rotateMatrix,false,rotate)
gl.drawArrays(gl.TRIANGLES,0,3)
requestAnimationFrame(animation);
}
animation();
</script>
原文地址:https://blog.csdn.net/gghhb12/article/details/142415500
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!