張肇同
【摘 要】在機器人仿真軟件開發、三維視景建模等領域,通常需要讀取三維建模,這些模型大都由專業的三維建模軟件生成,具有特定的文件格式。本文基于OpenGL,對此過程中的模型導入與動態觀察部分進行研究。在VS2017環境下,通過OpenGL與Assimp實現三維模型數據文件的可視化,使人們可以獲取到模型特定數據,并可直觀地看到模型,為其余工作奠定基礎。
【關鍵詞】OpenGL;Assimp;模型可視化;動態觀察
0 引言
目前,許多優秀的三維建模軟件如CATIA、UG、Pro/E等,可以方便地建立各種復雜物體模型,但除了軟件所給出的功能外,很難對模型進行控制和操作[1]。OpenGL則更容易實現模型的變換、紋理、交互操作等,但是卻沒有提供CATIA、UG等建模軟件中用于建立復雜三維模型的高級命令,只提供了基本的集合圖元(如點、線、多邊形)的繪制命令[2]。因此,若能將三維建模軟件輸出的模型文件,在OpenGL中進行“加工”,可以更好地解決實際問題。
1 模型讀取與繪制方法
考慮到各平臺文件格式不同,為了增強通用性,我們選擇通過Assimp庫輔助模型讀取工作,這樣可讀入十余種不同格式的主流模型文件,增強了通用性,方便了后續工作。
1.1 Assimp概述
Assimp(Open Asset Import Library)是開源圖形庫,它會將所有的模型數據加載至Assimp的通用數據結構中[3]。當Assimp加載完模型之后,我們就能夠從Assimp的數據結構中提取我們所需的所有數據了。由于Assimp的數據結構保持不變,不論導入的是什么種類的文件格式,它都能夠將模型數據從這些不同文件格式中抽象出來,用同一種方式訪問所需數據。
當使用Assimp導入一個模型的時候,它通常會將整個模型加載進一個場景對象,它會包含導入的模型中的所有數據。Assimp會將場景載入為一系列的節點,每個節點包含了場景對象中所儲存數據的索引,每個節點都可以由任意數量的子節點。
一個網格對象本身包含了渲染所需要的所有相關數據,如頂點、法向量、紋理坐標、面和材質等。一個網格包含了多個面,一個面包含了組成圖元的頂點索引。由于頂點數據和頂點索引是分開的,使用一個索引緩沖來渲染是非常方便的。
1.2 場景繪制方式
現在,我們可以根據場景的結構,讀取場景對象中的數據并繪制模型。為了更加系統的進行場景繪制,我們構建了Model類與Mesh類,分別對應于模型結構與網格結構:
class Model{
public:
Model(char* path){ };
void Draw(Shader shader);
private:
vector
void loadModel( string path);
void processNode(aiNode* node, const aiScene* scene);
Mesh processMesh( aiMesh* mesh, const aiScene* scene);
};
class Mesh{
public:
vector
vector
GLuint VAO;
Mesh(vector
void Draw(Shader shader);
private:
GLuint VBO, EBO;
void setupMesh();
};
1.2.1 模型讀取
首先,讀取給定路徑的模型文件并加載到Scene對象。除了加載文件之外,我們還可以設定一些選項強制性對導入的數據做一些額外的計算或操作。
1.2.2 處理模型節點
我們首先檢查每個節點的網格索引,并索引場景的mMeshes數組來獲取對應的網格。返回的網格將會傳遞到processMesh函數中,它會返回一個Mesh類對象,我們可以將他存儲在meshes數組中。當所有網格都被處理后,我們會遍歷節點的所有子節點,并對子節點中的網格傳遞到processMesh函數中,不斷遞歸下去直到節點中不再存在子節點為止。
1.2.3 處理模型網格
網格傳遞到processMesh函數后,開始對網格進行處理。處理網格的過程主要分為兩步:獲取所有的定點數據;獲取他們的頂點索引。處理后的數據將會存儲在兩個vector當中,我們會使用他們構建一個Mesh類對象,作為processMesh函數的返回值。
為了獲取頂點數據,我們首先定義一個Vertex結構:
struct Vertex
{
glm::vec3 Position;
glm::vec3 Normal;
};
我們將在每個迭代之后將它加到vector
Assimp的接口定義了每個網格都有一個面(Face)數組,一個面包含了多個索引,他們定義了在每個圖元中我們應該繪制哪個頂點,并以什么順序繪制。因此,我們遍歷了所有的面(使用mesh->mNumFaces來獲?。⒋鎯α嗣娴乃饕絭ector
1.2.4 繪制網格
現在,我們有一大列用于渲染的網格數據。將這些數據按照OpenGL渲染的標準步驟,配置正確的緩沖,并通過頂點屬性指針定義頂點著色器的布局等,這些設置都集中在mesh類的成員函數setupMesh()中。
初始化Model類對象,并調用其成員函數Draw(Shader shader),此函數將遍歷類對象的meshes數組,并調用Mesh類的成員函數Draw(Shader shader),根據頂點數組對象所綁定緩沖中的數據,繪制模型。
2 實驗結果
根據前文所述內容,在Visual Studio2017平臺實現了對模型文件的讀取、顯示與三維漫游功能。為了驗證系統顯示三維模型的實際效果,選用了CATIA中STL格式的模型文件,下面為得到的三維模型。
3 結語
對模型文件的讀取與顯示,是對模型一切后續操作的前提和基礎。本文通過對OpenGL與模型文件的研究,以Visual Studio2017作為開發平臺,利用Assimp庫讀取模型文件數據,并通過OpenGL顯示出了模型,今后,可將這種方法應用于機器人仿真軟件開發、三維視景建模等領域。
【參考文獻】
[1]張代聰.基于OpenGL的交互式PLC虛擬仿真系統[D].山東大學,2012.
[2]Richard S.Wright, Jr.OpenGL超級寶典[M].北京:人民郵電出版社,2012.
[3]肖健,魏雄,王仁波.基于 OpenGL 的大型建筑三維場景模擬的實現與意義[J].電子質量,2016(11):88-92.