webgl学习笔记四-动画
写在前面
建议先阅读下前面我的三篇文章。
下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘正方形,并且每次重绘时轻微地改变其角度。
demo
- 吊下胃口

- html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="../../lib/cuon-matrix.js"></script>
<body>
<canvas id="canvas" width="200px" height="200px"></canvas>
</body>
</html>
- JavaScript
<script>
// 顶点着色器程序
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform mat4 u_ModelMatrix;\n' +
'void main() {\n' +
' gl_Position = u_ModelMatrix * a_Position;\n' +
'}\n';
// 片元着色器程序
var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'}\n';
// Rotation angle (degrees/second)
var ANGLE_STEP = 45.0;
function main() {
// init gl
var gl = initCanvas();
// Initialize shaders
var shaderProgram = initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE).program;
// Write the positions of vertices to a vertex shader
var n = initVertexBuffers(gl, shaderProgram);
if (n < 0) {
console.log('Failed to set the positions of the vertices');
return;
}
// Specify the color for clearing <canvas>
gl.clearColor(0, 0, 0, 1);
// Get storage location of u_ModelMatrix
var u_ModelMatrix = gl.getUniformLocation(shaderProgram, 'u_ModelMatrix');
if (!u_ModelMatrix) {
console.log('Failed to get the storage location of u_ModelMatrix');
return;
}
// Current rotation angle
var currentAngle = 0.0;
// Model matrix
var modelMatrix = new Matrix4();
// Start drawing
var tick = function () {
currentAngle = animate(currentAngle); // Update the rotation angle
draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix); // Draw the triangle
requestAnimationFrame(tick, canvas); // Request that the browser ?calls tick
};
tick();
}
// init cavas webgl context
function initCanvas() {
//获取canvas元素
var canvas = document.getElementById('canvas');
//获取绘制二维上下文
var gl = canvas.getContext('webgl');
if (!gl) {
console.log("Failed");
return null;
}
return gl;
}
// init shader
function initShader(gl, vshader_source, fshader_source) {
//编译着色器
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vshader_source);
gl.compileShader(vertShader);
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fshader_source);
gl.compileShader(fragShader);
//合并程序
var program = gl.createProgram();
gl.attachShader(program, vertShader);
gl.attachShader(program, fragShader);
gl.linkProgram(program);
gl.useProgram(program);
return {
program: program
}
}
function initVertexBuffers(gl, shaderProgram) {
var vertices = new Float32Array([
-0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5
]);
var n = 4; // The number of vertices
// Create a buffer object
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log('Failed to create the buffer object');
return -1;
}
// Bind the buffer object to target
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// Write date into the buffer object
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// Assign the buffer object to a_Position variable
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return -1;
}
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// Enable the assignment to a_Position variable
gl.enableVertexAttribArray(a_Position);
return n;
}
function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) {
// Set the rotation matrix
modelMatrix.setRotate(currentAngle, 0, 0, 1);
modelMatrix.translate(0.35, 0, 0);
// Pass the rotation matrix to the vertex shader
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
// Clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw the rectangle
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
// Last time that this function was called
var g_last = Date.now();
function animate(angle) {
// Calculate the elapsed time
var now = Date.now();
var elapsed = now - g_last;
g_last = now;
// Update the current rotation angle (adjusted by the elapsed time)
var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
return newAngle %= 360;
}
main();
</script>
webgl学习笔记四-动画的更多相关文章
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记四:回忆ES5 中的类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- ES6学习笔记<四> default、rest、Multi-line Strings
default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...
- muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制
目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...
- python3.4学习笔记(四) 3.x和2.x的区别,持续更新
python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...
- Go语言学习笔记四: 运算符
Go语言学习笔记四: 运算符 这章知识好无聊呀,本来想跨过去,但没准有初学者要学,还是写写吧. 运算符种类 与你预期的一样,Go的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...
随机推荐
- Find the Duplicate Number (寻找重复数字)
对于一个长度为n+1的数组,其中每一个值的取值范围是[1,n],可以证明的是必然存在一个重复数字(抽屉原理),假设仅存在一个重复数字,找到他. 举例:输入:[1,3,4,2,1],输出:1 自己做的时 ...
- 【EXCEL】指定の項目の内容一覧を表示
上記の図の左の部分みたいな長いデータがあって. その中からただほしいのは右側部分ように一部分のみほしい時. 普段はVLOOKUP使用フィルターをかけて探すなどの方法をしようしていますが. ここで.簡単 ...
- 20155323刘威良第一次实验 Java开发环境的熟悉(Linux + IDEA)
20155323刘威良第一次实验 Java开发环境的熟悉(Linux + IDEA) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序 ...
- C#基础之接口
对于接口一直以来都清楚自己理解的不深入,这两天重温以前的代码时更加发现对接口的理解仅仅限于定义而已,得好好学学接口了. 1.接口的特点 接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接 ...
- win10 64位redis的安装和测试
步骤记录: 1.官网没有redis64位的版本,在git开源项目上找到64位的可用版本 https://www.cnblogs.com/tommy-huang/p/6093813.html 这里有下载 ...
- Java的Graphics类进行绘图的方法详解
Graphics类提供基本绘图方法,Graphics2D类提供更强大的绘图能力. Graphics类提供基本的几何图形绘制方法,主要有:画线段.画矩形.画圆.画带颜色的图形.画椭圆.画圆弧.画多边形等 ...
- Loadrunner教程--常用操做流程
1loadrunner压力测试一般使用流程 1.1loadrunner压力测试原理 本质就是在loadrunner上模拟多个用户同时按固定行为访问web站点.其中固定行为在loadrunner中是通过 ...
- Linux内核学习笔记(1)-- 进程管理概述
一.进程与线程 进程是处于执行期的程序,但是并不仅仅局限于一段可执行程序代码.通常,进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个 ...
- 洛谷【P1057】传球游戏
https://www.luogu.org/problemnew/show/P1057 题目描述 在体育课上, 老师带着同学们一起做传球游戏. 游戏规则是这样的: n 个同学站成一个圆圈, 其中的一个 ...
- Scrum立会报告+燃尽图(十月十日总第一次):选题
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2190 Scrum立会master:付佳 一.小组介绍 组长:付佳 组员: ...