亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Win32 OpenGL編程(16) 紋理貼圖

系統(tǒng) 2373 0

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

討論新聞組及文件

好久好久沒有繼續(xù)OpenGL了...中間發(fā)生了太多事情,比如Objective C及Cocoa的學(xué)習(xí), 粗略看了一些游戲引擎的源代碼,Google離開了,一個(gè)公司可以很有骨氣的說走就走,暫時(shí)沒有辦法離開的人,該繼續(xù)的還是得繼續(xù),現(xiàn)在回過神來,還是留 點(diǎn)時(shí)間來學(xué)OpenGL吧,不過作為工作需要,我以后可能會(huì)常常附帶OpenGL ES的信息,甚至,不是OpenGL ES可用的我就一筆帶過了,畢竟,我的工作現(xiàn)在是在IPhone平臺(tái)......


概念

上一節(jié)講過了在OpenGL中位圖的顯示,但是,那都是簡單的將圖片貼出來,放在平面上的效果,這一節(jié)解釋一下怎么在3D物體上應(yīng)用位圖,這個(gè)過程被稱作 紋理貼圖(Texture Mapping),想想以前的三棱錐吧,最好最好的時(shí)候,我們也僅僅是實(shí)現(xiàn)了漸變顏色或者是光照,那樣太單調(diào)了。既然是金字塔型,我們自然希望它想真的金 字塔一樣,有著巖石的外表,就像經(jīng)過了歲月的滄桑。
實(shí)際中,在制作游戲的時(shí)候中,要想某個(gè)物體想現(xiàn)實(shí)世界的物體,基本上不太可能完全通過程序的頂點(diǎn)色去實(shí)現(xiàn),那樣太復(fù)雜了,現(xiàn)實(shí)世界應(yīng)該怎樣描繪,美術(shù)比 程序員更加清楚,更重要的是,美術(shù)不僅知道怎么描述這個(gè)世界,還比程序員更加知道怎么從現(xiàn)實(shí)中獲取素材,及處理素材,程序描繪世界最好的辦法應(yīng)該是很好的 將美術(shù)制作的圖片資源恰當(dāng)?shù)娘@示出來,而不是真的編寫程序去描繪每個(gè)頂點(diǎn)的顏色,我們是程序員,不是上帝.........

概念上,紋理貼圖的英文更加能夠反映其實(shí)質(zhì),Texture Mapping,注意Mapping一詞,C++中的map沒有少用吧,這里是映射的意思,紋理貼圖本質(zhì)就是一個(gè)位圖(即紋理)中像素到某個(gè)立體圖形的映 射過程,也有紋理映射,材質(zhì)貼圖等多種翻譯.


2D紋理貼圖

首先,需要說明的是,紋理貼圖的應(yīng)用實(shí)在太廣,內(nèi)容實(shí)在太多,我根本沒有辦法簡簡單單一篇文章就覆蓋全部的知識(shí),甚至是常用的部分都很難,這里只能大概 的講些基礎(chǔ)概念及給出幾個(gè)例子了,相對來說,比NEHE的例子還是要多一點(diǎn)。(NEHE每個(gè)知識(shí)一個(gè)例子,而且沒有任何原理講解)

這里先 提供一個(gè)簡單的2D對2D的例子.

//OpenGL 初始化開始
void SceneInit( int w, int h)
{
GLenum err = glewInit();
if (err != GLEW_OK)
{
MessageBox( NULL , _T( "Error" ), _T( "Glew init failed." ), MB_OK);
exit(- 1 );
}


glClearColor ( 0.0 , 0.0 , 0.0 , 0.0 );
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);

HBITMAP hBmp=(HBITMAP)LoadImageW( NULL , L"tiger.bmp" , IMAGE_BITMAP, 0 , 0 , LR_CREATEDIBSECTION | LR_LOADFROMFILE );

if (!hBmp)
{
exit( 3 );
}

GetObject(hBmp, sizeof (gBmp), &gBmp);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4 );
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glGenTextures( 1 , &gTexName);
glBindTexture(GL_TEXTURE_2D, gTexName);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, gBmp.bmWidth, gBmp.bmHeight,
0 , GL_BGR, GL_UNSIGNED_BYTE, gBmp.bmBits);
}

//這里進(jìn)行所有的繪圖工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, gTexName);

glBegin(GL_QUADS);
glTexCoord2f( 0.0 , 0.0 ); glVertex3f(- 1.0 , - 1.0 , 0.0 );
glTexCoord2f( 1.0 , 0.0 ); glVertex3f( 1.0 , - 1.0 , 0.0 );
glTexCoord2f( 1.0 , 1.0 ); glVertex3f( 1.0 , 1.0 , 0.0 );
glTexCoord2f( 0.0 , 1.0 ); glVertex3f(- 1.0 , 1.0 , 0.0 );

glEnd();
SwapBuffers(ghDC);
glDisable(GL_TEXTURE_2D);
}

LoadImage 的使用參看上一節(jié)講位圖顯示的內(nèi)容:《 Win32 OpenGL編程(15) 位圖顯示

glGenTextures用于生成一 個(gè)材質(zhì)的ID,就像OpenGL的顯示列表的用法。

glBindTexture 為剛創(chuàng)建的紋理(以紋理ID表示)綁定一個(gè)紋理,這里的參數(shù)表示是2D的紋理,事實(shí)上,紋理可以使1維的,3維的,甚至4維的。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4句確定了此2D紋理映射的一些參數(shù),參數(shù)實(shí)在太多,要都解釋,估計(jì)抵 的上一本書的一章了。
GL_TEXTURE_WRAP *的參數(shù)用于指定當(dāng)紋 理的頂點(diǎn)指定超過范圍時(shí)的做法,這里的做法就是重復(fù)(REPEAT)。類似于設(shè)置桌面時(shí),圖小于桌面分辨率的平鋪效果。(哦?MS顯示桌面的方式難道也是 用紋理貼圖?) GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER用于指定縮小方法時(shí)的計(jì)算的方法, 雖然都叫FILTER, 但是事實(shí)上放大時(shí)相當(dāng)于插值。這里用的是最近點(diǎn)的方式,最常用的還有線性方式。一般來說,線程方式會(huì)有更大的消耗,更好的質(zhì)量。《OpenGL SUPERBIBLE》說線性方式在現(xiàn)代的顯卡中的性能弱點(diǎn)可以忽略不計(jì),并且其優(yōu)點(diǎn)值得使用。從字面上很好理解最近點(diǎn)方式,一般取紋理中心的像素單元放 大縮小,可能導(dǎo)致嚴(yán)重鋸齒。線性方式,則是取每幾個(gè)臨近像素點(diǎn)進(jìn)行加權(quán)平均,決定新像素點(diǎn)的值,詳細(xì)了解。。。看看數(shù)字圖像處理的書?印象中大學(xué)的數(shù)字圖 像處理教程就有比較詳細(xì)的解釋。

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
確定紋理的應(yīng)用方法,說實(shí)話,我不太喜歡OpenGL中這種組合參數(shù)API,
通過幾個(gè)參數(shù)組合的方式來決定某個(gè)特性, 查資料太費(fèi) 神,左看右看,半天都不明白自己需要的一個(gè)簡單功能為啥弄的這么麻煩。
此句的意思建議去看看
OpenGL Reference Manual 》的 解釋,希望你能在10個(gè)小時(shí)內(nèi)看明白那5,6個(gè)10多行的表格表示的3個(gè)參數(shù)的組合表示什么意思-_-!對了,忘了說,某些時(shí)候,還需要組合多次 glTexEnv*調(diào)用來表示一個(gè)操作內(nèi)容-_-! 再看看下面的glTexImage2D函數(shù),紅寶 書用了整整一面多的篇幅,列舉其參數(shù)的可能值,不過,有人能看得懂嗎?
想起來某年某月某日,
某人問我:"OpenGL與D3D孰好?"
我 答曰:"或D3D否?"
其責(zé)之:"何好之有?"
我嘆之:“OpenGL神設(shè)計(jì)之,唯神知其所用。"
這是題外話。。。。感嘆一下, 想起了Qt設(shè)計(jì)者關(guān)于API設(shè)計(jì)哲學(xué)的論述,(參看< 設(shè)計(jì) qt 風(fēng)格的c++api【轉(zhuǎn)】 >) 尤為感嘆。勿怪。
那這句程序到底是啥意思呢?。。。。。。。。。。我說我沒有看懂,你不會(huì)怪我吧?基本上, GL_DECAL在材質(zhì)沒有Alpha通道時(shí),相當(dāng)于 GL_REPLACE,(用材質(zhì)替代原來物體的顏 色)有Alpha通道時(shí),相當(dāng)于GL_BLEND,(用材質(zhì)與原有物體混合) 我有點(diǎn)語無倫次了。。。。不 過想想 OpenGL Reference Manual 》, 《OpenGL 編程指南》幾萬個(gè)字都沒有講清楚,那么我?guī)资畟€(gè)字沒有講清楚也就不奇怪了。 )《OpenGL 編程指南》如是說:紋理貼圖是個(gè)相當(dāng)大的主題,并且具有相當(dāng)程序的復(fù)雜性.
基本上,就當(dāng)這 些都是一坨配置吧.
下圖是出來的效果:


這樣的效果像什么?就像是上一節(jié)講到的位圖顯示吧?呵 呵,的確,我也有這樣的感嘆,事實(shí)上,這才是OpenGL中顯示圖形的最佳方式.....而在OpenGL ES中,前面那些接口甚至都不存在........這里,我通過irrlicht的 draw2DImage 函 數(shù)可以獲得印證.以下是Irrlicht中的一個(gè) draw2DImage 函數(shù)的具體實(shí)現(xiàn):

void COpenGLDriver::draw2DImage( const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture)
{
if (!texture)
return ;

// texcoords need to be flipped horizontally for RTTs
const bool isRTT = texture->isRenderTarget();
const core::dimension2d<u32>& ss = texture->getOriginalSize();
const f32 invW = 1.f / static_cast <f32>(ss.Width);
const f32 invH = 1.f / static_cast <f32>(ss.Height);
const core::rect<f32> tcoords(
sourceRect.UpperLeftCorner.X * invW,
(isRTT?sourceRect.LowerRightCorner.Y:sourceRect.UpperLeftCorner.Y) * invH,
sourceRect.LowerRightCorner.X * invW,
(isRTT?sourceRect.UpperLeftCorner.Y:sourceRect.LowerRightCorner.Y) *invH);

const video::SColor temp[ 4 ] =
{
0xFFFFFFFF ,
0xFFFFFFFF ,
0xFFFFFFFF ,
0xFFFFFFFF
};

const video::SColor* const useColor = colors ? colors : temp;

disableTextures( 1 );
setActiveTexture( 0 , texture);
setRenderStates2DMode(useColor[ 0 ].getAlpha()< 255 || useColor[ 1 ].getAlpha()< 255 ||
useColor[ 2 ].getAlpha()< 255 || useColor[ 3 ].getAlpha()< 255 ,
true , useAlphaChannelOfTexture);

if (clipRect)
{
if (!clipRect->isValid())
return ;

glEnable(GL_SCISSOR_TEST);
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y,
clipRect->getWidth(), clipRect->getHeight());
}

glBegin(GL_QUADS);

glColor4ub(useColor[ 0 ].getRed(), useColor[ 0 ].getGreen(), useColor[ 0 ].getBlue(), useColor[ 0 ].getAlpha());
glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.UpperLeftCorner.Y));

glColor4ub(useColor[ 3 ].getRed(), useColor[ 3 ].getGreen(), useColor[ 3 ].getBlue(), useColor[ 3 ].getAlpha());
glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.UpperLeftCorner.Y));

glColor4ub(useColor[ 2 ].getRed(), useColor[ 2 ].getGreen(), useColor[ 2 ].getBlue(), useColor[ 2 ].getAlpha());
glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.LowerRightCorner.Y));

glColor4ub(useColor[ 1 ].getRed(), useColor[ 1 ].getGreen(), useColor[ 1 ].getBlue(), useColor[ 1 ].getAlpha());
glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.LowerRightCorner.Y));

glEnd();

if (clipRect)
glDisable(GL_SCISSOR_TEST);
}

除了剪裁測試,還有其對材質(zhì)進(jìn)行了 一層封裝,核心內(nèi)容(從glBegin到glEnd間的部分)就是上述紋理貼圖的內(nèi)容.講到這里,疑問來了,在OpenGL中,我們到底應(yīng)該使用哪種方式 來進(jìn)行位圖的顯示呢?前面講過的方法明顯要更加簡單,紋理貼圖的方法明顯要更繞,但是適用范圍更廣.那么,我想,先看看效率吧,同樣的圖的顯示,我測試一 下此節(jié)程序及上節(jié)程序的最大幀率.
加入下述FPS測試代碼,并且通過wglSwapIntervalEXT(0);關(guān)閉垂直同步(默認(rèn)是開啟垂直 同步的).(為了相對公平,原glbitmap的程序也改成了雙緩沖,新的程序關(guān)閉了深度測試)
// called every frame
int CalculateFPS(DWORD now)
{
static int frameCounted = 0;
static int startTime = GetTickCount();
static int fps = 0;
++frameCounted;

int elapsed = now - startTime;

if (elapsed >= 1500 )
{
fps = ( 1000 * frameCounted ) / elapsed;
startTime = now;
frameCounted = 0;
}

return fps;
}

// calculate the fps and display it in the window captain
void DisplayFPS(DWORD now)
{
static char buffer[100];
int fps = CalculateFPS(now);

sprintf(buffer, "fps=%d", fps);
SetWindowTextA(ghWnd, buffer);
}

測試結(jié)果是glBitmap版本大概是950~970之 間.而紋理貼圖版本只有930到950之間,也就是說,glBitmap版本在單純的圖片顯示上,效率還是有優(yōu)勢的,畢竟,OpenGL提供的特殊接口不 可能比通用實(shí)現(xiàn)方式要慢(最壞也要一樣,因?yàn)樘厥饨涌谄鸫a還能用通用實(shí)現(xiàn)方式實(shí)現(xiàn),不然寫驅(qū)動(dòng)的都吃白飯了)但是,就如前面所說的,紋理貼圖方式適用范圍 更廣,OpenGL ES中,也只能使用此方式,另外,"使用紋理貼圖方式,還能利用上很多3D的特效,因?yàn)?只要使用OpenGL寫引擎的,幾乎都用的紋理貼圖的方式." (我同事的原話)


2D紋理,3D圖形

無論如何,OpenGL是為3D而生的,那么光講2D那就相當(dāng)于沒有講 OpenGL,這里,提供一個(gè)2D紋理映射到3D圖形的例子.例子來自于 《Nehe OpenGL Tutorials》( 本教程位置 ),因?yàn)橘N圖位置的設(shè)置太繁瑣了,不想自己再寫一個(gè)了.例子經(jīng)過改造,嵌入了 Win32的框架中,然后,顯示的還是上面的老虎.


//OpenGL初始化開始
void SceneInit( int w, int h)
{
GLenum err = glewInit();
if (err != GLEW_OK)
{
MessageBox( NULL , _T( "Error" ), _T( "Glew init failed." ), MB_OK);
exit(- 1 );
}

wglSwapIntervalEXT( 0 );

glClearColor ( 0.0 , 0.0 , 0.0 , 0.0 );
glShadeModel(GL_FLAT);

glViewport( 0 , 0 ,WIDTH,HEIGHT); // Reset The Current Viewport

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window
gluPerspective( 45.0f ,(GLfloat)WIDTH/(GLfloat)HEIGHT, 0.1f , 100.0f );

glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix


HBITMAP hBmp=(HBITMAP)LoadImageW( NULL , L"tiger.bmp" , IMAGE_BITMAP, 0 , 0 , LR_CREATEDIBSECTION | LR_LOADFROMFILE );

if (!hBmp)
{
exit( 3 );
}

GetObject(hBmp, sizeof (gBmp), &gBmp);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4 );

glGenTextures( 1 , &gTexName);
glBindTexture(GL_TEXTURE_2D, gTexName);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, gBmp.bmWidth, gBmp.bmHeight,
0 , GL_BGR, GL_UNSIGNED_BYTE, gBmp.bmBits);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);


glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor( 0.0f , 0.0f , 0.0f , 0.5f ); // Black Background
glClearDepth( 1.0f ); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
}

//這里進(jìn)行所有的繪圖工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef( 0.0f , 0.0f ,- 5.0f );

glRotatef(xrot, 1.0f , 0.0f , 0.0f );
glRotatef(yrot, 0.0f , 1.0f , 0.0f );
glRotatef(zrot, 0.0f , 0.0f , 1.0f );

glBindTexture(GL_TEXTURE_2D, gTexName);

glBegin(GL_QUADS);
// Front Face
glTexCoord2f( 0.0f , 0.0f ); glVertex3f(- 1.0f , - 1.0f , 1.0f );
glTexCoord2f( 1.0f , 0.0f ); glVertex3f( 1.0f , - 1.0f , 1.0f );
glTexCoord2f( 1.0f , 1.0f ); glVertex3f( 1.0f , 1.0f , 1.0f );
glTexCoord2f( 0.0f , 1.0f ); glVertex3f(- 1.0f , 1.0f , 1.0f );
// Back Face
glTexCoord2f( 1.0f , 0.0f ); glVertex3f(- 1.0f , - 1.0f , - 1.0f );
glTexCoord2f( 1.0f , 1.0f ); glVertex3f(- 1.0f , 1.0f , - 1.0f );
glTexCoord2f( 0.0f , 1.0f ); glVertex3f( 1.0f , 1.0f , - 1.0f );
glTexCoord2f( 0.0f , 0.0f ); glVertex3f( 1.0f , - 1.0f , - 1.0f );
// Top Face
glTexCoord2f( 0.0f , 1.0f ); glVertex3f(- 1.0f , 1.0f , - 1.0f );
glTexCoord2f( 0.0f , 0.0f ); glVertex3f(- 1.0f , 1.0f , 1.0f );
glTexCoord2f( 1.0f , 0.0f ); glVertex3f( 1.0f , 1.0f , 1.0f );
glTexCoord2f( 1.0f , 1.0f ); glVertex3f( 1.0f , 1.0f , - 1.0f );
// Bottom Face
glTexCoord2f( 1.0f , 1.0f ); glVertex3f(- 1.0f , - 1.0f , - 1.0f );
glTexCoord2f( 0.0f , 1.0f ); glVertex3f( 1.0f , - 1.0f , - 1.0f );
glTexCoord2f( 0.0f , 0.0f ); glVertex3f( 1.0f , - 1.0f , 1.0f );
glTexCoord2f( 1.0f , 0.0f ); glVertex3f(- 1.0f , - 1.0f , 1.0f );
// Right face
glTexCoord2f( 1.0f , 0.0f ); glVertex3f( 1.0f , - 1.0f , - 1.0f );
glTexCoord2f( 1.0f , 1.0f ); glVertex3f( 1.0f , 1.0f , - 1.0f );
glTexCoord2f( 0.0f , 1.0f ); glVertex3f( 1.0f , 1.0f , 1.0f );
glTexCoord2f( 0.0f , 0.0f ); glVertex3f( 1.0f , - 1.0f , 1.0f );
// Left Face
glTexCoord2f( 0.0f , 0.0f ); glVertex3f(- 1.0f , - 1.0f , - 1.0f );
glTexCoord2f( 1.0f , 0.0f ); glVertex3f(- 1.0f , - 1.0f , 1.0f );
glTexCoord2f( 1.0f , 1.0f ); glVertex3f(- 1.0f , 1.0f , 1.0f );
glTexCoord2f( 0.0f , 1.0f ); glVertex3f(- 1.0f , 1.0f , - 1.0f );
glEnd();

xrot+= 0.3f ;
yrot+= 0.2f ;
zrot+= 0.4f ;

SwapBuffers(ghDC);
}
顯 示效果:



基本的意思還是和上面沒有區(qū)別,最最主要的部 分為頂點(diǎn)的設(shè)置部分,會(huì)發(fā)現(xiàn),將2D紋理映射到2D及映射到3D的區(qū)別并不大,2D紋理的位置指定還是按照一個(gè)一個(gè)面的來.這里,只不過以前2D時(shí)是僅有 一個(gè)面,現(xiàn)在面多了而已,方法還是一樣.另外,深度測試還是開啟為好,不然會(huì)亂作一團(tuán).

本文的完整源代碼在代碼庫中的2010-3-25目錄下


參考資料

1. 《 OpenGL Reference Manual 》,OpenGL 參考手冊

2. 《OpenGL 編程指南》(《 OpenGL Programming Guide 》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis 著,徐波譯,機(jī)械工業(yè)出版社

3. 《Nehe OpenGL Tutorials》,Nehe著,在 http://nehe.gamedev.net/ 上可以找到教程及相關(guān)的代碼下載,(有PDF版本教程下載)Nehe自己還做了一個(gè)面向?qū)ο蟮目蚣埽鳛檠菔境绦騺碚f,這樣的框架非常合適。也有 中文版 ,各取所需吧。

4.《OpenGL SUPERBIBLE》Fourth Edition,Comprehensive Tutorial and Reference,Richard S.Wright, Jr.,Benjamin Lipchak, Nicholas Haemel. Addison-Wesley


完整源代碼獲取說明

由于 篇幅限制,本文一般僅貼出代碼的主要關(guān)心的部分,代碼帶工程(或者makefile)完整版(如果有的話)都能用Mercurial在Google Code中下載。文章以博文發(fā)表的日期分目錄存放,請直接使用Mercurial克隆下庫:

https://blog-sample-code.jtianling.googlecode.com/hg/

Mercurial使用方法見《 分布式的,新一代版本控制系統(tǒng) Mercurial的介紹及簡要入門

要是僅僅想瀏覽全部代碼也 可以直接到google code上去看,在下面的地址:

http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code

原創(chuàng)文章作者保留版權(quán) 轉(zhuǎn)載請注明原作者 并給出鏈接

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

Win32 OpenGL編程(16) 紋理貼圖


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲综合射 | 人人做人人爽久久久精品 | 国产综合精品久久亚洲 | 操操操日日日 | 精品久久久久久中文字幕无碍 | 国产一区亚洲一区 | 超清乱人伦中文视频在线 | 日本一区二区高清 | 91成人影院未满十八勿入 | 天天躁日日2018躁狠狠躁 | 97在线免费看视频 | 床上毛片| 御姐色网| 91综合久久婷婷久久 | 无毒不卡| 欧美不卡在线视频 | 色视频亚洲| 国产精品亚洲一区二区三区 | 五月婷婷亚洲 | 色 在线播放 | 99资源在线 | 高清国产美女一级毛片 | 午夜免费福利在线观看 | 国产日韩欧美亚洲 | 最近中文字幕无吗免费视频 | 国产乱子伦一级毛片 | 日本在线观看www | 国产爱视频 | 成人a毛片手机免费播放 | 四虎国产精品一区二区 | 欧美日韩视频一区二区 | 毛片免费毛片一级jjj毛片 | 99久久久久国产精品免费 | 日韩亚洲欧美综合一区二区三区 | 香蕉综合在线 | 久草在在线视频 | 日韩欧美亚洲国产一区二区三区 | 色偷偷亚洲第一综合 | 四虎影院在线播放 | 77yyzz男人的天堂 | 精品福利视频第一 |