WebGL学习笔记(2)

根据上一篇学习笔记,理解WebGL的工作原理及基本调用代码后,可以开始研究3D顶点对象的缩放、旋转、以及对对象进行可交互(鼠标或键盘控制)的旋转或者缩放。

要理解对象的旋转/缩放需要首先学习矩阵的计算原理,关于矩阵变换参考这两篇文章:
https://blog.csdn.net/jscese/article/details/52065628
https://blog.csdn.net/u012501459/article/details/12945149#transform

其中还涉及到了Math函数的cos正切(输入弧度参数得到三角形的对边/邻边的比值)与sin正弦函数,具体的内容请自行百度百科。

矩阵计算的学习笔记:

1个vec * 1个mat4得到1个新的vec:

Vec*mat4计算示例:
Mat = [
M1,m2,m3,m4
M5,m6,m7,m8
M9,m10,m11,m12,
M13,m14,m15,m16
]
Vec = [x,y,z,1]

New_vec_x = x*m1+y*m5+z*m9+1*m13
New_vec_y = x*m2+y*m6+z*m10+1*m14
New_vec_z = x*m3+y*m7+z*m11+1*m15
New_vec_1 = x*m4+y*m8+z*m12+1*m16
New_vec = [new_vec_x, new_vec_y, new_vec_z, new_vec1]

常用的矩阵变换:

Uniform Scaling 统一缩放矩阵:
s=1.5 顶点缩放1.5倍
[
s,0,0,0,
0,s,0,0,
0,0,s,0,
0,0,0,1
]

平移矩阵:
[
1,0,0,tx
0,1,0,ty,
0,0,1,tz,
0,0,0,1
]

沿x轴旋转矩阵
[
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
]
沿z轴旋转矩阵
[
cosθ, sinθ, 0, 0
-sinθ, cosθ, 0, 0
0, 0,1, 0
0,0,0,1
]

扫描二维码关注公众号,回复: 1803277 查看本文章

理解上述内容后,就可以用矩阵对webgl对象进行缩放/旋转/平移了,测试代码如下,拷贝到您的浏览器可以查看一个立方体并可以用鼠标进行旋转控制:

<!doctype html>
<html>
<head>
</head>
<body>

<canvas id="my_Canvas" width="500" height="500"></canvas>

<script>

var canvas = document.getElementById('my_Canvas')

var gl = canvas.getContext('experimental-webgl')

var vertices = [
-1, -1, -1,
1, -1, -1,
-1, 1, -1,
1, 1, -1,

-1, -1, 1,
1, -1, 1,
-1, 1, 1,
1, 1, 1,
]

var vertex_buffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
gl.bindBuffer(gl.ARRAY_BUFFER, null)

var vertCode = `
attribute vec3 coordinates;
uniform mat4 myTranslateMatrix;
uniform mat4 myScaleMatrix;
uniform mat4 myRotateMatrix;
uniform mat4 myRotateXMatrix;
uniform mat4 myRotateZMatrix;
void main(void){
gl_Position = ( vec4(coordinates, 2.5) )*myTranslateMatrix*myScaleMatrix * myRotateMatrix * myRotateXMatrix * myRotateZMatrix;
gl_PointSize = 10.0;
}
`

var fragCode = `
void main(void){
gl_FragColor = vec4(0.1,0.1,0.1, 1.0);
}
`

var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode)
gl.compileShader(vertShader)

var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode)
gl.compileShader(fragShader)

var program = gl.createProgram()
gl.attachShader(program, vertShader)
gl.attachShader(program, fragShader)
gl.linkProgram(program)
gl.useProgram(program)


var coordinates = gl.getAttribLocation(program, 'coordinates')
gl.enableVertexAttribArray(coordinates)
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer)
gl.vertexAttribPointer(coordinates, 3, gl.FLOAT, false, 0,0)

var myTranslateMatrix = gl.getUniformLocation(program, 'myTranslateMatrix')

var myTranslate = function(gl, matrixUniform, x,y,z){
var matrix = new Float32Array([
1,0,0,x,
0,1,0,y,
0,0,1,z,
0,0,0,1
])
gl.uniformMatrix4fv(matrixUniform, false, matrix)
}

var myScaleMatrix = gl.getUniformLocation(program, 'myScaleMatrix')

myScale = function(gl, matrixUniform, scale){

gl.uniformMatrix4fv(matrixUniform, false, new Float32Array([
scale, 0, 0, 0,
0, scale, 0,0,
0,0,scale,0,
0,0,0,1
]))

}


myRotateX = function(gl, myRotateMatrix, jd){
var hd;
var coshd;
var sinhd;
hd=jd*Math.PI/180
coshd=Math.cos(hd)
sinhd=Math.sin(hd)

gl.uniformMatrix4fv(myRotateMatrix, false, new Float32Array([
1, 0,0,0,
0, coshd,sinhd,0,
0, -1*sinhd, coshd, 0,
0,0,0,1

]))
}

myRotateY = function(gl, myRotateMatrix, jd){
var hd;
var coshd;
var sinhd;
hd=jd*Math.PI/180
coshd=Math.cos(hd)
sinhd=Math.sin(hd)
gl.uniformMatrix4fv(myRotateMatrix, false, new Float32Array([
coshd, 0,-1*sinhd,0,
0, 1,0,0,
sinhd, 0 , coshd, 0,
0,0,0,1

]))
}

myRotateZ = function(gl, myRotateMatrix, jd){
var hd;
var coshd;
var sinhd;
hd=jd*Math.PI/180
coshd=Math.cos(hd)
sinhd=Math.sin(hd)
gl.uniformMatrix4fv(myRotateMatrix, false, new Float32Array([
coshd, sinhd,0,0,
-1*sinhd, coshd,0,0,
0, 0 , 1, 0,
0,0,0,1

]))
}

var xjd=0,yjd=0,zjd=0

var moving = false
var mov_x_length = 0
var mov_y_length = 0
var page_x=0;
var page_y=0;

canvas.onmousedown = function(e){
moving = true
console.log('mousedown', e)
page_x = e.x
page_y = e.y
}

canvas.onmouseup = function(e) {
moving = false
console.log('mouseup', e)
}

canvas.onmousemove = function(e) {
if(moving) {
//console.log('mousemove', e)
mov_x_length+=page_x-e.x
mov_y_length+=page_y-e.y
// e.x, e.y
console.log(mov_x_length, mov_y_length)
page_x = e.x
page_y = e.y
}
}

myRotateMatrix = gl.getUniformLocation(program, 'myRotateMatrix')
myRotateXMatrix = gl.getUniformLocation(program, 'myRotateXMatrix')
myRotateZMatrix = gl.getUniformLocation(program, 'myRotateZMatrix')

animate = function(){

myTranslate(gl, myTranslateMatrix, 0,0,0.0)
myScale(gl, myScaleMatrix, 1)

myRotateX(gl,myRotateXMatrix, mov_y_length)
myRotateY(gl,myRotateMatrix, mov_x_length)
myRotateZ(gl,myRotateZMatrix, zjd)
gl.clearColor(0.5,0.5,0.5, 1.0)
gl.enable(gl.DEPTH_TEST)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.viewport(0,0,canvas.width, canvas.height)
gl.drawArrays(gl.LINE_LOOP, 0, 8)

requestAnimationFrame(animate)
}

animate()

</script>

</body>
</html>

猜你喜欢

转载自www.cnblogs.com/bird-eat-vegetable/p/9247361.html