1、效果图:
2、完整源代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="webgl" width="500" height="500" style="background-color: skyblue;"></canvas>
</body>
<!-- 顶点着色器代码 -->
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 apos;
void main(){
//设置几何体轴旋转角度为30度 并把角度值转化为弧度制
float radian = radians(30.0);
//求解旋转角度余弦值
float cos = cos(radian);
//求解旋转角度正弦值
float sin = sin(radian);
//引用上面的计算数据,创建绕x轴旋转矩阵
// 1 0 0 0
// 0 cosα sinα 0
// 0 -sinα cosα 0
// 0 0 0 1
mat4 mx = mat4(1,0,0,0, 0,cos,-sin,0, 0,sin,cos,0, 0,0,0,1);
//引用上面的计算数据,创建绕y轴旋转矩阵
// cosβ 0 sinβ 0
// 0 1 0 0
//-sinβ 0 cosβ 0
// 0 0 0 1
mat4 my = mat4(cos,0,-sin,0, 0,1,0,0, sin,0,cos,0, 0,0,0,1);
//两个旋转矩阵、顶点坐标齐次连乘
gl_Position = mx*my*apos;
}
</script>
<!-- 片元着色器代码 -->
<script id="fragmentShader" type="x-shader/x-fragment">
void main(){
//逐片元处理数据
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
</script>
<script>
//获取canvas画布
var canvas = document.getElementById('webgl');
//获取webgl上下文
var gl = canvas.getContext('webgl');
//顶点着色器源码
var vertexShaderSource = document.getElementById('vertexShader').innerText;
//片元着色器源码
var fragShaderSource = document.getElementById('fragmentShader').innerText;
//初始化着色器
var program = initShader(gl, vertexShaderSource, fragShaderSource);
//获取顶点着色器的位置变量apos
var aposLocation = gl.getAttribLocation(program, 'apos');
//八个顶点的坐标数组
var data = new Float32Array([
0.5, 0.5, 0.5, //顶点0
-0.5, 0.5, 0.5, //顶点1
-0.5, -0.5, 0.5, //顶点2
0.5, -0.5, 0.5, //顶点3
0.5, 0.5, -0.5, //顶点4
-0.5, 0.5, -0.5, //顶点5
-0.5, -0.5, -0.5, //顶点6
0.5, -0.5, -0.5, //顶点7
]);
// 顶点索引数组
var indexes = new Uint8Array([
// 前四个点
0, 1, 2, 3,
// 后四个顶点
4, 5, 6, 7,
// 前后对应点
0, 4,
1, 5,
2, 6,
3, 7
]);
//创建缓冲区对象
var indexexBuffer = gl.createBuffer();
//绑定缓冲区对象
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexexBuffer);
//索引数组indexes数据传入缓冲区
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexes,gl.STATIC_DRAW);
//创建缓冲区对象
var Buffer = gl.createBuffer();
//绑定缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER,Buffer);
//将顶点数据data传入缓冲区
gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW)
//缓冲区中的数据按照一定的规律传递给位置变量apos
gl.vertexAttribPointer(aposLocation,3,gl.FLOAT,false,0,0);
//允许数据传递
gl.enableVertexAttribArray(aposLocation);
//LINE_LOOP模式绘制前四个点
gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,0);
//LINE_LOOP模式从第五个点开始绘制四个点
gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,4);
//LINES模式绘制后八个点
gl.drawElements(gl.LINES,8,gl.UNSIGNED_BYTE,8);
//声明初始化着色器函数
function initShader(gl, vertexShaderSource, fragmentShaderSource) {
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
return program;
}
</script>
</html>