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 ...
随机推荐
- Mvc 分页栏扩展方法
using System; using System.Collections.Generic; using System.Reflection; using System.Text; using Sy ...
- 转:PHP – Best Practises
原文来自于:http://thisinterestsme.com/php-best-practises/ There are a number of good practises that you s ...
- JavaScript自学代码--(四)
//JavaScript Window - 浏览器对象模型 window.document.getElementById("header"); //等价于 document.get ...
- LINUX的VIM建立UTF-8编译的文件
以前没注意,其实,在有些场合,这个编码还是很重要的. 比如: 我在作一个脚本时,是将一个服务器信息以JSON格式通过requests.put发送到对方服务器. 但对方服务器需要我对JSON格式进行复杂 ...
- TF卡的Class4/Class6/Class10
TF卡全称TransFlash卡,即T-Flash又称MicroSD,随设备微型化的需要,TF卡用途越来越广,速度也越来越快,从最初的Class2早已发展到目前主流的Class10,TF卡体积为15m ...
- 如何禁止anonymous用户访问nexus
nexus在默认情况下是允许anonymous用户浏览仓库,并下载仓库中的jar包的,如果我们搭建的私服是有公网IP的,必须要进行设置,使得anonymous用户的权限被禁用.操作步骤如下: 使用管理 ...
- easyui datagrid pagesize设置无效
- HDOJ--1698
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- vijosP1388 二叉树数
vijosP1388 二叉树数 链接:https://vijos.org/p/1388 [思路] Catalan数.根据公式h=C(2n,n)/(n+1)计算.首先化简为 (n+i)/i的积(1< ...
- JDBC_demo:java连接mysql过程
1.任何数据库驱动程序都提供对java.sql.Driver接口的驱动类,mysql-connector-java-5.1.39-bin.jar中Driver: package com.mysql.j ...