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的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...
随机推荐
- Matlab调用C语言函数
Matlab调用C语言函数 如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:double add(double x, double y) { return x + y ;}现在我想要在 ...
- 20155320 2016-2017-3 《Java程序设计》第三周学习总结
20155320 2016-2017-3 <Java程序设计>第三周学习总结 教材学习内容总结 定义类 步骤: 在程序中定义类 使用new关键词新建一个对象 声明参考名称,并将名称参考至新 ...
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
A There is a tree with nn nodes, at which attach a binary 64*6464∗64 matrix M_i (1 \le i \le n)M i ...
- css3新增的content 的用法:
<-----------------------------------------------文字加在内容后面----------------------------------------- ...
- CF 959 E. Mahmoud and Ehab and the xor-MST
E. Mahmoud and Ehab and the xor-MST https://codeforces.com/contest/959/problem/E 分析: 每个点x应该和x ^ lowb ...
- MSP-EZ430U_02板子测试使用
1. 实物如下 2. 先上电,显示驱动没安装 3. 找到驱动的位置,不过实际上安装IAR for msp430之后,驱动就自动的识别了.
- javaweb(三十三)——使用JDBC对数据库进行CRUD
一.statement对象介绍 Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可. Statement对象的exe ...
- Zigbee系列(概览)
Zigbee技术特点 低速率: 数据传输速率只有20~250kb/s, 2.4GHZ提供250kb/s, 915MHz对应40kb/s, 868Mhz对应20kb/s 低功耗:睡眠模式设备使用电池供电 ...
- 车牌,车架号,VIN码毫秒识别技术,汽车后市场的春天到来了
vin码(车架号)识别运用 不仅在制造.销售.保养.保险.车辆评估.交易环节会需要录入汽车的VIN码,在交通事故处理中,作为汽车身份唯一识别码,VIN码是处理事故的执法人员必须要记录的信息之一.随着汽 ...
- 随身Wifi+win7 搭建http代理 域名劫持 抓包 内容篡改实验环境
需求来源: 1.平板或手机是个封闭系统无法给wifi设置代理 2.需要利用filllder进行抓包,内容篡改等实验 拥有硬件资源:PC机器 + 小米随身wifi 方案1: NtBind Dns + N ...