天天看點

OpenGL——紋理貼圖技術

摘要:本文簡要介紹了OpenGL的紋理貼圖技術及其在MFC中的基本操作步驟。并通過最後的執行個體驗證了紋理貼圖技術在繪制真實感圖形中的必要性。

關鍵詞:OpenGL;MFC;紋理貼圖;計算機圖形學

現實世界中的物體表面往往有各種紋理,是以要繪制逼真的三維物體,除了對物體進行光照處理外,還需要加上紋理貼圖,使物體看起來更真實。OpenGL是SGI公司的一個開放的三維計算機圖形軟體接口,為使用者提供豐富的圖形庫,能快速渲染出高品質的三維彩色圖像。OpenGL程式設計的重點是圖形的生成和如何産生各種真實效果,但是編寫一個優秀的Windows程式,還必須用到使用者界面接口。VC++的MFC模式可以較為完美地實作對OpenGL生成的效果圖的動态互動操作。

紋理貼圖技術簡介

紋理貼圖技術也叫紋理映射技術,它是計算機圖形學中廣泛應用的一項重要技術。傳統的幾何造型隻能表示景物的形狀,無法描述景物表面的微觀細節,而利用紋理圖像來描述景物表面各點處的反射屬性,可以達到模拟景物表面豐富的紋理細節的目的,提高計算機生成圖形的真實性。另一方面,采用紋理映射的方法可以大大地簡化模組化的過程。比如,同是一棟大樓表面,若完全用模組化的方法來構造,則需要畫出大樓的每一扇門、每一扇窗

戶;若采用紋理映射,隻需建立簡單的長方體模型,用拍下的大樓外觀圖檔貼至模型表面即可。相比之下,工作量要小得多。

OpenGL紋理貼圖

紋理映射是将指定圖像的一部分映射到允許進行紋理映射的每個圖段上。這種映射伴随着使用一幅圖像的顔色到某一圖段的(s,t,r)坐标所訓示的位置上并修改該圖段的RGBA顔色。但要特别注意的是,在OpenGL中,紋理映射僅在RGBA模式下說明,在顔色索引模式下,它的使用未作定義。概括地說,使用紋理繪制的一般步驟為:定義紋理貼圖、控制紋理、說明紋理貼圖方式,定義紋理坐标等。

2.1 定義紋理

紋理的定義有兩種:連續法和離散法。連續法把紋理定義為一個二進制函數,函數的定義域就是紋理空間。而離散法則是把紋理定義在一個二維數組中,該數組表示紋理空間中行間隔和列間隔固定的一組網格點上的紋理值。網格點之間的其它點的紋理值可以通過對相鄰網格點上紋理值進行插值來獲得。通過紋理空間與物體空間之間的坐标變換,可以把紋理映射到物體表面。一般來說,離散法是較為常用的紋理定義方法。其實作函數為

glTexlmage2D()。該函數的原型如下:void glTexImage2D(Gl_enum target,GLint level,Gl_enum compo—nents, GLsizei width, GLsizei height, Glint border,Gl_enumformat。Gl_enumtype,const GLvoid pixels);其中:target指定紋理映射,此處必須是GL—TEXT—URE 2D;level指定紋理圖像分辨率的級數,當隻

有一種分辨率時,level=0;Components是選擇用于調整和混合的成分;width和height分别指定紋理圖像的寬和高,必須是2 ,凡為正數;Border為邊界的寬度,必須是0和1;format和type分别指定紋理映射的格式和資料類型;Pixels指定一個指針,指向紋理資料在記憶體中的位置。

2.2 控制紋理

紋理圖像在映射到物體時會産生許多問題。這些問題主要有紋理圖像的紋理怎樣對應到螢幕上的像素、怎樣通過紋理貼圖實作紋理縮放和紋理重複等。其實作函數為glTexParmneter(),該函數的原型(以glTexParmneterf形式為例)為:void glTexPa—rmneterf(GLeRuin target,GLeRuin pname,GLfloat pa—ram),其中target參數為目标紋理,pname參數的取值有以下幾個:GL TEXTURE MIN FILTER、GL,ⅡⅨ TURE—MAG一兀I肛R、GL—TEXrrI yRE— WRAP一GL— TEXTU RE —WRAP— T,而parmn參數的取值要根據pname而定。

2.3 說明紋理貼圖方式

OpenGL用于紋理貼圖方式的函數為glTex~v(),該函數的原型(以glTexEnvf形式為例)為:voidglTexEnv(Gl_enum target,Gl_enum pname,GLfloat pa—ram)其中target參數必須為GL—TEXTURE —ENV,pname參數必須為GL—TEXTURE —ENV—MODE,而參數parmn為GL—MODULATE 、GL—DECAL或GL—BLEND。

2.4 定義紋理坐标

紋理坐标控制紋理圖像中的像素怎樣映射到物體。紋理坐标可以是1、2、3、4維的,通常用齊次坐标來表示,即(5,t,r,q)。OpenGL定義紋理坐标的函數為 xCoord()。該函數共有32種不同的形式。例如:glTexCoord4f(O.Of,0.Of,0.Of,0.Of)。

3 基于MFC的OpenGL中的紋理貼圖利用VC++的MFC AppWizard(exe)建立一個新項目OpenglTexture,選擇基于單文檔界面的應用,其它選項都使用預設值。在OpenglTextureView.h頭檔案中,添加各成員變量和成員函數。

for(i=0;i<128;i++)

{

    for(j=0;j<64;j++)

    {

    c=(((i&Ox08)==0) ((j ))==0)*255;

    g=(4*i)%255;

    b:(j*i)%255;

    imag~Ei兒j][0]=(GIaxbyte)b;

    image[i兒J兒1]=(GIaxbyte)g;

    image~i][j][2]=(GIaibyte)c;

    }

}

glPixelStorei(GL—UNPACK— ALIGNMENT,2);

glTexImage2D(GL—TEXTURE一2D,0,3,64,64 ,0,GL— RGB,GL—UNSIGNED— BYTE,image);

//定義紋理

glTexParameteri(GL— TEXTURE一2D,GL— TEXTURE — W RAP— S,

GL— CLAMP);

//控制紋理

glTexParameteri(GL—

TEXTURE一2D,GL— TE XTURE — WRAP—T,GL— CLAMP);

glTexParameteri(GL—TEXTURE一2D,GL—TEXTURE—MAG—FIL—E R,GL— NEAREST);

glTexParameteri(GL— TEXTURE 一2D,GL— TEXTURE — MIN— FIL—TE R,GL— NE AREST);

rSTexEnvf(GL—TEXTURE —ENV,GL—TEXTURE —ENV—MODE,GL— DECAL);//說明紋理貼圖方式

glEnable(GL— TEXTURE 一2D);//啟動紋理貼圖

glShadeModel(GL—SMOOTH);

glBegin(GL— QUADS);//定義紋理坐标和物體幾何坐标

glTexCoord2f(1.of,1.Of);glVertex3f(1.Of,1.Of,0.Of);

glTexCoord2f(1.of,0.Of);glVertex3f(1.Of,一1.Of,0.Of);

glTexCoord2f(0.of,0.Of);glVertex3f(一1.Of,一1.Of,0.Of);

glTexCoord2f(0.Of.I.Of);glVertex3f(一I.Of,I.Of,0.Of);

glEnd();

glDisabh(GL—TEXTURE 一2D);//關閉紋理貼圖

結束語

利用OpenGL強大的圖形功能,可以輕松地實作逼真的貼圖模型。在此基礎上,運用VC++的MFC應用程式模式,可對OpenGL産生的模型進行更進一步的控制和變化。同時提供給使用者一個友好的操作環境,這在當今的時尚程式設計中是不可或缺的。

參考文獻:

[1] 向世明.OpenGL程式設計與執行個體[M].北京:電子工業出版社,1999.

[2] Hearn D,Baker M P.計算機圖形學[M].北京:電子工業出版社,1998.

[3] Kruglinski D J.Visual C++技術内幕(第四版)[M].北京:清華大學出版社,2001.

[4] 李穎,朱伯立.OpenGL技術應用執行個體精粹[M].北京:國防工業出版社,2001.

[5] Toudeft Abd~ e,GaUinari Patrick.Neural and Ia ve o0n一terns[J].IEE Proceedings:Control theory and Applications,1997,144(6):531—536