OpenGL學習(五)變換

OpenGL學習(六)變換

參考官方文檔https://learnopengl-cn.github.io/

那麼現在有意思的來了。首先關於矩陣運算就不用多做介紹了。直接進入實戰部分。先下載GLM。這個直接百度可以找到:https://github.com/g-truc/glm。(官方文檔中給出的鏈接打不開,只能百度)下載解壓。剛開始我以爲需要用cMake,後面發現不用cMake,只需要在你當前的項目的屬性中添加包含目錄就行了。需要用到的大多數功能都可以在下面3個頭文件中找到。

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

例如:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include<iostream>

int main() {
	glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f);//創建向量
	glm::mat4 trans = glm::mat4(1.0f);//創建一個4*4的單位矩陣
	trans = glm::translate(trans, glm::vec3(1.0f, 1.0f, 0.0f));//傳入一個單位矩陣和一個位移向量,最終生成一個變換矩陣
	vec = trans * vec;//變換矩陣作用在向量上實現向量的位移
	std::cout << vec.x << vec.y << vec.z << std::endl;//1+1,0+1,0+0=>2,1,0
}

輸出結果爲:

210

C:\Users\xhh\Source\Repos\glmTest\x64\Debug\glmTest.exe (進程 58428)已退出,代碼爲 0。
按任意鍵關閉此窗口. . .

下面我們將再我們前面的窗口的基礎上,運用glm的矩陣來操作窗口的繪圖。

頂點着色器shader.vs

#version 330 core
layout(location=0) in vec3 aPos;
layout(location=1) in vec3 aColor;
layout(location=2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;
uniform mat4 transform;

void main(){
	gl_Position=transform*vec4(aPos.x,aPos.y,aPos.z,1.0);
	ourColor=aColor;
	TexCoord=vec2(aTexCoord.x,1.0-aTexCoord.y);
}

主程序中main.cpp

...;
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
...;
int main(){
    ...;
    glm::mat4 trans;
	trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
	trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
    ...;
    while(...){
        ...;
        unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
        ...;
    }
    ...;
}

這樣對我們的圖案旋轉90度並縮小爲原來的二分之一。像這樣

或者再渲染循環中將舉證創建爲:

		glm::mat4 trans = glm::mat4(1.0f);
		trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
		trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
		unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));

最終運行時會發現窗口中的圖片會不斷的旋轉:
在這裏插入圖片描述
練習:

  1. 使用應用在箱子上的最後一個變換,嘗試將其改變爲先旋轉,後位移。看看發生了什麼,試着想想爲什麼會發生這樣的事情

改爲:

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

這時它會繞窗口的中心旋轉而不是箱子的中心旋轉,
在這裏插入圖片描述

爲什麼這兩個操作的順序反過來結果會差別這麼大呢?

這個問題學過量子力學的應該很好理解。其實很簡單的一個問題,前面的代碼是平移在前而旋轉在後,兩個操作平移記爲T,旋轉記爲R,作用到向量X上,TRX,所以實際上是先繞窗口中心旋轉然後再平移到右下角。而現在就是反過來,先平移到右下角然後再繞中心旋轉。旋轉角度是隨時間增大的,所以實際上就變成這樣了。

  1. 嘗試再次調用glDrawElements畫出第二個箱子,使用變換將其擺放在不同的位置。讓這個箱子被擺放在窗口的左上角,並且會不斷的縮放(而不是旋轉)。(sin函數在這裏會很有用,不過注意使用sin函數時應用負值會導致物體被翻轉)

第二個箱子,再渲染循環中接着前面的glDrawElements來,代碼如下:

//第二個箱子
		trans = glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, 0.5f, 0.0f));
		trans = glm::scale(trans, glm::vec3(abs(sin((float)(glfwGetTime()))),abs(sin((float)glfwGetTime())), 1.0f));
		transformLoc = glGetUniformLocation(ourShader.ID, "transform");
		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texture1);
		ourShader.use();
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

很順利的得到了想要的結果了,它會隨時間縮小幅度變化:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章