在了解矩陣的變換之后,我們就可以開始對圖形進行變換。這里使用的變換圖形是之前繪制出來的笑臉箱子。歡迎光臨我的個人網站Orient一起討論學習。這里是我的GitHub,如果您喜歡,不妨點個
star
。?
數學庫包
首先我們需要引入專門為OpenGL量身定做的數學庫——GLM(OpenGL Mathematics)
我們可以從它的網站上下載。
GLM的網站可能需要通過VPN訪問,如果你無法訪問,你可以點擊這里進行下載。如果你使用的是Visual Studio 2017 ,那么在你搭建完開發環境后,你可以直接引入GLM的相關頭文件
我們需要引入以下3個頭文件:
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
變換
uniform
在變換之前,我們需要修改頂點著色器,讓其接收一個 mat4
的 uniform
變量,然后在用矩陣 uniform
乘以位置向量:
#version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(aPos, 1.0f);
TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
}
變換矩陣
首先我們把箱子逆時針旋轉90度(沿著Z軸旋轉),然后縮放0.5倍。我們需要創建變換矩陣:
glm::mat4 transfrom
transform = glm::rotate(transform, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
transform = glm::scal(transform, glm::vec3(0.5, 0.5, 0.5));
可以看到,變換順序和程序編寫順序剛好相反。在程序中,我們先寫出旋轉變換,然后再寫縮放變換
glm::rotate
函數是旋轉函數。GLM希望旋轉的角度是弧度制,所以使用了 glm::radians
對角度進行轉換。同時我們的紋理是在 XY 平面上,所以我們把它繞著Z軸
(0.0, 0.0, 1.0)
進行旋轉。
glm::scal
函數是縮放函數,我們需要將紋理圖像對應的軸縮放 (0.5, 0.5, 0.5)
倍。
把變換矩陣傳遞給著色器
unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
首先用 glGetUniformLocation
函數查詢了 uniform
變量地址。
然后用 glUniformMatrix4fv
函數把矩陣數據發送給著色器。
第一個參數是 uniform
的位置值;
第二個參數告訴OpenGL發送的矩陣個數,這里是1;
第三個參數確定是否進行矩陣置換(交換行和列)。GLM中不需要,所以設置為 GL_FALSE
;
第四個參數是矩陣數據,但GLM并不是把矩陣存儲為OpenGL期望接受的格式,因此這里用 glm::value_ptr
函數變換數據。
以上完成了紋理圖像的縮放旋轉
接下來我們讓紋理圖像隨著時間變換而不斷旋轉
我們只需要將變換矩陣更改成如下形式即可:
glm::mat4 transform;
transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
glm::translate
函數是位移函數,將紋理圖像位移了 (0.5, -0.5, 0.0)
個單位,將紋理圖像位移到了屏幕的右下角。
我們把旋轉函數的第二個參數改成了 glfwGetTime()
,因此紋理圖像旋轉的弧度是隨著運行時間的增加而不斷增加的。
運行效果如下:

本文的代碼可在這里找到,如果對您有所幫助,不妨點個贊。?