乙個非常流行的模型導入庫是assimp,它是open asset import library(開放的資產導入庫)的縮寫
** assimp資料結構的(簡化)模型如下 **
opengl中定義乙個頂點,
每個頂點包含乙個位置向量、乙個法向量和乙個紋理座標向量
struct vertex
;
紋理資料,儲存了紋理的id以及它的型別,比如是漫反射貼圖或者是鏡面光貼圖
struct texture
;
網格類的結構
class mesh
;
void
setupmesh()
設定乙個命名標準:每個漫反射紋理被命名為texture_diffusen,每個鏡面光紋理應該被命名為texture_specularn,其中n的範圍是1到紋理取樣器最大允許的數字。比如說我們對某乙個網格有3個漫反射紋理,2個鏡面光紋理,它們的紋理取樣器應該之後會被呼叫:
uniform sampler2d texture_diffuse1;
uniform sampler2d texture_diffuse2;
uniform sampler2d texture_diffuse3;
uniform sampler2d texture_specular1;
uniform sampler2d texture_specular2;
渲染**
void
draw
(shader shader)
glactivetexture
(gl_texture0)
;// 繪製網格
glbindvertexarray
(vao)
;gldrawelements
(gl_********s, indices.
size()
, gl_unsigned_int,0)
;glbindvertexarray(0);}
** model類 **
class model
void
draw
(shader shader)
;
private:
/* 模型資料 */
vector meshes;
string directory;
/* 函式 */
void
loadmodel
(string path)
;void
processnode
(ainode *node,
const aiscene *scene)
; mesh processmesh
(aimesh *mesh,
const aiscene *scene)
; vector
loadmaterialtextures
(aimaterial *mat, aitexturetype type,
string typename);}
;
** draw函式 **
void
draw
(shader shader)
標頭檔案
#include
#include
#include
載入
// 接下來對它的子節點重複這一過程
for(
unsigned
int i =
0; i < node->mnumchildren; i++
)}
mesh processmesh
(aimesh *mesh,
const aiscene *scene)
// 處理索引..
.// 處理材質
if(mesh->mmaterialindex >=0)
return
mesh
(vertices, indices, textures)
;}
處理網格的過程主要有三部分:獲取所有的頂點資料,獲取它們的網格索引,並獲取相關的材質資料。處理後的資料將會儲存在三個vector當中,我們會利用它們構建乙個mesh物件,並返回它到函式的呼叫者那裡
頂點的位置是這樣處理的:
glm::vec3 vector;
vector.x = mesh->mvertices[i].x;
vector.y = mesh->mvertices[i].y;
vector.z = mesh->mvertices[i].z;
vertex.position = vector;
處理法線的步驟也是差不多的:
vector.x = mesh->mnormals[i].x;
vector.y = mesh->mnormals[i].y;
vector.z = mesh->mnormals[i].z;
vertex.normal = vector;
紋理座標的處理也大體相似,但assimp允許乙個模型在乙個頂點上有最多8個不同的紋理座標,我們不會用到那麼多,我們只關心第一組紋理座標。我們同樣也想檢查網格是否真的包含了紋理座標(可能並不會一直如此)
if(mesh->mtexturecoords[0]) // 網格是否有紋理座標?
else
vertex.texcoords = glm::vec2(0.0f, 0.0f);
assimp的介面定義了每個網格都有乙個面(face)陣列,每個面代表了乙個圖元,在我們的例子中(由於使用了aiprocess_triangulate選項)它總是三角形。乙個面包含了多個索引,它們定義了在每個圖元中,我們應該繪製哪個頂點,並以什麼順序繪製,所以如果我們遍歷了所有的面,並儲存了面的索引到indices這個vector中就可以了。
for(unsigned int i = 0; i < mesh->mnumfaces; i++)
if
(mesh->mmaterialindex >=0)
vector
loadmaterialtextures
(aimaterial *mat, aitexturetype type, string typename)
return textures;
}
紋理載入優化
struct texture
;vector textures_loaded;
vector
loadmaterialtextures
(aimaterial *mat, aitexturetype type, string typename)}if
(!skip)
}return textures;
}
載入OpenGL函式
載入opengl函式是建立opengl上下文後的一項重要的初始化工作,需要使用平台特定的函式查詢函式指標,且不同的版本有不同的語義。我們使用 wglgetprocaddress 來查詢函式指標,該函式接收乙個ascii字串的函式名作為引數,可以查詢 opengl 函式 和 平台特定的wgl函式,這個...
OpenGL 光照模型
材質有三種,也就是對光有三種反射 材質被分為了三個屬性,也分別用三個引數來刻畫 對於乙個頂點,有四個向量來刻畫其光照 計算的時候也分為鏡面 漫和環境三類,之後再疊加起來即得到光照下的顏色 向量nlvr 求解顏色 鏡面反射 is rs max v r a,0 ls 環境反射 ia ra la於是 i ...
OpenGL環境下模型檔案的載入(3DS OBJ)
3ds 乙個讀取3ds檔案的類cload3ds 乙個讀取3ds檔案的類cload3ds obj obj模型檔案的結構 匯入與渲染 obj模型檔案的結構 匯入與渲染 雖然原始碼裡使用的load3ds和loadobj均非出自以上鏈結,但大體都是差不多,因此還是有很大的借鑑意義,感謝原作者的無私奉獻。3d...