根据上一篇学习笔记,理解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. Python爬虫《Python网络爬虫相关基础概念》

    引入 之前在授课过程中,好多同学都问过我这样的一个问题:为什么要学习爬虫,学习爬虫能够为我们以后的发展带来那些好处?其实学习爬虫的原因和为我们以后发展带来的好处都是显而易见的,无论是从实际的应用还是从 ...

  2. SharePoint Tricks

    1. 64位IE浏览器无法使用Open with Explorer功能,而且会直接用浏览器去打开office文件(不管是否选择使用客户端打开) 2. 对于 large list or library, ...

  3. 《ArcGIS Runtime SDK for Android开发笔记》——(15)、要素绘制Drawtools3.0工具DEMO

    1.前言 移动GIS项目开发中点线面的要素绘制及编辑是最常用的操作,在ArcGIS Runtime SDK for iOS 自带AGSSketchLayer类可以帮助用户快速实现要素的绘制,图形编辑. ...

  4. hibernate 性能优化之 1+N 问题

    1. 注意 session.clear()的运用,尤其在不断分页查询的时候 a) 在一个大集合中进行遍历,遍历 msg,去除其中的含有敏感字样的对象 b) 另外一种形式的内存泄漏 面试题:Java 有 ...

  5. Filter学习总结,顺便提及点servlet3.0异步filter和异步监听

      Filter介绍:     Filter在项目中经常可以用到,通常配置在web.xml中.是服务器端的一个组件,对于用户的请求和响应数据进行过滤操作,控制是否让用户访问到对应的web资源.常用于编 ...

  6. github代码上传教程

    github 上传代码步骤 一.git以及Github Git是个正快速成长的版本控制系统,它由GitHub维护. 优势: 1.支持离线开发,离线Repository. 2.强大的分支功能,适合多个独 ...

  7. 使用embeded tomcat进行嵌入式javaee开发-启动tomcat

    昨天在网上研究了下关于将tomcat嵌入到主程序中进行运行,而不是像以前将一个web项目copy到tomcat中进行运行.之所以这样做的原因,即是因为项目部署到客户方,在进行更新的时候,需要手动地进行 ...

  8. Selenium2学习(四)-- xpath定位

    前言 在上一篇简单的介绍了用工具查看目标元素的xpath地址,工具查看比较死板,不够灵活,有时候直接复制粘贴会定位不到.这个时候就需要自己手动的去写xpath了,这一篇详细讲解xpath的一些语法. ...

  9. 函数名: lseek

    函数名: lseek 功 能: 移动文件读/写指针 头文件:#include <sys/types.h> #include <unistd.h> 用 法: off_t lsee ...

  10. 原生JavaScript实现JSON合并(递归深度合并)

    // 遇到相同元素级属性,以(minor)为准 // 不返还新Object,而是main改变 function mergeJSON(minor, main) { for(var key in mino ...