webgl学习笔记三-平移旋转缩放
写在前面
建议先阅读下前面我的两篇文章。
平移
1、关键点说明
顶点着色器需要加上 uniform vec4 u_Translation, 存储平移的坐标矢量。
顶点坐标位置 : gl_Position = a_Position + u_Translation
平移API : gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);
2、demo
- html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<canvas id="canvas" width="200px" height="200px"></canvas>
</body>
</html>
- JavaScript
<script>
function main() {
//顶点着色器程序
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform vec4 u_Translation;\n' +
'void main() {\n' +
' gl_Position = a_Position + u_Translation;\n' +
'}\n';
//片元着色器
var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'}\n';
//获取canvas元素
var canvas = document.getElementById('canvas');
//获取绘制二维上下文
var gl = canvas.getContext('webgl');
if (!gl) {
console.log("Failed");
return;
}
//编译着色器
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 shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
//获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return;
}
var n = initBuffers(gl, shaderProgram);
if (n < 0) {
console.log('Failed to set the positions');
return;
}
// 清除指定<画布>的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空 <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, n);
}
function opt(gl, shaderProgram) {
var Tx = 0.5, Ty = 0.5, Tz = 0.0;
var u_Translation = gl.getUniformLocation(shaderProgram, 'u_Translation');
if (!u_Translation) {
console.log('Failed to get the storage location of u_Translation');
return;
}
gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);
}
function initBuffers(gl, shaderProgram) {
var vertices = new Float32Array([
0, 0.5, -0.5, -0.5, 0.5, -0.5
]);
var n = 3;//点的个数
//创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log("Failed to create the butter object");
return -1;
}
//将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
//向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
//获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
//连接a_Position变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);
return n;
}
main();
</script>
旋转
1、关键点说明
- 坐标P(x,y,z) , 绕Z轴旋转β角度变成 p1(x1, y1, z1)
则根据数据三角函数公式可得:
x1 = xcosβ - ysinβ
y1 = xsinβ + ycosβ
z1=z
顶点着色器需要加上 uniform float u_CosB, u_SinB 存储旋转角度。
顶点坐标位置 :
- gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB
- gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB
旋转API :
- gl.uniform1f(u_CosB, cosB)
- gl.uniform1f(u_sinB, sinB);
2、demo
- JavaScript
<script>
function main() {
//顶点着色器程序
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform float u_CosB, u_SinB;\n' +
'void main() {\n' +
' gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;\n' +
' gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;\n' +
' gl_Position.z = a_Position.z;\n' +
' gl_Position.w = 1.0;\n' +
'}\n';
//片元着色器程序
var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'}\n';
var Tx = 0.5, Ty = 0.5, Tz = 0.0;
//获取canvas元素
var canvas = document.getElementById('canvas');
//获取绘制二维上下文
var gl = canvas.getContext('webgl');
if (!gl) {
console.log("Failed");
return;
}
//编译着色器
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 shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
//获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return;
}
var n = initBuffers(gl, shaderProgram);
if (n < 0) {
console.log('Failed to set the positions');
return;
}
opt(gl, shaderProgram);
// 清除指定<画布>的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空 <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, n);
}
function opt(gl, program) {
// 旋转角度
var ANGLE = 90.0;
var radian = Math.PI * ANGLE / 180.0;
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
var u_CosB = gl.getUniformLocation(program, 'u_CosB');
var u_sinB = gl.getUniformLocation(program, 'u_SinB');
gl.uniform1f(u_CosB, cosB);
gl.uniform1f(u_sinB, sinB);
}
function initBuffers(gl, shaderProgram) {
var vertices = new Float32Array([
0, 0.5, -0.5, -0.5, 0.5, -0.5
]);
var n = 3;//点的个数
//创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log("Failed to create the butter object");
return -1;
}
//将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
//向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
//获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
//连接a_Position变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);
return n;
}
main();
</script>
缩放
1、关键点说明
顶点着色器需要加上 uniform mat4 u_xformMatrix, 存储缩放因子的坐标矢量。
顶点坐标位置 : gl_Position = u_xformMatrix * a_Position
缩放API : gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
- u_xformMatrix : 缩放因子
- xformMatrix : 原始坐标
2、demo
- JavaScript
<script>
function main() {
//顶点着色器程序
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform mat4 u_xformMatrix;\n' +
'void main() {\n' +
' gl_Position = u_xformMatrix * a_Position;\n' +
'}\n';
//片元着色器程序
var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'}\n';
var Tx = 0.5, Ty = 0.5, Tz = 0.0;
//获取canvas元素
var canvas = document.getElementById('canvas');
//获取绘制二维上下文
var gl = canvas.getContext('webgl');
if (!gl) {
console.log("Failed");
return;
}
//编译着色器
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 shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
//获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return;
}
var n = initBuffers(gl, shaderProgram);
if (n < 0) {
console.log('Failed to set the positions');
return;
}
opt(gl, shaderProgram);
// 清除指定<画布>的颜色
gl.clearColor(0, 0, 0, 1);
// 清空 <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw the rectangle
gl.drawArrays(gl.TRIANGLES, 0, n);
}
// 缩放
function opt(gl, program) {
// 缩放因子
var Sx = 1.0, Sy = 1.5, Sz = 1.0;
var xformMatrix = new Float32Array([
Sx, 0.0, 0.0, 0.0,
0.0, Sy, 0.0, 0.0,
0.0, 0.0, Sz, 0.0,
0.0, 0.0, 0.0, 1.0
]);
var u_xformMatrix = gl.getUniformLocation(program, 'u_xformMatrix');
gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
}
// 构建缓冲区
function initBuffers(gl, shaderProgram) {
var vertices = new Float32Array([
0, 0.5, -0.5, -0.5, 0.5, -0.5
]);
var n = 3;//点的个数
//创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log("Failed to create the butter object");
return -1;
}
//将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
//向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
//获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
//连接a_Position变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);
return n;
}
// 主方法调用
main();
</script>
写在最后
webgl学习笔记三-平移旋转缩放的更多相关文章
- WebGL学习笔记三
在上一章中主要说明了通过矩阵来实现平面图形的平移.旋转.缩放,到最后完全可以用4*4矩阵实现所有的动作,在本章就是第四章主要是对矩阵进行了封装,其WebGL的流程和上一章大部分大部分相同,定义可以在w ...
- webgl学习笔记五-纹理
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...
- webgl学习笔记四-动画
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...
- osg矩阵变换节点-----平移旋转缩放
osg矩阵变换节点-----平移旋转缩放 转自:http://www.cnblogs.com/ylwn817/articles/1973396.html 平移旋转缩放这个三个是osg矩阵操作中,最常见 ...
- WebGL学习笔记二——绘制基本图元
webGL的基本图元点.线.三角形 gl.drawArrays(mode, first,count) first,代表从第几个点开始绘制即顶点的起始位置 count,代表绘制的点的数量. mode,代 ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- osg中使用MatrixTransform来实现模型的平移/旋转/缩放
osg中使用MatrixTransform来实现模型的平移/旋转/缩放 转自:http://www.cnblogs.com/kekec/archive/2011/08/15/2139893.html# ...
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
- JSP学习笔记(三):简单的Tomcat Web服务器
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
随机推荐
- leetcode记录-两数之和
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...
- PostgreSQL的hstore初步学习
安装hstore: 进入源代码的 /contrib/hstore 目录,然后执行gmake 和 gmake install: [root@pg200 hstore]# gmake gcc -O2 -W ...
- Swift - 重写导航栏返回按钮
// 重写导航栏返回按钮方法 func configBackBtn() -> Void { // 返回按钮 let backButton = UIButton(type: .custom) // ...
- day 11 名片管理系统
1 思路 #名片1 名片2 {"name":"alex","age":18,"QQ":12123} {"nam ...
- LVS入门篇(三)之LVS的工作模式和调度算法
1.NAT模型 (1)原理图: ①.客户端(200.10.10.1)将请求发往前端的负载均衡器(114.100.80.10),请求报文源地址是CIP(客户端IP),后面统称为CIP),目标地址为VIP ...
- 简单读取 properties文件
看了网上很多读取的方法,都太过复杂,直接使用下面的方法就可以简单读取 properties文件了 ide使用idea 测试读取成功 import java.util.ResourceBundle; p ...
- Spring学习(十三)-----Spring 表达式语言(Spring EL)
本篇讲述了Spring Expression Language —— 即Spring3中功能丰富强大的表达式语言,简称SpEL.SpEL是类似于OGNL和JSF EL的表达式语言,能够在运行时构建复杂 ...
- 关于Python的装饰器(2)
Python中被装饰器修饰的函数,解析后会生成一个参数是被修饰函数的装饰器函数对象,可以调用,可以接受传参(如果被修饰的函数定义了参数),实际调用的时候,尽管代码里值写了被修饰的函数,被调用的却是最终 ...
- 用Micro:bit做剪刀、石头、布游戏
剪刀.石头.布游戏大家都玩过,今天我们用Micro:bit建一个剪刀.石头.布游戏! 第一步,起始 当你摇动它时,我们希望the micro:bit选择剪刀.石头.布.尝试创建一个on shake b ...
- JUC——ThreadFactory线程工厂类(四)
ThreadFactory线程工厂类 在默认情况下如果要想创建一个线程类对象,大部分情况的选择是:直接通过子类为父类进行实例化,利用Runnable子类为Runnable接口实例化. 或者直接调用La ...