根据上一篇学习笔记,理解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
]

理解上述内容后,就可以用矩阵对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>

WebGL学习笔记(2)的更多相关文章

  1. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

  2. webgl学习笔记四-动画

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放   下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...

  3. webgl学习笔记三-平移旋转缩放

    写在前面 建议先阅读下前面我的两篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 平移 1.关键点说明 顶点着色器需要加上 uniform vec4 u_Translation ...

  4. webgl学习笔记二-绘图多点

    写在前面 建议先看下第一篇webgl学习笔记一-绘图单点 第一篇文章,介绍了如何用webgl绘图一个点.接下来本文介绍的是如何绘制多个点.形成一个面. webgl提供了一种很方便的机制,即缓冲区对象, ...

  5. WebGL学习笔记二——绘制基本图元

    webGL的基本图元点.线.三角形 gl.drawArrays(mode, first,count) first,代表从第几个点开始绘制即顶点的起始位置 count,代表绘制的点的数量. mode,代 ...

  6. WEBGL学习笔记(七):实践练手1-飞行类小游戏之游戏控制

    接上一节,游戏控制首先要解决的就是碰撞检测了 这里用到了学习笔记(三)射线检测的内容了 以鸟为射线原点,向前.上.下分别发射3个射线,射线的长度较短大概为10~30. 根据上一节场景的建设,我把y轴设 ...

  7. WebGL学习笔记(3)

    根据上篇笔记,在对3D对象可进行普通的控制后,以及学习了http://hiwebgl.com的教程第10章内容:世界模型的载入以及控制镜头移动,经过多次调试矩阵代码,已经可以实现在世界中旋转镜头/控制 ...

  8. WebGL学习笔记七点一

    第六章讲的是一些GL的一些语法,前面已经涉及,学习时直接跳过,来看第七章,第七章是真正意义的三维立体的出现,其实图形绘制方法是差不多的,就是Z坐标此时不再为0,所以很容易能构造出一些立体图形,但是立体 ...

  9. WebGL学习笔记一

    学习用来做web3D的,从第一页开始学起先做2D的,接下来的程序是一个入门级的程序,可以通过在画板上的不同位置点击而获取不同颜色的点,以画板中心为坐标原点四个象限有不同的颜色,访问地址  http:/ ...

随机推荐

  1. Protocol Buffers序列化原理

    1. 使用Varint编码数据,越小的数据,用少的字节编码.如小于128的用一个字节编码,大于128的用多个字节编码.同时,每个字节最高为1或者0表示是否为数字的一部分. 2. 由于负数的补码表示很大 ...

  2. 理解JavaScript作用域

    这是一篇译文,这里贴上译文地址:http://www.zcfy.cc/article/understanding-scope-in-javascript-8213-scotch-4075.html 这 ...

  3. 编程语言的发展历史剧。(参考https://baijiahao.baidu.com/s?id=1588675986991787716&wfr=spider&for=pc)

    1800年 约瑟夫·玛丽·雅卡尔(Joseph Marie Jacquard),设计出人类历史 上首台可设计织布机——雅卡尔织布机,对将来发展出其他可编程机器起了重要作用 1842年 阿达·洛夫莱斯( ...

  4. VMware 安装提示缺少MicrosoftRuntime DLL 问题解决办法

    VMware 安装提示缺少MicrosoftRuntime DLL 问题解决办法 刚刚安装VMware失败了试了好多办法,在这总结一下. 下面是程序的截图 这是报错信息 网上的解决方法: 当出现安装失 ...

  5. mysql三-1:理解存储引擎

    一.什么是存储引擎 mysql中建立的库===>文件夹 库中建立的表===>文件 生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型,处 ...

  6. 【代码笔记】Java文件的输入输出(1)——Java.io包的初步理解

    Java里面文件的输入输出全部在java.io包里面. Java.io包里面所有的类都需要掌握. java.io包里面所有的东西都在上面了. 包里面的相关类.异常等树关系如下 类分层结构 java.l ...

  7. Windows 线程消息队列和GetMessage实现内幕

      注:转自http://blog.csdn.net/FreeWave/article/details/2056469?reload.        清晰地讲解了Windows线程的消息队列和GetM ...

  8. 收缩事务日志(sqlserver)

    sqlserver数据库的日志文件其实是由很多个逻辑上的日志文件组成,我们可以通过命令看一下数据库日志文件 ​可以看到的是sqlserver数据库日志文件是由很多文件组成的,当数据库日志文件已满的时候 ...

  9. Windows装系统

    这几天电脑频繁崩溃,自己尝试着装了几次系统,遇到一些问题.有的解决了,有的没解决.将其一一记录在这里,作为经验参考. 自己以前最常用的方式是直接通过ultraiso将IOS文件解压到到U盘,会将U盘做 ...

  10. 初识Git与Github

    学习和使用Git和Github的确是一件很有意义的事,通过使用Git和Github,可以让我们很方便地管理自己的各种文件,还可以帮助一名程序员更好地用于代码管理.而对于一名软件技术人员,建立自己的Gi ...