先看几个摘抄的代码例子
- 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>Documenttitle>
- head>
-
- <body>
- <canvas id="canvas" width="400" height="400">
- Please use a browser that supports "canvas"
- canvas>
- <script src="../lib/cuon-matrix.js">script>
- <script>
- var VSHADER_SOURCE =
- 'attribute vec4 a_Position;\n' +
- 'attribute vec4 a_Color;\n' +
- 'uniform mat4 u_ViewProjMatrix;\n' +
- 'varying vec4 v_Color;\n' +
- 'void main() {\n' +
- ' gl_Position = u_ViewProjMatrix * a_Position;\n' +
- ' v_Color = a_Color;\n' +
- '}\n';
-
- // Fragment shader program
- var FSHADER_SOURCE =
- '#ifdef GL_ES\n' +
- 'precision mediump float;\n' +
- '#endif\n' +
- 'varying vec4 v_Color;\n' +
- 'void main() {\n' +
- ' gl_FragColor = v_Color;\n' +
- '}\n';
- const gl = canvas.getContext('webgl');
- const createShader = (type, source) => {
- const shader = gl.createShader(type);
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
- const compileState = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
- if (!compileState) {
- const info = gl.getShaderInfoLog(shader);
- console.log('编译白痴信息为' + info)
- gl.deleteShader(shader);
- return null;
- }
- return shader
- }
- const createProgram = (vshader, fshader) => {
- const vertexShader = createShader(gl.VERTEX_SHADER, vshader);
- const fragementSaher = createShader(gl.FRAGMENT_SHADER, fshader);
- if (!vertexShader || !fragementSaher) {
- console.log('创建着色器失败')
- return null
- }
- const program = gl.createProgram();
- gl.attachShader(program, vertexShader);
- gl.attachShader(program, fragementSaher);
- gl.linkProgram(program);
- const linkState = gl.getProgramParameter(program, gl.LINK_STATUS);
- if (!linkState) {
- const err = gl.getProgramInfoLog(program);
- console.log('链接报错信息为' + err);
- gl.deleteShader(vertexShader);
- gl.deleteShader(fragementSaher);
- gl.deleteProgram(program);
- return null
- }
- return program
- }
- const program = createProgram(VSHADER_SOURCE, FSHADER_SOURCE)
- gl.useProgram(program);
- gl.program = program;
- const initVertexBuffers = () => {
- var verticesColors = new Float32Array([
- // Vertex coordinates and color
- 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // v0 White
- -1.0, 1.0, 1.0, 1.0, 0.0, 1.0, // v1 Magenta
- -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, // v2 Red
- 1.0, -1.0, 1.0, 1.0, 1.0, 0.0, // v3 Yellow
- 1.0, -1.0, -1.0, 0.0, 1.0, 0.0, // v4 Green
- 1.0, 1.0, -1.0, 0.0, 1.0, 1.0, // v5 Cyan
- -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, // v6 Blue
- -1.0, -1.0, -1.0, 0.0, 0.0, 0.0 // v7 Black
- ]);
-
- var indices = new Uint8Array([
- 0, 1, 2, 0, 2, 3, // front
- 0, 3, 4, 0, 4, 5, // right
- 0, 5, 6, 0, 6, 1, // up
- 1, 6, 7, 1, 7, 2, // left
- 7, 4, 3, 7, 3, 2, // down
- 4, 7, 6, 4, 6, 5 // back
- ]);
- const vertexColorbuffer = gl.createBuffer();
- const indexBuffer = gl.createBuffer();
- const size = verticesColors.BYTES_PER_ELEMENT;
- gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
- gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
- var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
- gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, size * 6, 0);
- gl.enableVertexAttribArray(a_Position);
- var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
- gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, size * 6, size * 3);
- gl.enableVertexAttribArray(a_Color);
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
-
- return indices.length;
- }
- const n = initVertexBuffers();
- gl.clearColor(0.0, 0.0, 0.0, 1.0);
- gl.enable(gl.DEPTH_TEST);
- console.log(n, 'nnn')
- var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_ViewProjMatrix');
- var mvpMatrix = new Matrix4();
- mvpMatrix.setPerspective(30, 1, 1, 100);
- mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0);
- gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
-
- script>
- body>
-
- html>
- var canvasElement=document.getElementById('webgl');
- var gl=canvasElement.getContext('webgl');
- //顶点着色器源码
- var vertexShaderSource = '' +
- //attribute声明vec4类型变量apos
- '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;' +
- '}';
- //片元着色器源码
- var fragShaderSource = '' +
- 'void main(){' +
- ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
- '}';
- //初始化着色器
- var program = initShader(gl,vertexShaderSource,fragShaderSource);
- //获取顶点着色器的位置变量apos
- var aposLocation = gl.getAttribLocation(program,'apos');
-
- // 8个顶点坐标数组
- 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 indexesBuffer=gl.createBuffer();
- //绑定缓冲区对象
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexesBuffer);
- //索引数组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模式绘制后8个点
- 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;
- }
glDrawElements 和glDrawArrays的GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON这个模式mode,不同的模式对indices顶点索引数组有不同的解释,包含步长和步进方式;
譬如
Tips:(一般规定逆时针卷绕为正方向)
GL_TRIANGLES:每三个顶点绘制一个三角形,如果顶点数量不是3的倍数,则忽略最后一个或两个顶点。
GL_TRIANGLE_STRIP:有两种情况,
(1)当前顶点序号n是偶数时,三角形三个顶点的顺序是(n - 2, n - 1, n )。
(2)当前顶点序号n是奇数时,三角形三个顶点的顺序是(n - 1, n - 2, n)。
这两种情况,保证了采用此种渲染方式的三角形顶点的卷绕顺序。
例如:对于v2顶点,其序号为2,此时三个顶点的顺序是(v0, v1, v2);对于v3顶点,其序号为3,此时三个顶点的顺序是(v2, v1, v3),均是逆时针卷绕。
GL_TRIANGLE_FAN:一系列顶点中的第一个点为中心点,其他顶点为边缘点,绘制一系列组成扇形的相邻三角形。例如三角形(v0, v1, v2)、(v0, v2, v3)。