要完成圖形學課程的大作業,用傳統的手動寫點,線,麵等其他資料的方式太繁瑣,工程量太大,且效果不好。故而使用3dsmax建模,然後匯出obj模型,讀取模型進行繪製即可。
要讀取obj模型,首先要知道obj模型的內容,即點,面,法線,紋理座標等。
用記事本開啟obj檔案,即可檢視obj的內容。
其中#為注釋部分
先讀取乙個最簡單的obj模型
v 就是點的位置資訊(3f x,y,z)
vn 就是點的法線資訊(3f x,y,z)
vt 是點的紋理座標(3f u,v,w),一般只用uv座標即可
f 即面的資訊
面最基本的形式就是 f 1/1/1 2/2/2 3/3/3,其中每個分塊就是乙個點的資訊(三角麵片構成面,所以是三個分塊),每個點的資訊都由 頂點位置索引/紋理座標索引/法線索引構成(索引從1開始,用c++讀取的時候要注意 -1)。
面的資訊有多種形式,這裡只討論這一種,其他形式各位自己去實現就ok
下面就是讀取obj檔案了,先進行準備工作
struct float3 //點的位置資訊和法線資訊的資料型別
;struct float2 //點的紋理座標資料型別
;struct face //面資訊
;unsigned char*loadfilecontent(const char*path, int &filesize) //該函式來自於萌谷教程
//讀取檔案,返回檔案內容,把檔案大小賦值給filesize
fclose(pfile);
} return filecontent;
}
能夠讀取檔案內容之後,再進行模型類的定義
初步定義模型類(針對乙個obj只有乙個模型而言)
class objmodel
;
下面進行模型的讀取,建構函式直接讀取obj檔案,考慮到提前不知道位置等資訊的數量,所以採用vector庫進行儲存資料
objmodel::objmodel(const char * objfilename)
stringstream ssfilecontent((char*)filecontent); //流讀取檔案內容
string temp; //接受無關資訊
char szoneline[256]; //讀取一行的資料
while (!ssfilecontent.eof())
if (szoneline[1] == 'n') //法線資訊
else //點的位置資訊
}else if (szoneline[0] == 'f') //面資訊
mface.push_back(tempface);
}} //end 非0行
} //end while
delete filecontent;
}
新增紋理,自己寫這個建立紋理的函式即可,這裡不展開論述
void objmodel::settexturefrombmp(const char * texfilename)
下面就是繪製該模型,使用三角麵片來繪製,需要注意的就是索引資訊要-1(本人開始寫的時候沒有注意到這一點,直接導致vector越界)
void objmodel::objdraw()
glend();
}
效果如圖
這只是最簡單的模型讀取,沒有考慮含有材質庫,以及多個圖元的obj模型。
後續在此基礎上還要進行修改即擴充
OpenGL讀取Obj模型檔案
想要順利讀取obj模型檔案,先要了解這種檔案的格式,obj檔案格式是非常簡單的。這種檔案以純文字的形式儲存了模型的頂點 法線和紋理座標和材質使用資訊。obj檔案的每一行,都有極其相似的格式。在obj檔案中,每行的格式如下 字首 引數1 引數2 引數3 其中,字首標識了這一行所儲存的資訊型別。引數則是...
opengl讀取OBJ模型檔案
要順利讀取 obj模型檔案,先要了解obj檔案的格式。obj檔案格式是非常簡單的,它以純文字的形式儲存了模型的頂點 法線和紋理座標和材質使用資訊。obj檔案的每行的格式如下 字首引數1引數 2引數3 其中,字首標識了這一行所儲存的資訊型別。引數則是具體的資料。obj檔案常見的的字首有 v表示本行指定...
opengl讀取obj模型3
第三版本相較於前兩個版本,新增了對 f 1 1 型別的支援 面 由點座標和法向量組成 以及對mtl檔案的讀取。準備工作,準備乙個結構體來儲存材質資訊,然後由vector儲存即可 struct mmaterial ka,kd,ks即相應的環境光,漫反射及鏡面反射的引數,mtexturename儲存著該...