OpenGL ES2学习笔记(9)-- 转换矩阵
线性代数是计算机图形学的一块基石,本篇文章总结如何在Shader中使用矩阵来移动、缩放和旋转顶点。
代码和效果
把下面的代码复制到OpenGL Console里:
import java.nio.ByteBuffer
import java.nio.ByteOrder
import javax.media.opengl.GL
import org.glob.math.Matrix4f // shaders def vertexShaderCode = """
uniform mat4 u_Matrix;
attribute vec4 a_Position; void main() {
gl_Position = u_Matrix * a_Position;
}
""" def fragmentShaderCode = """
#ifdef GL_ES
precision mediump float;
#endif void main() {
gl_FragColor = vec4(0.8, 0.4, 0.2, 1.0);
}
""" def shaderProgram = glob.compileAndLink(vertexShaderCode, fragmentShaderCode)
def aPositionLocation = shaderProgram.getAttribLocation("a_Position")
shaderProgram.use() def matrix = Matrix4f.translationM(-0.5f, -0.5f, 0.0f)
shaderProgram.getUniform("u_Matrix").setMatrix4fv(matrix.floats) // vertex data def BYTES_PER_FLOAT = 4
def POSITION_ELEMENT_COUNT = 2
def POINT_COUNT = 4 def vertices = [
0.0f, 0.0f,
0.0f, 0.5f,
0.5f, 0.5f,
0.5f, 0.0f,
] as float[] def vertexData = ByteBuffer
.allocateDirect(vertices.length * BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
vertexData.put(vertices)
vertexData.position(0)
gl.glVertexAttribPointer(aPositionLocation, POSITION_ELEMENT_COUNT, gl.GL_FLOAT, false, 0, vertexData)
gl.glEnableVertexAttribArray(aPositionLocation) // draw triangle gl.glClear(gl.GL_COLOR_BUFFER_BIT)
gl.glDrawArrays(gl.GL_TRIANGLE_FAN, 0, POINT_COUNT)
效果:
Uniform
uniform相当于Shader程序的全局常量,也可以看做是Shader程序的参数,由Shader程序的使用者传入。我们在Vertex Shader程序的第一行定义了一个mat4(4x4矩阵)类型的uniform,并且在main()方法里将顶点位置和它相乘,这样就可以对顶点做mat4所代表的转换:
uniform mat4 u_Matrix;
attribute vec4 a_Position; void main() {
gl_Position = u_Matrix * a_Position;
}
Matrix4f类
为了简化矩阵的使用,我封装了一个4x4矩阵类,叫做Matrix4f。下面的代码定义了一个移动矩阵(将x和y坐标分别向负方向移动0.5),然后将它传入Shader程序:
def matrix = Matrix4f.translationM(-0.5f, -0.5f, 0.0f)
shaderProgram.getUniform("u_Matrix").setMatrix4fv(matrix.floats)
ShaderProgram和ShaderUniform相关代码:
public class ShaderProgram extends GLObject {
...
public ShaderUniform getUniform(String name) {
return new ShaderUniform(objectId, name);
}
...
}
public class ShaderUniform extends GLWrapper {
private final int programId;
private final String uniformName;
private int location;
public ShaderUniform(int programId, String uniformName) {
this.programId = programId;
this.uniformName = uniformName;
}
public void setMatrix4fv(float[] v) {
getGL().glUniformMatrix4fv(getLocation(), 1, false, v, 0);
}
private int getLocation() {
if (location == 0) {
location = getGL().glGetUniformLocation(programId, uniformName);
}
return location;
}
}
移动矩阵
上面的代码所达到的移动效果示例图如下:
缩放矩阵
把前面代码里的移动矩阵改成缩放矩阵:
def matrix = Matrix4f.scalingM(1.5f, 1.5f, 0.0f)
效果是矩形变成了原来的1.5倍:
旋转矩阵
最后试试旋转矩阵:
def matrix = Matrix4f.rotationM(30, 0.0f, 0.0f, 1.0f)
效果是矩形沿着z轴逆时针旋转了30度:
OpenGL ES2学习笔记(9)-- 转换矩阵的更多相关文章
- OpenGL ES2学习笔记(6)-- Line Strip和Line Loop
Line Strip 上一篇文章画了两条线段,但是用了4个点.如果几条线段首尾相接的话,可以让OpenGL把他们当成Line Strip来画,这样就可以用n+1个点来画n条线段. 代码 import ...
- OpenGL ES学习笔记(三)——纹理
首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <OpenGL ES学习笔记( ...
- OpenGL ES 学习笔记 - Overview - 小旋的博客
移动端图形标准中,目前 OpenGL ES 仍然是比较通用的标准(Vulkan 则是新一代),这里新开一个系列用于记录学习 OpenGL ES 的历程,以便查阅理解. OverView OpenGL ...
- OpenGL ES学习笔记(二)——平滑着色、自适应宽高及三维图像生成
首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <Android学习笔记--O ...
- 【GISER && Painter】Chapter00:OpenGL原理学习笔记
说明:简单了解一下OpenGL的工作原理,初步认识计算机对于图形渲染的底层设计与实现,第一次接触,也没学过C艹,欢迎各位批评指正. 一 什么是OpenGL? OpenGL是一个开放标准(specif ...
- OpenGL ES学习笔记(一)——基本用法、绘制流程与着色器编译
首先声明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. 在Android.iOS等移动平台上 ...
- leetcood学习笔记-54-螺旋矩阵
题目描述: 第一次提交: class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: j,x = 0 ...
- 【DirectX 11学习笔记】世界矩阵的理解-运动合成
最近在看龙书,写一下自己的学习理解,主要是物体运动的合成. 物体于局部坐标系内构建,每个物体拥有自己的局部坐标系以及相应的顶点矩阵A,并通过世界矩阵变换到唯一的世界坐标系. 物体在某时刻发生了位移和旋 ...
- OpenCV2学习笔记05:矩阵翻转
对图像进行翻转或旋转可以使用cv::flip()函数,可以实现将一个二维矩阵沿X轴.Y轴或者同时沿XY轴翻转.函数原型如下: C++: void flip(InputArray src, Output ...
随机推荐
- Navigation bar 的注意事项
Navigation bar 的注意事项 Bar button item 使用 button 作为 custom view,初始化 isEnabled 为 false,注意顺序 需要设置 bar bu ...
- ListToDataTable
public static DataTable ToDataTable<T>(IEnumerable<T> collection) { var ...
- 如何快速正确的安装 Ruby, Rails 运行环境-b
对于新入门的开发者,如何安装 Ruby, Ruby Gems 和 Rails 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.次安装方法同样适用于产品环境! 系 ...
- 几MB的大图片变成几百KB
使用windows自带的“画图”工具就可以. 1.用“画图”打开图片. 2.点击“重新调整大小” 弹出如下窗口 修改这里的“水平”和“垂直”,如都从100改为30.改完之后,点击确定,最后再“保存”或 ...
- 意犹未尽而来的第一篇Android 逆向
游戏:咕噜王国大冒险 平台:android 目标: 1. 去除乱七八糟提示(本篇目标) 2. 去除google弹窗 3. 破解“all stages” 破文开始: 1. 使用APKIDE反编译:搜索字 ...
- Mybatis 学习
1. Mybatis 中 # 与 $ 符号的区别: a. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号. 如:order by #user_id#,如果传入的值是12,那么解 ...
- BZOJ 1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路
Description 农夫约翰正驾驶一条小艇在牛勒比海上航行. 海上有N(1≤N≤100)个岛屿,用1到N编号.约翰从1号小岛出发,最后到达N号小岛.一 张藏宝图上说,如果他的路程上经过的小岛依次出 ...
- SEO 网站URL优化
很多人都知道URL对SEO的重要之处,但是很多站点却忽略了站点的路径优化.今天本人在这里写几点关于优化路径小篇! 本人结论出关于站点URL在优化中其实也是占为一个相当重要的一个优化!优化站点的URL本 ...
- EMMC 简要介绍
一直想写一篇关于EMMC的文章,但是因为之前弄了很多PPT,所以一直提不起兴趣,索性直接把之前的一个介绍EMMC的PPT贴出来给大家看看,有什么问题可以直接跟帖,我会第一时间进行解答,谢谢
- 最简单的CRC32源码-逐BYTE法
从按BIT计算转到按BYTE计算,要利用异或的一个性质,具体见前面的文章<再探CRC >. 其实方法跟逐BIT法是一样的,我们只是利用异或的性质,把数据分成一BYTE一BYTE来计算,一B ...