当前位置: 代码迷 >> 综合 >> OpenGL矩阵运算——GLM库的使用(OpenGL Mathematics(GLM) - 几何数学库)
  详细解决方案

OpenGL矩阵运算——GLM库的使用(OpenGL Mathematics(GLM) - 几何数学库)

热度:95   发布时间:2024-02-04 17:11:42.0

转载:https://blog.csdn.net/qq_42537915/article/details/104146135?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

转载:https://blog.csdn.net/Wonz5130/article/details/83116009?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param

 

OpenGl中在进行图形变换的时候需要使用几何数学库,这里使用第三方数学库GLM。

github地址:https://github.com/g-truc/glm

 

OpenGL Mathematics (GLM) 是基于OpenGL着色语言(GLSL)规范的图形软件的头文件C ++数学库。

GLM提供的类和函数使用与GLSL相同的命名约定和功能设计和实现,因此任何知道GLSL的人都可以在C ++中使用GLM。

这个项目不限于GLSL的功能。基于GLSL扩展约定的扩展系统提供扩展能力:矩阵变换,四元数,数据打包,随机数,噪声等等。

这个库与OpenGL完美地工作,但它也确保与其他第三方库和SDK的互操作性。它是软件渲染(光线追踪/光栅化),图像处理,物理模拟和任何需要简单方便的数学库的开发上下文的良好候选。

GLM是用C ++ 98编写的,但是当编译器支持时可以利用C ++ 11。它是一个没有依赖的平台独立库,它正式支持以下编译器:

    ● 苹果Clang 6.0及更高版本
● GCC 4.7及以上
● 英特尔C ++ Composer XE 2013及更高版本
● LLVM 3.4及更高版本
● Visual C ++ 2013及更高版本
● CUDA 7.0及更高版本(实验版)
● 任何C ++ 11编译器

 

GLM库简介

OpenGL没有内建矩阵运算方法,常用的第三方库为GLM。GLM是OpenGL Mathematics的缩写。作为一个header only库,GLM只要包括了相应的头文件就可以使用它提供的类和函数。GLM是C++语言编写的,故不适用于C语言工程。

头文件

  • GLM对于矩阵数据类型的定义位于glm/glm.hpp头文件中。
  • 生成变换矩阵的函数位于glm/gtc/matrix_transform.hpp头文件中。
  • 生成投影矩阵的函数位于glm/ext/matrix_clip_space.hpp头文件中。
  • 将数组转换成矩阵的函数位于头文件glm/gtc/type_ptr.hpp中。
  • glm::value_ptr函数位于头文件glm/gtc/type_ptr.hpp中

GLM常用数据类型

  • vec2 二维向量
  • vec3 三维向量
  • vec4 四维向量
  • mat2 二阶矩阵
  • mat3 三阶矩阵
  • mat4 四阶矩阵

GLM常用函数

  • glm::radians()
    角度制转弧度制,可应用于glm::rotate()中。
  • glm::translate()
    返回一个平移矩阵,第一个参数是目标矩阵,第二个参数是平移的方向向量。
  • glm::rotate()
    返回一个将点绕某个轴逆时针旋转一定弧度的旋转矩阵,第一个参数是弧度,第二个参数是旋转轴。
  • glm::scale()
    返回一个缩放矩阵,第一个参数是目标矩阵,第二个参数是在各坐标轴上的缩放系数。
  • glm::ortho(float left, float right, float bottom, float top, float zNear, float zFar);
    正交投影矩阵。前四个参数分别是视口的左、右、上、下坐标。第五和第六个参数则定义了近平面和远平面的距离。
  • glm::perspective(float fovy, float aspect, float zNear, float zFar);
    透视投影矩阵。第一个参数为视锥上下面之间的夹角,第二个参数为视口宽高比,第三、四个参数分别为近平面和远平面的深度。
  • glm::value_ptr()
    传入一个矩阵,返回一个数组。

GLM矩阵的默认构造

GLM库从0.9.9版本起,默认会将矩阵类型初始化为一个零矩阵(所有元素均为0),而不是单位矩阵。如果使用0.9.9及以上的版本,需要在声明矩阵时传入参数1,例如glm::mat4 mat(1.0f)。

向着色器中输入矩阵

glm::value_ptr函数

GLM的glm::value_ptr()函数可以返回一个数组,其中按列优先储存了矩阵的元素。例如:

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <typeinfo>int main() {glm::mat4 trans(1.0f);trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0, 1, 0));//0  0  1  0//0  1  0  0//-1 0  0  0//0  0  0  1float *p = glm::value_ptr(trans);std::cout << typeid(p).name() << std::endl;for (int i=0; i < 16; i++) {std::cout << *p << ' ';p++;}std::cout << std::endl;return 0;
}
//输出结果:
//float *
//0 0 -1 0 0 1 0 0 1 0 0 0 0 0 0 1

我们可以用glm::value_ptr()搭配glUniformMatrix4fv函数向着色器传入矩阵:

glUniformMatrix4fv(glGetUniformLocation(ID, "name"), 1, GL_FALSE, glm::value_ptr(trans));
//ID为着色器程序的位置,glCreateProgram()的返回值
//name为自己在着色器中定义的uniform,如:uniform mat4 transform

glUniformMatrix4fv函数

void glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)

  • location: uniform的位置。
  • count: 需要加载数据的数组元素的数量或者需要修改的矩阵的数量。
  • transpose: 列优先矩阵传false,行优先矩阵传true。
  • value: 指向由count个元素的数组的指针。

GLSL中的向量*向量运算

需要注意的是,在GLSL中,vec4 * vec4是逐元乘法(component wise),例如:

vec4 a = vec4(1.0, 2.0, 3.0, 4.0);
vec4 b = vec4(0.1, 0.2, 0.3, 0.4);
vec4 c = a * b;
//c: vec4(0.1, 0.4, 0.9, 1.6)