WebGl 旋转(矩阵变换)
代码1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGl 旋转(矩阵变换)</title>
</head>
<body>
<canvas id="myCanvas" width="500" height="300" style="border: 1px solid red"></canvas>
</body>
<script> window.onload = function () { //第1步 - 准备Canvas和获取WebGL的渲染上下文
var canvas = document.getElementById('myCanvas'),
gl = canvas.getContext('webgl'); //第2步 - 定义几何并将其存储在缓冲区对象
var vertices = [
-0.5,0.5,0.0,
0.0,0.5,0.0,
-0.25,0.25,0.0,
],
colors = [
0,0,1,
1,0,0,
0,1,0,],
indices =[0,1,2]; var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var color_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var index_buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); //第3步 - 创建和编译着色器程序
var vertCode =
'attribute vec3 coordinates;' +
'uniform mat4 rotate;'+
'attribute vec3 color;'+
'varying vec3 vColor;'+
'void main(void) {' +
' gl_Position = rotate*vec4(coordinates,1.0);' +
'vColor = color;'+
'}'; var fragCode =
'precision mediump float;'+
'varying vec3 vColor;'+
'void main(void) {' +
' gl_FragColor = vec4(vColor, 1);' +
'}'; var vertShader = gl.createShader(gl.VERTEX_SHADER);
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(vertShader);
gl.compileShader(fragShader);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram); //第4步 - 关联着色器程序到缓冲区对象 gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord = gl.getAttribLocation(shaderProgram, 'coordinates');
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord); gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
var color = gl.getAttribLocation(shaderProgram, "color");
gl.vertexAttribPointer(color, 3, gl.FLOAT, false,0,0) ; //color
gl.enableVertexAttribArray(color); //绕着Z轴旋转
var init_angle = 0.0;//初始角度
var angle_step = 1;//旋转步伐
var current_angle = init_angle;
var radian = Math.PI * (current_angle % 360) / 180.0;
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
var xformMatrix = new Float32Array([
cosB, sinB, 0.0, 0.0,
-sinB, cosB, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]);
var rotate = gl.getUniformLocation(shaderProgram, "rotate");
gl.uniformMatrix4fv(rotate, false, xformMatrix); //第5步 - 绘制所需的对象
setInterval(function () {
radian = Math.PI * (current_angle % 360) / 180.0;
cosB = Math.cos(radian);
sinB = Math.sin(radian);
xformMatrix = new Float32Array([
cosB, sinB, 0.0, 0.0,
-sinB, cosB, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]);
gl.uniformMatrix4fv(rotate, false, xformMatrix); gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.clearColor(0.5, 0.5, 0.5, 0.9);
gl.clearDepth(1.0);
gl.viewport(0.0, 0.0, canvas.width, canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); //当前角度
current_angle = current_angle + angle_step; },10); } </script>
</html>
代码2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGl 旋转(矩阵变换)</title>
</head>
<body>
<canvas id="myCanvas" width="500" height="300" style="border: 1px solid red"></canvas>
</body>
<script> window.onload = function () { //第1步 - 准备Canvas和获取WebGL的渲染上下文
var canvas = document.getElementById('myCanvas'),
gl = canvas.getContext('webgl'); //第2步 - 定义几何并将其存储在缓冲区对象
var vertices = [
-0.5,0.5,0.0,
0.0,0.5,0.0,
-0.25,0.25,0.0,
],
colors = [
0,0,1,
1,0,0,
0,1,0,],
indices =[0,1,2]; var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var color_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var index_buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); //第3步 - 创建和编译着色器程序
var vertCode =
'attribute vec3 coordinates;' +
'uniform mat4 Pmatrix;'+
'uniform mat4 Vmatrix;'+
'uniform mat4 Mmatrix;'+
'attribute vec3 color;'+
'varying vec3 vColor;'+
'void main(void) {' +
' gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(coordinates,1.0);' +
'vColor = color;'+
'}'; var fragCode =
'precision mediump float;'+
'varying vec3 vColor;'+
'void main(void) {' +
' gl_FragColor = vec4(vColor, 1);' +
'}'; var vertShader = gl.createShader(gl.VERTEX_SHADER);
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(vertShader);
gl.compileShader(fragShader);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram); //第4步 - 关联着色器程序到缓冲区对象
var Pmatrix = gl.getUniformLocation(shaderProgram, "Pmatrix");
var Vmatrix = gl.getUniformLocation(shaderProgram, "Vmatrix");
var Mmatrix = gl.getUniformLocation(shaderProgram, "Mmatrix"); gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord = gl.getAttribLocation(shaderProgram, 'coordinates');
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord); gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
var color = gl.getAttribLocation(shaderProgram, "color");
gl.vertexAttribPointer(color, 3, gl.FLOAT, false,0,0) ; //color
gl.enableVertexAttribArray(color); //
var proj_matrix = get_projection(40, canvas.width/canvas.height, 1, 100);
var mov_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
var view_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; //translating z
view_matrix[14] = view_matrix[14]-2; //zoom //第5步 - 绘制所需的对象
var time_old = 0;
var animate = function(time) {
var dt = time-time_old;
rotateZ(mov_matrix, dt*0.002);
time_old = time; gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.clearColor(0.5, 0.5, 0.5, 0.9);
gl.clearDepth(1.0);
gl.viewport(0.0, 0.0, canvas.width, canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // 将旋转矩阵传输给顶点着色器
gl.uniformMatrix4fv(Pmatrix, false, proj_matrix);
gl.uniformMatrix4fv(Vmatrix, false, view_matrix);
gl.uniformMatrix4fv(Mmatrix, false, mov_matrix); gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
window.requestAnimationFrame(animate);
} animate(0); /*========================= MATRIX ========================= */ function get_projection(angle, a, zMin, zMax) {
var ang = Math.tan((angle*.5)*Math.PI/180);//angle*.5
return [
0.5/ang, 0 , 0, 0,
0, 0.5*a/ang, 0, 0,
0, 0, -(zMax+zMin)/(zMax-zMin), -1,
0, 0, (-2*zMax*zMin)/(zMax-zMin), 0
];
} //z轴旋转
function rotateZ(m, angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
var mv0 = m[0], mv4 = m[4], mv8 = m[8]; m[0] = c*m[0]-s*m[1];
m[4] = c*m[4]-s*m[5];
m[8] = c*m[8]-s*m[9];
m[1] = c*m[1]+s*mv0;
m[5] = c*m[5]+s*mv4;
m[9] = c*m[9]+s*mv8;
} } </script>
</html>
WebGl 旋转(矩阵变换)的更多相关文章
- webGL 旋转算法
lon = 0,//y旋转角度 lat = 0, onMouseDownLat = 0, phi = 0, theta = 0; if ( isUserInteracting === false ) ...
- WebGL简易教程(五):图形变换(模型、视图、投影变换)
[toc] 1. 概述 通过之前的教程,对WebGL中可编程渲染管线的流程有了一定的认识.但是只有前面的知识还不足以绘制真正的三维场景,可以发现之前我们绘制的点.三角形的坐标都是[-1,1]之间,Z值 ...
- Unity中动态绘制圆柱体
问题背景 上次写了动态绘制立方体,这最近又来了新功能,绘制圆柱(风筒),要求是给了很多节点,根据节点去动态绘制风筒,风筒就是圆柱连接而成的,可以理解为管道,还有就是拐角处注意倒角,圆润过度过来. 实现 ...
- 探索颜色渐变绘制算法(基于Processing语言) 第一部分
突然间意识到连续变化的颜色在程序中是如何实现的这一问题.没错,就想有事找事,我会分好几部分慢慢探寻,其实笔者也不会,咱一起研究.ok,我们开始! 第一部分 初始部分就从官方案例来入手学习.官方给了三个 ...
- webgl自学笔记——矩阵变换
这章主要探讨矩阵,这些矩阵代表了应用在我们场景上的变换,允许我们移动物体.然而在webGL api中并没有一个专门的camera对象,只有矩阵.好消息是使用矩阵来取代相机对象能让webgl在很多复杂动 ...
- osg矩阵变换节点-----平移旋转缩放
osg矩阵变换节点-----平移旋转缩放 转自:http://www.cnblogs.com/ylwn817/articles/1973396.html 平移旋转缩放这个三个是osg矩阵操作中,最常见 ...
- WebGL编程指南案例解析之平移和旋转的矩阵实现
手写各种矩阵: //矩阵 var vShader = ` attribute vec4 a_Position; uniform mat4 u_xformMatrix; void main(){ gl_ ...
- WebGL编程指南案例解析之平移和旋转的math库实现
这里说的math库实现,指的是,通过一般的加减乘除(角度计算)来更新坐标值. 因为涉及到坐标的变化,所以这里都是基于对顶点着色器的修改 平移: var vShader = ` attribute ve ...
- WebGl 缩放(矩阵变换)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
随机推荐
- GetModuleFileName
原文:http://www.cnblogs.com/dongzhiquan/archive/2009/07/28/1994776.html GetModuleFileName HMODULE hMod ...
- Android踩坑随笔Fragment中onActivityResult方法不被调用
最近项目里要做头像功能,参考了这篇博客(GitHub - zhudfly/SelectAvatarApplication: 一个选择并显示头像圆形控件,可以通过拍照或者选择相册中的图片来设置图片),但 ...
- java中方法调用在内存中的体现
在java中,方法以及局部变量(即在方法中声明的变量)是放在栈内存上的.当你调用一个方法时,该方法会放在调用栈的栈顶.栈顶的方法是目前正在执行的方法,直到执行完毕才会从栈顶释放.我们知道,栈是一种执行 ...
- 毕向东_Java基础视频教程第20天_IO流(5~6)
第20天-05-IO流(文件列表一) static File[] listRoots() List the available filesystem roots. String[] list() Re ...
- Windows环境下JDK的配置及多版本JDK切换的方法记录
(这里记录了笔者了解的关于JDK环境配置的信息,以及针对系统上存在不同版本JDK时所尝试的解决方案.具体来说,是已安装 JDK 8 后,又安装了 JDK 9 时所遇到的问题和尝试的解决方法.这次记录以 ...
- 【RabbitMQ】2、RabbitMQ入门程序——Hello World
首先说一下,MQ全称为Message Queue消息队列是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.消息传递指的是程序 ...
- ZOJ-3279 Ants 树状数组 + 二分
题目链接: https://cn.vjudge.net/problem/ZOJ-3279 题目大意: 有1到n 那个level 每一个level有a[i]只蚂蚁两种操作 p a b 把第a个level ...
- iOS--性能优化--保持界面流畅
卡顿产生的原因和解决方案 在 VSync 信号到来后,系统图形服务会通过 CADisplayLink 等机制通知 App,App 主线程开始在 CPU 中计算显示内容,比如视图的创建.布局计算.图片解 ...
- 【LGP5162】WD与积木
题目 场面过度玄学,容易引起不适 我们发现我们要求的这个期望由分母和分子两部分构成 易发现 \[Ans=\frac{\sum_{i=1}^nS_2(n,i)\times i\times i!}{\su ...
- Vue - 如何实现一个双向绑定
JS - 如何实现一个类似 vue 的双向绑定 Github JS 实现代码 先来看一张图: 这张图我做个简要的描述: 首先创建一个实例对象,分别触发了 compile 解析指令 和 observe ...