opengl 模型載入

2021-09-05 09:30:06 字數 4321 閱讀 6450

乙個非常流行的模型導入庫是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...