当前位置: 首页 > news >正文

8、webgl 基本概念 + 图像变换(平移 + 旋转 + 缩放)

基本概念

平移

1、普通坐标进行单一的变换
2、利用向量进行平移
3、在webgl中:
(1)用vec2分量表示平移矢量(-0.5,0.5),如果是三维的就使用 vec4 来定义变量
(2)在三维坐标系上 A(X,Y,Z)
在齐次坐标系中我们会使用(X, Y, Z, W)来表示这个顶点
(X, Y, Z, 0)来表示向量

沿 Z 轴旋转

三角函数的和差公式
在这里插入图片描述

图像变换

常规方式实现平移

利用参数Tx 的传参方式,向x 轴进行平移。
劣势:沿着 Y 轴平移也需要定义变量,获取变量名的位置,再进行赋值计算,比较麻烦,比如下面的平移方式

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><canvas width="500" height="500" id="myCanvas"></canvas><script type="vertex" id="vertex">attribute vec2 a_position;attribute vec4 a_color;uniform float Tx;varying vec4 v_color;void main() {gl_Position = vec4(a_position.x + Tx, a_position.y, 0, 1);gl_PointSize = 10.0;v_color = a_color;}</script><script type="fragment" id="fragment">precision mediump float;varying vec4 v_color;void main() {gl_FragColor = v_color;}</script><script>let myCanvas = document.getElementById("myCanvas");let gl = myCanvas.getContext("webgl");// IE8 之前的浏览器不兼容if(!gl) {alert("浏览器不支持 webgl!")}// 创建着色器function createShader(gl, type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);let isSuccess = gl.getShaderParameter(shader, gl.COMPILE_STATUS);return isSuccess ? shader : console.log(gl.getShaderInfoLog(shader))}// 获取着色器中的文本内容字符串function getInnerText(id) {return document.getElementById(id).innerText;}const vertexStr = getInnerText("vertex");const fragmentStr = getInnerText("fragment");const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr);// 创建程序function createProgram(gl, vertexShader, fragmentShader) {let program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);let isSuccess = gl.getProgramParameter(program, gl.LINK_STATUS);return isSuccess ? program : console.log(gl.getProgramInfoLog(program));}let program = createProgram(gl, vertexShader, fragmentShader);gl.useProgram(program);// 获取顶点着色器中变量let a_position = gl.getAttribLocation(program, 'a_position');let screenSize = gl.getUniformLocation(program, 'screenSize');let Tx = gl.getUniformLocation(program, 'Tx');let a_color = gl.getAttribLocation(program, 'a_color');// 获取画布的宽高,因为顶点着色器中已经gl.uniform2f(screenSize, myCanvas.width, myCanvas.height);gl.uniform1f(Tx, 0.5)let positionBuffer = gl.createBuffer();let indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); // 绑定索引缓冲区gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);// 矩形的正面,要逆时针的顶点进行写, 矩形就是两个三角形,也就是需要写 6个 顶点,  gl.ARRAY_BUFFER 这个缓冲区需要把所有的顶点都写上,但其实例如矩形的时候有些顶点是重复的,当面越来越多就会造成严重的性能问题,此时我们可以使用 gl.ELEMENT_ARRAY_BUFFER(也就是顶点索引)缓冲区来进行优化-只需要传不重复的点gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 1, 0, -0.5, 0.5, 1, 0, 0, 0.5, 0.5, 0, 1, 0, 0.5, -0.5, 0, 0, 1, -0.5, -0.5, 1, 1, 0,-0.5, 0.5, 1, 0, 0]), gl.STATIC_DRAW);// gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([//     0, 1, 2,//     2, 3, 0// ]), gl.STATIC_DRAW);gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 4 * 5, 0);gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, 4 * 5, 4* 2);// 启用这个位置数据gl.enableVertexAttribArray(a_position);gl.enableVertexAttribArray(a_color);// 绘制三角形 drawArrays 直接从数据的缓冲区取数据// gl.drawElements(mode, count, type, offset) // mode: 制定绘制图元的类型, gl.POINTS, gl.TRIANGLES, gl.LINES...// count: 指定绘制图形的顶点个数// type:指定索引缓冲区的值的类型,常用的值有两个 gl.UNSINGED_TYPE(无符号8位整数值) 和 gl.UNSINGED_SHORT(无符号短整型16位)// offset:指定索引数组中开始绘制的位置,以字节为单位// gl.drawElements(gl.TRIANGLES_FAN, 6, gl.UNSIGNED_SHORT, 0);gl.drawArrays(gl.TRIANGLE_FAN, 0, 6);</script>
</body>
</html>

向量的方式进行平移

在三维坐标系上A(X,Y,Z)
在齐次坐标系中我们会使用(X, Y,Z,W)来表示这个顶点
(X, Y, Z, 0)来表示向量

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><canvas width="500" height="500" id="myCanvas"></canvas><script type="vertex" id="vertex">/*在三维坐标系上A(X,Y,Z)在齐次坐标系中我们会使用(X, Y,Z,W)来表示这个顶点(X, Y, Z, 0)来表示向量*/attribute vec4 a_position;attribute vec4 a_color;// 用vec2分量表示平移矢量(-0.5,0.5),如果是三维的就使用 vec4 来定义变量uniform vec4 a_Translate;varying vec4 v_color;void main() {gl_Position = vec4(a_position + a_Translate);gl_PointSize = 10.0;v_color = a_color;}</script><script type="fragment" id="fragment">precision mediump float;varying vec4 v_color;void main() {gl_FragColor = v_color;}</script><script>let myCanvas = document.getElementById("myCanvas");let gl = myCanvas.getContext("webgl");// IE8 之前的浏览器不兼容if(!gl) {alert("浏览器不支持 webgl!")}// 创建着色器function createShader(gl, type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);let isSuccess = gl.getShaderParameter(shader, gl.COMPILE_STATUS);return isSuccess ? shader : console.log(gl.getShaderInfoLog(shader))}// 获取着色器中的文本内容字符串function getInnerText(id) {return document.getElementById(id).innerText;}const vertexStr = getInnerText("vertex");const fragmentStr = getInnerText("fragment");const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr);// 创建程序function createProgram(gl, vertexShader, fragmentShader) {let program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);let isSuccess = gl.getProgramParameter(program, gl.LINK_STATUS);return isSuccess ? program : console.log(gl.getProgramInfoLog(program));}let program = createProgram(gl, vertexShader, fragmentShader);gl.useProgram(program);// 获取顶点着色器中变量let a_position = gl.getAttribLocation(program, 'a_position');let screenSize = gl.getUniformLocation(program, 'screenSize');let a_Translate = gl.getUniformLocation(program, 'a_Translate');let a_color = gl.getAttribLocation(program, 'a_color');// 获取画布的宽高,因为顶点着色器中已经gl.uniform2f(screenSize, myCanvas.width, myCanvas.height);gl.uniform4f(a_Translate, 0.5, -0.5, 0, 0)let positionBuffer = gl.createBuffer();let indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); // 绑定索引缓冲区gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);// 矩形的正面,要逆时针的顶点进行写, 矩形就是两个三角形,也就是需要写 6个 顶点,  gl.ARRAY_BUFFER 这个缓冲区需要把所有的顶点都写上,但其实例如矩形的时候有些顶点是重复的,当面越来越多就会造成严重的性能问题,此时我们可以使用 gl.ELEMENT_ARRAY_BUFFER(也就是顶点索引)缓冲区来进行优化-只需要传不重复的点gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 1, 0, -0.5, 0.5, 1, 0, 0, 0.5, 0.5, 0, 1, 0, 0.5, -0.5, 0, 0, 1, -0.5, -0.5, 1, 1, 0,-0.5, 0.5, 1, 0, 0]), gl.STATIC_DRAW);// gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([//     0, 1, 2,//     2, 3, 0// ]), gl.STATIC_DRAW);gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 4 * 5, 0);gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, 4 * 5, 4* 2);// 启用这个位置数据gl.enableVertexAttribArray(a_position);gl.enableVertexAttribArray(a_color);// 绘制三角形 drawArrays 直接从数据的缓冲区取数据// gl.drawElements(mode, count, type, offset) // mode: 制定绘制图元的类型, gl.POINTS, gl.TRIANGLES, gl.LINES...// count: 指定绘制图形的顶点个数// type:指定索引缓冲区的值的类型,常用的值有两个 gl.UNSINGED_TYPE(无符号8位整数值) 和 gl.UNSINGED_SHORT(无符号短整型16位)// offset:指定索引数组中开始绘制的位置,以字节为单位// gl.drawElements(gl.TRIANGLES_FAN, 6, gl.UNSIGNED_SHORT, 0);gl.drawArrays(gl.TRIANGLE_FAN, 0, 6);</script>
</body>
</html>

常规实现图像旋转

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><canvas width="500" height="500" id="myCanvas"></canvas><script type="vertex" id="vertex">/*在三维坐标系上A(X,Y,Z)在齐次坐标系中我们会使用(X, Y,Z,W)来表示这个顶点(X, Y, Z, 0)来表示向量*/attribute vec4 a_position;attribute vec4 a_color;// 用vec2分量表示平移矢量(-0.5,0.5),如果是三维的就使用 vec4 来定义变量uniform vec4 a_Translate;uniform float cosb, sinb;varying vec4 v_color;void main() {gl_Position.x = a_position.x * cosb - a_position.y * sinb;gl_Position.y = a_position.x * sinb + a_position.y * cosb;gl_Position.z = a_position.z;gl_Position.w = 1.0;gl_PointSize = 10.0;v_color = a_color;}</script><script type="fragment" id="fragment">precision mediump float;varying vec4 v_color;void main() {gl_FragColor = v_color;}</script><script>let myCanvas = document.getElementById("myCanvas");let gl = myCanvas.getContext("webgl");// IE8 之前的浏览器不兼容if(!gl) {alert("浏览器不支持 webgl!")}// 创建着色器function createShader(gl, type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);let isSuccess = gl.getShaderParameter(shader, gl.COMPILE_STATUS);return isSuccess ? shader : console.log(gl.getShaderInfoLog(shader))}// 获取着色器中的文本内容字符串function getInnerText(id) {return document.getElementById(id).innerText;}const vertexStr = getInnerText("vertex");const fragmentStr = getInnerText("fragment");const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr);// 创建程序function createProgram(gl, vertexShader, fragmentShader) {let program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);let isSuccess = gl.getProgramParameter(program, gl.LINK_STATUS);return isSuccess ? program : console.log(gl.getProgramInfoLog(program));}let program = createProgram(gl, vertexShader, fragmentShader);gl.useProgram(program);// 获取顶点着色器中变量let a_position = gl.getAttribLocation(program, 'a_position');let screenSize = gl.getUniformLocation(program, 'screenSize');let a_Translate = gl.getUniformLocation(program, 'a_Translate');let u_cosb = gl.getUniformLocation(program, 'cosb');let u_sinb = gl.getUniformLocation(program, 'sinb');let a_color = gl.getAttribLocation(program, 'a_color');let deg = 45;let cosb = Math.cos(deg * Math.PI /180);let sinb = Math.sin(deg * Math.PI /180);gl.uniform1f(u_cosb, cosb);gl.uniform1f(u_sinb, sinb);// 获取画布的宽高,因为顶点着色器中已经gl.uniform2f(screenSize, myCanvas.width, myCanvas.height);gl.uniform4f(a_Translate, 0.5, -0.5, 0, 0)let positionBuffer = gl.createBuffer();let indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); // 绑定索引缓冲区gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);// 矩形的正面,要逆时针的顶点进行写, 矩形就是两个三角形,也就是需要写 6个 顶点,  gl.ARRAY_BUFFER 这个缓冲区需要把所有的顶点都写上,但其实例如矩形的时候有些顶点是重复的,当面越来越多就会造成严重的性能问题,此时我们可以使用 gl.ELEMENT_ARRAY_BUFFER(也就是顶点索引)缓冲区来进行优化-只需要传不重复的点gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 0, 1, 0, -0.5, 0.5, 0, 1, 0, 0, 0.5, 0.5, 0, 0, 1, 0, 0.5, -0.5, 0, 0, 0, 1, -0.5, -0.5, 0, 1, 1, 0,-0.5, 0.5, 1, 0, 0, 0]), gl.STATIC_DRAW);// gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([//     0, 1, 2,//     2, 3, 0// ]), gl.STATIC_DRAW);gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 4 * 6, 0);gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, 4 * 6, 4* 3);// 启用这个位置数据gl.enableVertexAttribArray(a_position);gl.enableVertexAttribArray(a_color);// 绘制三角形 drawArrays 直接从数据的缓冲区取数据// gl.drawElements(mode, count, type, offset) // mode: 制定绘制图元的类型, gl.POINTS, gl.TRIANGLES, gl.LINES...// count: 指定绘制图形的顶点个数// type:指定索引缓冲区的值的类型,常用的值有两个 gl.UNSINGED_TYPE(无符号8位整数值) 和 gl.UNSINGED_SHORT(无符号短整型16位)// offset:指定索引数组中开始绘制的位置,以字节为单位// gl.drawElements(gl.TRIANGLES_FAN, 6, gl.UNSIGNED_SHORT, 0);gl.drawArrays(gl.TRIANGLE_FAN, 0, 6);</script>
</body>
</html>

传递矩阵进行图像旋转

矩阵传值要按照列为主序,也就是 转置矩阵. 左矩阵的列数是右边矩阵的行数才可以先乘

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><canvas width="500" height="500" id="myCanvas"></canvas><script type="vertex" id="vertex">// 3个点的传值// attribute vec3 a_position;// 4 个点的传值attribute vec4 a_position;attribute vec4 a_color;uniform vec4 a_Translate;// uniform float cosb, sinb;/*用矩阵的方式 声明旋转矩阵*/// 3 行3列的参数定义// uniform mat3 rotateMatrix;// 4行4列的参数定义uniform mat4 rotateMatrix;varying vec4 v_color;void main() {/*gl_Position.x = a_position.x * cosb - a_position.y * sinb;gl_Position.y = a_position.x * sinb + a_position.y * cosb;gl_Position.z = a_position.z;gl_Position.w = 1.0;*/// 三个点的时候,需要转换一下// gl_Position = vec4(rotateMatrix * a_position, 1);// 四个点的时候,直接计算就行gl_Position = rotateMatrix * a_position;gl_PointSize = 10.0;v_color = a_color;}</script><script type="fragment" id="fragment">precision mediump float;varying vec4 v_color;void main() {gl_FragColor = v_color;}</script><script>let myCanvas = document.getElementById("myCanvas");let gl = myCanvas.getContext("webgl");// IE8 之前的浏览器不兼容if(!gl) {alert("浏览器不支持 webgl!")}// 创建着色器function createShader(gl, type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);let isSuccess = gl.getShaderParameter(shader, gl.COMPILE_STATUS);return isSuccess ? shader : console.log(gl.getShaderInfoLog(shader))}// 获取着色器中的文本内容字符串function getInnerText(id) {return document.getElementById(id).innerText;}const vertexStr = getInnerText("vertex");const fragmentStr = getInnerText("fragment");const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr);// 创建程序function createProgram(gl, vertexShader, fragmentShader) {let program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);let isSuccess = gl.getProgramParameter(program, gl.LINK_STATUS);return isSuccess ? program : console.log(gl.getProgramInfoLog(program));}let program = createProgram(gl, vertexShader, fragmentShader);gl.useProgram(program);// 获取顶点着色器中变量let a_position = gl.getAttribLocation(program, 'a_position');let screenSize = gl.getUniformLocation(program, 'screenSize');let a_Translate = gl.getUniformLocation(program, 'a_Translate');let rotateMatrix = gl.getUniformLocation(program, 'rotateMatrix');let a_color = gl.getAttribLocation(program, 'a_color');let deg = 40;let cosb = Math.cos(deg * Math.PI /180);let sinb = Math.sin(deg * Math.PI /180);// 矩阵传值要按照列为主序,也就是 转置矩阵. 左矩阵的列数是右边矩阵的行数才可以先乘// gl.uniformMatrix3fv(rotateMatrix, false, new Float32Array([//     cosb, sinb, 0,//     -sinb, cosb, 0,//     0, 0, 1// ]));// 四个分量的时候矩阵传值gl.uniformMatrix4fv(rotateMatrix, false, new Float32Array([cosb, sinb, 0, 0,-sinb, cosb, 0, 0,0, 0, 1, 0,0, 0, 0, 1]));let positionBuffer = gl.createBuffer();let indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); // 绑定索引缓冲区gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);// 矩形的正面,要逆时针的顶点进行写, 矩形就是两个三角形,也就是需要写 6个 顶点,  gl.ARRAY_BUFFER 这个缓冲区需要把所有的顶点都写上,但其实例如矩形的时候有些顶点是重复的,当面越来越多就会造成严重的性能问题,此时我们可以使用 gl.ELEMENT_ARRAY_BUFFER(也就是顶点索引)缓冲区来进行优化-只需要传不重复的点gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 0, 1, 0, -0.5, 0.5, 0, 1, 0, 0, 0.5, 0.5, 0, 0, 1, 0, 0.5, -0.5, 0, 0, 0, 1, -0.5, -0.5, 0, 1, 1, 0,-0.5, 0.5, 1, 0, 0, 0]), gl.STATIC_DRAW);// gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([//     0, 1, 2,//     2, 3, 0// ]), gl.STATIC_DRAW);gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 4 * 6, 0);gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, 4 * 6, 4* 3);// 启用这个位置数据gl.enableVertexAttribArray(a_position);gl.enableVertexAttribArray(a_color);// 绘制三角形 drawArrays 直接从数据的缓冲区取数据// gl.drawElements(mode, count, type, offset) // mode: 制定绘制图元的类型, gl.POINTS, gl.TRIANGLES, gl.LINES...// count: 指定绘制图形的顶点个数// type:指定索引缓冲区的值的类型,常用的值有两个 gl.UNSINGED_TYPE(无符号8位整数值) 和 gl.UNSINGED_SHORT(无符号短整型16位)// offset:指定索引数组中开始绘制的位置,以字节为单位// gl.drawElements(gl.TRIANGLES_FAN, 6, gl.UNSIGNED_SHORT, 0);gl.drawArrays(gl.TRIANGLE_FAN, 0, 6);</script>
</body>
</html>

传入矩阵进行图像缩放

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><canvas width="500" height="500" id="myCanvas"></canvas><script type="vertex" id="vertex">attribute vec4 a_position;attribute vec4 a_color;uniform vec4 a_Translate;uniform mat4 scaleMatrix;varying vec4 v_color;void main() {// 缩放gl_Position = scaleMatrix * a_position;gl_PointSize = 10.0;v_color = a_color;}</script><script type="fragment" id="fragment">precision mediump float;varying vec4 v_color;void main() {gl_FragColor = v_color;}</script><script>let myCanvas = document.getElementById("myCanvas");let gl = myCanvas.getContext("webgl");// IE8 之前的浏览器不兼容if(!gl) {alert("浏览器不支持 webgl!")}// 创建着色器function createShader(gl, type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);let isSuccess = gl.getShaderParameter(shader, gl.COMPILE_STATUS);return isSuccess ? shader : console.log(gl.getShaderInfoLog(shader))}// 获取着色器中的文本内容字符串function getInnerText(id) {return document.getElementById(id).innerText;}const vertexStr = getInnerText("vertex");const fragmentStr = getInnerText("fragment");const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr);// 创建程序function createProgram(gl, vertexShader, fragmentShader) {let program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);let isSuccess = gl.getProgramParameter(program, gl.LINK_STATUS);return isSuccess ? program : console.log(gl.getProgramInfoLog(program));}let program = createProgram(gl, vertexShader, fragmentShader);gl.useProgram(program);// 获取顶点着色器中变量let a_position = gl.getAttribLocation(program, 'a_position');let screenSize = gl.getUniformLocation(program, 'screenSize');let a_Translate = gl.getUniformLocation(program, 'a_Translate');let rotateMatrix = gl.getUniformLocation(program, 'rotateMatrix');let scaleMatrix = gl.getUniformLocation(program, 'scaleMatrix');let a_color = gl.getAttribLocation(program, 'a_color');let Sx = 1.5, Sy = 0.5, Sz = 1;let deg = 40;let cosb = Math.cos(deg * Math.PI /180);let sinb = Math.sin(deg * Math.PI /180);gl.uniformMatrix4fv(scaleMatrix, false, new Float32Array([Sx, 0, 0, 0,0, Sy, 0, 0,0, 0, Sz, 0,0, 0, 0, 1]))// 矩阵传值要按照列为主序,也就是 转置矩阵. 左矩阵的列数是右边矩阵的行数才可以先乘// gl.uniformMatrix3fv(rotateMatrix, false, new Float32Array([//     cosb, sinb, 0,//     -sinb, cosb, 0,//     0, 0, 1// ]));// 四个分量的时候矩阵传值gl.uniformMatrix4fv(rotateMatrix, false, new Float32Array([cosb, sinb, 0, 0,-sinb, cosb, 0, 0,0, 0, 1, 0,0, 0, 0, 1]));let positionBuffer = gl.createBuffer();let indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); // 绑定索引缓冲区gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);// 矩形的正面,要逆时针的顶点进行写, 矩形就是两个三角形,也就是需要写 6个 顶点,  gl.ARRAY_BUFFER 这个缓冲区需要把所有的顶点都写上,但其实例如矩形的时候有些顶点是重复的,当面越来越多就会造成严重的性能问题,此时我们可以使用 gl.ELEMENT_ARRAY_BUFFER(也就是顶点索引)缓冲区来进行优化-只需要传不重复的点gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 0, 1, 0, -0.5, 0.5, 0, 1, 0, 0, 0.5, 0.5, 0, 0, 1, 0, 0.5, -0.5, 0, 0, 0, 1, -0.5, -0.5, 0, 1, 1, 0,-0.5, 0.5, 1, 0, 0, 0]), gl.STATIC_DRAW);// gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([//     0, 1, 2,//     2, 3, 0// ]), gl.STATIC_DRAW);gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 4 * 6, 0);gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, 4 * 6, 4* 3);// 启用这个位置数据gl.enableVertexAttribArray(a_position);gl.enableVertexAttribArray(a_color);// 绘制三角形 drawArrays 直接从数据的缓冲区取数据// gl.drawElements(mode, count, type, offset) // mode: 制定绘制图元的类型, gl.POINTS, gl.TRIANGLES, gl.LINES...// count: 指定绘制图形的顶点个数// type:指定索引缓冲区的值的类型,常用的值有两个 gl.UNSINGED_TYPE(无符号8位整数值) 和 gl.UNSINGED_SHORT(无符号短整型16位)// offset:指定索引数组中开始绘制的位置,以字节为单位// gl.drawElements(gl.TRIANGLES_FAN, 6, gl.UNSIGNED_SHORT, 0);gl.drawArrays(gl.TRIANGLE_FAN, 0, 6);</script>
</body>
</html>
http://www.dtcms.com/a/575223.html

相关文章:

  • 郑州建设信息网站环球网最新国际新闻
  • 租赁公司网站源码上线吧做的网站可以备案
  • 手机网站开发解决方案如何将自己做的网页做成网站
  • 在JavaScript中,将包含HTML实体字符的字符串转换为普通字符
  • 网站 建设理由网页设计教程详细步骤ppt
  • 深入理解 Python 的“左闭右开”设计哲学
  • 公司网站建设维保协议wordpress文本块表格
  • hanchengkeji杭州网站建设做网站后台维护的岗位叫什么
  • 企业网站建设最新技术diy小程序开发平台
  • 网站建设功能报价单网站建设资格预审公告
  • wordpress添加动漫人物深圳网站优化
  • 日均亿级数据的实时分析:Doris如何接过Spark的接力棒?
  • 网站建设微信官网开发外贸网站做的作用是什么
  • 东莞网络公司哪个网站好wordpress博客怎么搜索
  • 怎么给网站创建二维码国内知名企业网站
  • 网站建设的公司邢台市信都区
  • 功能型网站开发者模式有什么危害
  • 手机网站开发 1433端口错误sem优化系统
  • 关键词解释:Focal Loss解决类别极度不平衡问题而设计的损失函数
  • Kubernetes-入门概念
  • 竞拍网站建设电子商务网站建设概括
  • 用卫生纸做的礼物街网站模板网站自助建站
  • 电影模板哪个网站好2345浏览器导航页
  • 扬州市市政建设处网站上海网络维护有哪些公司
  • 农村网站建设调查报告兰州市城乡建设局网站官网
  • 电竞竞猜网站 建设五大建设是指什么
  • 联合建设官方网站做网站用的书
  • 手机主题如何自己制作网站wordpress精简主题
  • wordpress 用iis建站特价服务器
  • 重庆招聘网站哪个好外加工平台