变换

建议在组合矩阵时,先进行缩放操作,然后是旋转,最后才是位移,否则它们会(消极地)互相影响。

模型平移后,模型还是以原点进行旋转。而模型中心已经不在原点上,导致旋转异常。         

这时因为: 
在物体刚刚放入世界坐标系的时候使用的是本地坐标,也就是本地和世界坐标系的原点和坐标轴都是重合的,此时所有物体都“把世界坐标系当做自己的本地坐标系”。 
而经过了坐标变换之后: 
缩放变换不改变坐标轴的走向,也不改变原点的位置,所以两个坐标系仍然重合。 
旋转变换改变坐标轴的走向,但不改变原点的位置,所以两个坐标系坐标轴不再处于相同走向。 
平移变换不改变坐标轴走向,但改变原点位置,两个坐标系原点不再重合。

一、在顶点着色器中声明一个uniform 变量

uniform mat4 transform;

glPosition = transform*vec4(aPos,1.0f);

二、创建变换矩阵

1 glm::mat4 trans;
2 trans = glm::rotate(trans,glm:radians(90.0f),glm::vec3(0.0,0.0,1.0));
3 trans = glm::scale(trans,glm::vec3(0.5,0.5,0.5));

首先,我们把箱子在每个轴上都缩小0.5倍,然后沿z轴旋转90度。GLM希望它的角度是弧度制的(Radian),所以我们使用glm::radians将角度转化为弧度。

三、把矩阵发送给着色器,着色器会变换传入的顶点坐标

1 unsigned int transformLoc = glGetUniformLocation(ourShader.ID,"transform");//查询uniform变量的地址
2 glUniformMatrix4f(transformLoc,1,GL_FALSE,glm::value_ptr(trans));

然后用有Matrix4fv后缀的glUniform函数把矩阵数据trans发送给着色器.

第一个参数:uniform变量(transform)的位置值

第二个参数:告诉openGL我们将要发送多少个矩阵

第三个参数:询问我们是否需要对矩阵进行转置

最后一个参数:真正的矩阵数据,GLM并不是把它们的矩阵储存为OpenGL所希望接受的那种,因此我们要先用GLM的自带的函数value_ptr来变换这些数据。

若让物体随着时间推移旋转:

1 glm::mat4 trans;
2 trans = glm::translate(trans,glm::vec3(0.5f,-0.5f,0.5f));
3 trans = glm::rotate(trans,(float)glfwGetTime(),glm::vec3(0.0f,0.0f,1.0f));

在这里我们先把箱子围绕原点(0, 0, 1)旋转,之后,我们把旋转过后的箱子位移到屏幕的右下角。记住,实际的变换顺序应该与阅读顺序相反:尽管在代码中我们先位移再旋转,实际的变换却是先应用旋转再是位移的。

原文地址:https://www.cnblogs.com/keguniang/p/9923718.html