根据上一篇学习笔记,理解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. [转]MySQL索引类型

    此为转载文章,仅做记录使用,方便日后查看,原文链接:https://www.cnblogs.com/luyucheng/p/6289714.html MySQL索引类型   一.简介 MySQL目前主 ...

  2. python的元组及其书写规矩

    1.元组 (1)元组看起来犹如列表,但使用圆括号而不是方括号来标识.定义元组后,就可以使用索引来访问其元素,就像访问列表元素一样. (2)元组的元素不可修改,但是可以赋值. 2.规矩 (1)缩进:建议 ...

  3. Stage6--Python简单爬虫

    正则表达式简单介绍 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将匹配的子串做替换或者从某个串中取出符合某个条件的子串等. 字符 ...

  4. solidity语言8

    输入参数 pragma solidity ^0.4.16; contract Simple { function taker(uint _a, uint _b) public pure { // do ...

  5. python 02/100例

    题目 输入某年某月某日,判断这一天是这一年的第几天? 分析 例如:2018年6月19日 天数 = 19天 + 一月天数 + 2月天数 + ... + 6月天数 注意 闰年的2月是29天,如果年份是闰年 ...

  6. March 5 2017 Week 10 Sunday

    If you do what you love, you will never work a day in your life. 做你所爱的事情,你就不会觉得是在工作. Today, one mach ...

  7. ZT c++ 中的重载全局new,delete

    c++ 中的重载全局new,delete 分类: c++ 2010-08-06 10:31 116人阅读 评论(1) 收藏 举报 deletec++file编译器语言工作 最近做一个小项目,对c++又 ...

  8. YouTube 1080P高清视频下载方法

    在国内在线视频网站还停留在1080P蓝光的时候,YouTube早已经支持4K和8K分辨率的极清视频.虽然4K和8K的清晰度比1080P高了许多档次,但是大部分人的电脑播放4K视频还是很卡的,所以目前来 ...

  9. Kubernetes stateful set讲解以及一个基于postgreSQL的具体例子

    Stateful Set是Kubernetes 1.9版本新引入的一个概念,用于管理有状态的应用. Kubernetes官方文档: https://kubernetes.io/docs/concept ...

  10. Django运行访问项目出现的问题:Invalid HTTP_HOST header: '192.168.114.25:8001'. You may need to add u'192.168.114.25' to ALLOWED_HOSTS.

    当运行python manage.py runserver 0.0.0.0:8001时候,出现Invalid HTTP_HOST header: '192.168.114.25:8001'. You ...