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
]
理解上述内容后,就可以用矩阵对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)的更多相关文章
- webgl学习笔记五-纹理
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...
- webgl学习笔记四-动画
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...
- webgl学习笔记三-平移旋转缩放
写在前面 建议先阅读下前面我的两篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 平移 1.关键点说明 顶点着色器需要加上 uniform vec4 u_Translation ...
- webgl学习笔记二-绘图多点
写在前面 建议先看下第一篇webgl学习笔记一-绘图单点 第一篇文章,介绍了如何用webgl绘图一个点.接下来本文介绍的是如何绘制多个点.形成一个面. webgl提供了一种很方便的机制,即缓冲区对象, ...
- WebGL学习笔记二——绘制基本图元
webGL的基本图元点.线.三角形 gl.drawArrays(mode, first,count) first,代表从第几个点开始绘制即顶点的起始位置 count,代表绘制的点的数量. mode,代 ...
- WEBGL学习笔记(七):实践练手1-飞行类小游戏之游戏控制
接上一节,游戏控制首先要解决的就是碰撞检测了 这里用到了学习笔记(三)射线检测的内容了 以鸟为射线原点,向前.上.下分别发射3个射线,射线的长度较短大概为10~30. 根据上一节场景的建设,我把y轴设 ...
- WebGL学习笔记(3)
根据上篇笔记,在对3D对象可进行普通的控制后,以及学习了http://hiwebgl.com的教程第10章内容:世界模型的载入以及控制镜头移动,经过多次调试矩阵代码,已经可以实现在世界中旋转镜头/控制 ...
- WebGL学习笔记七点一
第六章讲的是一些GL的一些语法,前面已经涉及,学习时直接跳过,来看第七章,第七章是真正意义的三维立体的出现,其实图形绘制方法是差不多的,就是Z坐标此时不再为0,所以很容易能构造出一些立体图形,但是立体 ...
- WebGL学习笔记一
学习用来做web3D的,从第一页开始学起先做2D的,接下来的程序是一个入门级的程序,可以通过在画板上的不同位置点击而获取不同颜色的点,以画板中心为坐标原点四个象限有不同的颜色,访问地址 http:/ ...
随机推荐
- go语言中文处理
中文在go语言中占三个字节,len 或者 range 一个含中文的字符串跟我们预期的结果不一样 求长度用 utf8.RuneCountInString,遍历用 rune func main() { t ...
- 关于消息推送的补充,主要介绍服务端的实现,包含object c 版本 c 版本 java 版本 php 版本 (转)
要实现消息推送功能,我们可以采用第三方(腾讯:信鸽:百度:云推送:极光推送:友盟):当然,因为各种原因,我们不能使用第三方的推送服务,那我们就需要自己编写服务端.在网上寻觅了很久,找到一篇很不错的讲解 ...
- Csharp: Detect Mobile Browsers
/// <summary> /// 檢測手機客戶端 HttpCapabilitiesBase.IsMobileDevice /// .NET 4.5 /// 塗聚文注 /// </s ...
- Android开发ListView嵌套ImageView实现单选按钮
做Android开发两年的时间,技术稍稍有一些提升,刚好把自己实现的功能写出来,记录一下,如果能帮助到同行的其他人,我也算是做了件好事,哈哈!!废话不多说,先上个图. 先上一段代码: if (last ...
- myeclipse 2014 闪退问题解决
1.删掉Workspace下面的 \.metadata\.plugins\org.eclipse.core.resources一整个文件夹 2.删掉Workspace 下面的 \.metadata\ ...
- mysql 常用操作语句
1 根据表中的其中一个字段的值来修改同行某字段的值 UPDATE radar a INNER JOIN radar b ON a.id=b.id SET a.letter=LEFT(b.filena ...
- SharePoint 2013 - Client Side Rendering
1. Client side rendering 代码结构为: (function () { // Create object that have the context information ab ...
- 《ArcGIS Runtime SDK for Android开发笔记》——问题集:Error:Error: File path too long on Windows, keep below 240 characters
1.前言 在使用Android Studio开发环境时,经常会爆出以下错误,虽然具体细节内容各有不同,但是说明的都是同一个问题,在windows中使用过长的路径,超过240字符. Error:Erro ...
- Java—集合框架 Collections.sort()、Comparable接口和Comparator接口
Collentions工具类--java.util.Collections Collentions是Java集合框架中,用来操作集合对象的工具类,也是Java集合框架的成员,与List.Map和Set ...
- C#设计模式之代理模式(一)
原文地址:http://blog.csdn.net/lovelion/article/details/8227953 代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时 ...