线性代数计算机图形学的一块基石,本篇文章总结如何在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)-- 转换矩阵的更多相关文章

  1. OpenGL ES2学习笔记(6)-- Line Strip和Line Loop

    Line Strip 上一篇文章画了两条线段,但是用了4个点.如果几条线段首尾相接的话,可以让OpenGL把他们当成Line Strip来画,这样就可以用n+1个点来画n条线段. 代码 import ...

  2. OpenGL ES学习笔记(三)——纹理

    首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <OpenGL ES学习笔记( ...

  3. OpenGL ES 学习笔记 - Overview - 小旋的博客

    移动端图形标准中,目前 OpenGL ES 仍然是比较通用的标准(Vulkan 则是新一代),这里新开一个系列用于记录学习 OpenGL ES 的历程,以便查阅理解. OverView OpenGL ...

  4. OpenGL ES学习笔记(二)——平滑着色、自适应宽高及三维图像生成

    首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <Android学习笔记--O ...

  5. 【GISER && Painter】Chapter00:OpenGL原理学习笔记

    说明:简单了解一下OpenGL的工作原理,初步认识计算机对于图形渲染的底层设计与实现,第一次接触,也没学过C艹,欢迎各位批评指正. 一  什么是OpenGL? OpenGL是一个开放标准(specif ...

  6. OpenGL ES学习笔记(一)——基本用法、绘制流程与着色器编译

    首先声明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. 在Android.iOS等移动平台上 ...

  7. leetcood学习笔记-54-螺旋矩阵

    题目描述: 第一次提交: class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: j,x = 0 ...

  8. 【DirectX 11学习笔记】世界矩阵的理解-运动合成

    最近在看龙书,写一下自己的学习理解,主要是物体运动的合成. 物体于局部坐标系内构建,每个物体拥有自己的局部坐标系以及相应的顶点矩阵A,并通过世界矩阵变换到唯一的世界坐标系. 物体在某时刻发生了位移和旋 ...

  9. OpenCV2学习笔记05:矩阵翻转

    对图像进行翻转或旋转可以使用cv::flip()函数,可以实现将一个二维矩阵沿X轴.Y轴或者同时沿XY轴翻转.函数原型如下: C++: void flip(InputArray src, Output ...

随机推荐

  1. Mvc 分页栏扩展方法

    using System; using System.Collections.Generic; using System.Reflection; using System.Text; using Sy ...

  2. 转:PHP – Best Practises

    原文来自于:http://thisinterestsme.com/php-best-practises/ There are a number of good practises that you s ...

  3. JavaScript自学代码--(四)

    //JavaScript Window - 浏览器对象模型 window.document.getElementById("header"); //等价于 document.get ...

  4. LINUX的VIM建立UTF-8编译的文件

    以前没注意,其实,在有些场合,这个编码还是很重要的. 比如: 我在作一个脚本时,是将一个服务器信息以JSON格式通过requests.put发送到对方服务器. 但对方服务器需要我对JSON格式进行复杂 ...

  5. TF卡的Class4/Class6/Class10

    TF卡全称TransFlash卡,即T-Flash又称MicroSD,随设备微型化的需要,TF卡用途越来越广,速度也越来越快,从最初的Class2早已发展到目前主流的Class10,TF卡体积为15m ...

  6. 如何禁止anonymous用户访问nexus

    nexus在默认情况下是允许anonymous用户浏览仓库,并下载仓库中的jar包的,如果我们搭建的私服是有公网IP的,必须要进行设置,使得anonymous用户的权限被禁用.操作步骤如下: 使用管理 ...

  7. easyui datagrid pagesize设置无效

  8. HDOJ--1698

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. vijosP1388 二叉树数

    vijosP1388 二叉树数 链接:https://vijos.org/p/1388 [思路] Catalan数.根据公式h=C(2n,n)/(n+1)计算.首先化简为 (n+i)/i的积(1< ...

  10. JDBC_demo:java连接mysql过程

    1.任何数据库驱动程序都提供对java.sql.Driver接口的驱动类,mysql-connector-java-5.1.39-bin.jar中Driver: package com.mysql.j ...