青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

DirectDraw 與 DirectInput 的游戲編程體驗

原文地址:http://www.gameres.com/Articles/Program/Abstract/DirectDraw%E4%B8%8EDirectInput%E7%9A%84%E6%B8%B8%E6%88%8F%E7%BC%96%E7%A8%8B%E4%BD%93%E9%AA%8C.htm

  我想關于這個主題的文章,不算少,但也不算太多。但大多是分別介紹 DirectDraw 與 DirectInput,而并沒有將其結合起來,也許你會問:“分開與合并起來并沒有本質區別啊!”。其實的確沒有本質區別,但那樣使那些最初對游戲編程報有極大熱情的愛好者感到非常失望,因為這其中的一個并不能完全滿足他們的要求,并且使其感到巨大的阻力,從而失去信心。所以本文將 DirectDraw 與 DirectInput結合起來去講一個主題就是“游戲編程”,請注意是“游戲編程”,當然這只是一個簡單的桌面游戲,但這已經與先前有很大的不同了,這已不是簡單的 DirectDraw或 DirectInput編程。我想你現在應該能夠體會出其中的區別了。

  聲明:在這之前需要你具有一定的 WIN32 API 函數的知識,并且可以熟練使用。和 DirectDraw的知識,關于DirectDraw可以參見 www.frontfree.net 中的 <<動畫程序編寫——DirectDraw之旅>> 1-3),或其它文章。最后是 c++ 語言,當然也要包括面向對象的那部分。在 Visual C++ .NET 編譯環境下進行開發的。

  首先 ,我們還是先簡要復習一下DirectDraw的概念吧!
DirectDraw本質上是顯存管理程序。它最重要的性能是允許程序員直接在顯存里存儲和操縱位圖。它使你能夠利用視頻硬件bliter(位塊傳輸器)在顯存內部進行位圖的blit(位塊傳輸)。用視頻硬件的blitter從顯存向顯存進行blit比從內存向顯存更快。這在64位顯卡向顯存提供64位數據路徑的今天顯得尤其重要,硬件獨立于促CPU進行位塊傳輸操作,使得CPU得以繼續工作。另外DirectDraw支持顯卡的其他硬件加速特性,例如對精靈和z -buffering的硬件支持。

DirectDraw的工作原理

我們這里還是用圖表方式展現給大家吧!

  細心的朋友可以很明顯地注意到圖示中的右上角的圖解中說明,表面對象有兩個寬度,一個是WIDTH,一個是PITCH。WIDTH就是創建表面時所給出的那個寬度,而PITCH是表面的實際寬度,是按字節算的。在許多顯卡上,PITCH和WIDTH是相等的,比如在640x480的高彩模式下,PITCH為1280。而在某些顯卡上,PITCH比WIDTH要大。比如在640x480的256色模式下,當WIDTH是640時,PITCH為1024而不是640,這些顯卡這樣做是為了更好地進行數據對齊來提高性能或達到其它目的。所以,我們在實際編程時,為了保證程序的兼容性,必須按PITCH處理。 但這些硬件的底層問題,我們不用太關心,只要稍有了解就可以了。

下面我們再簡要敘述一下,如何使用 DirectX 9.0 中提供的 DirectDraw 類庫來創建對象并使用操作對象。

宏定義在先,定義刪除指針和釋放對象的宏

#defineSAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

先創建一個 CDisplay 的全局對象
CDisplay就是ddutil.h中定義的類,用于處理表面之間的拷貝翻頁等操作的類,再次定義一個全局變量,用于以后對指向的表面之間進行操作

CDisplay* g_pDisplay = NULL;

然后創建表面,當然可以創建很多的表面,這些表面都是離屏表面,在更新畫面時,都可以用 CDisplay 類的對象中的方法,將其拷貝到后備緩沖區表面上。只要創建離屏表面,就要用到 CSurface 類。CSurface也是ddutil.h頭文件中定義的類,用于對表面本身進行操作,如設置色彩鍵碼,在此定義的圖畫指針。
 

CSurface* g_pBackSurface = NULL;

DirectX 中就一共用這兩個類封裝了 DirectDraw 對象的大部分操作,如果你覺得這還不能滿足要求,那么你也可以在程序中用 DirectDraw API 函數編寫程序,不過在本文中不再介紹。

這之后,我們會用到 InitDirectDraw 函數。這個函數是我們自己創建的。在此函數中作所有的 DirectDraw 的對象初始化工作。

HRESULT InitDirectDraw( HWND hWnd )
{
?????HRESULT hr;
//接受返回值,其實是long型變量
?????LPDIRECTDRAWPALETTE pDDPal = NULL; //定義程序中的調色板
?????int iSprite;//定義與sprite個數有關的計數器
?????g_pDisplay = newCDisplay();//動態開辟一個CDisplay類
?????if( FAILED( hr = g_pDisplay->CreateFullScreenDisplay( hWnd, SCREEN_WIDTH,
???????????SCREEN_HEIGHT, SCREEN_BPP ) ) )
/*設置程序為全屏,并且 g_pDisplay 就是動態開辟一個CDisplay類的指針,而在這個類的域中,有一個DirectDraw主表面指針,和一個后備緩沖區表面的指針。在從我建議你可以先去閱讀一下 ddutil.h 和 ddutil.cpp 文件。*/
?????{
???????????MessageBox( hWnd, TEXT("This display card does not support 1024x768x8. "),
?????????????????TEXT("DirectDraw Sample"), MB_ICONERROR | MB_OK );

???????????return hr;
?????}

?????if( FAILED( hr = g_pDisplay->CreatePaletteFromBitmap( &pDDPal, MAKEINTRESOURCE( IDB_DIRECTX ) ) ) )//顧名思義,就是從bmp圖片中獲得調色板值,并賦值在pDDPal結構指針所指向的結構體中。
???????????returnhr;
?????if( FAILED( hr = g_pDisplay->SetPalette( pDDPal ) ) )//用剛才從IDB_DIRECTX中獲得的調色板制來設置程序調色板
???????????returnhr;
?????SAFE_RELEASE( pDDPal );
//釋放指針,在用過后,一定要釋放,這是良好的編程習慣
??????// 用IDB_WINXP圖片創建一個表面,并用g_pBackSurface指向這個表面
?????if( FAILED( hr = g_pDisplay->CreateSurfaceFromBitmap( ??????&g_pBackSurface, MAKEINTRESOURCE( IDB_WINXP ),
??????SCREEN_WIDTH, SCREEN_HEIGHT ) ) )

???????????return hr;//設置色彩鍵碼為黑色,0代表黑色,這樣在表面的拷貝過程中黑色像素的點將不會被拷貝,這樣可以產生鏤空效果。當然你可以任意設置關鍵顏色,而顏色的表示法可以用 RGB 宏定義。例如 紅色:RGB( 255,0,0 ), 黑色 RGB( 255,255,255 )
??????if( FAILED( hr = g_pBackSurface->SetColorKey( RGB( 255,255,255 ) ) ) )
???????????returnhr;
?????returnS_OK;
}

下面的函數是用于更新畫面的。
 

HRESULT DisplayFrame()
{
?????HRESULT hr;
?????g_pDisplay->Clear( 0 );
//清空后備緩沖區表面
?????//將g_pBackSurface所指向的圖片拷貝到后備緩沖區表面
??????g_pDisplay->Blt( 0, 0, g_pBackSurface, NULL );//最關鍵的地方在這里,請看下面的語句,只要我們一執行翻頁操作,就可以將改動了的圖像了顯示在屏幕上了
?????if( FAILED( hr = g_pDisplay->Present()/*翻頁操作*/) )
???????????returnhr;
?????returnS_OK;
}

下面的函數是用于在程序失去焦點時調用的。

HRESULT RestoreSurfaces()
{
?????HRESULT hr;
?????LPDIRECTDRAWPALETTE pDDPal = NULL;
/*當程序失去焦點,要保存當前的畫面,請注意這里,g_pDisplay->GetDirectDraw()函數返回的才是真正的 DirectDraw 對象 */
?????if( FAILED( hr = g_pDisplay->GetDirectDraw()->RestoreAllSurfaces() ) )
???????????returnhr;//在此我們還要重新創建調色板
?????if( FAILED( hr = g_pDisplay->CreatePaletteFromBitmap( &pDDPal, MAKEINTRESOURCE( IDB_DIRECTX ) ) ) )
???????????returnhr;//重新設置調色板
?????if( FAILED( hr = g_pDisplay->SetPalette( pDDPal ) ) )
???????????returnhr;
?????SAFE_RELEASE( pDDPal );//重新畫出圖畫
?????if( FAILED( hr = g_pLogoSurface->DrawBitmap( MAKEINTRESOURCE( IDB_WINXP ),
SPRITE_DIAMETER, SPRITE_DIAMETER ) ) )

???????????returnhr;
?????returnS_OK;
}

下面這個函數是釋放表面指針所用的。

VOID FreeDirectDraw()
{
??????SAFE_DELETE( g_pBackSurface );
??????SAFE_DELETE( g_pDisplay );
}

我們的回顧到此結束,下面我們開始本文要介紹的一個關鍵技術,DirectInput 的使用。
游戲編程可不僅僅是圖形程序的開發工作,實際上包含了許多方面,本文所要講述的就是關于如何使用 DirectInput 來對鍵盤編程的問題。
而我們為什么要選擇用 DirectInput 來處理游戲中的輸入問題呢?其實用 Win32 API 函數也完全可以處理這些工作,例如其中,有一個

GetAsyncKeyState() 的函數可以返回一個指定鍵的當前狀態是按下還是松開。這個函數還能返回該指定鍵在上次調用 GetAsyncKeyState() 函數以后,是否被按下過。雖然這個函數聽上去很不錯,但需要我們自己輪換查詢每個鍵盤的狀態。而在 DirectInput 中我們已經可以脫離這些煩瑣的工作,只因它的功能更強大。

由于本文重點在二者的結合,故在此只介紹 DirectInput 中比較簡單的,而且最容易上手的立即模式的工作方式。
而這里我們要用到 DirectInput 的 API 函數。有人會問,為什么在 DirectDraw 中用 DirectX 提供的類庫編程,而對于 DirectInput 卻直接使用要用其 API 函數呢,是因為沒有提供 DirectInput 的類庫嗎?不是!而是因為使用類庫并不很方便而且不靈活。

OK,讓我們開始我們游戲編程的第二部——DirectInput編程。

前面講 DirectDraw 時,并沒有提到,微軟是按 COM 來設計DirectX的,所以就有了一個 DIRECTINPUT 對象來表示輸入設備,而某個具體的設備由 DIRECTINPUTDEVICE 對象來表示。也許會感到很無奈,怎么游戲編程需要這么多的知識啊,其實您也無需煩惱,只要知道一下就可以了,其實這并不;影響您的設計,而且就算您不知道,也同樣可以駕馭DIRECTINPUT。

實際的建立過程是先創建一個 DIRECTINPUT 對象,然后在通過此對象的 CreateDevice 方法來創建 DIRECTINPUTDEVICE 對象。

#include <dinput.h>
#defineDINPUT_BUFFERSIZE 16
LPDIRECTINPUT lpDirectInput;
// DirectInput 對象實際上是一個com對象
LPDIRECTINPUTDEVICE lpKeyboard; // DirectInput 設備
BOOL InitDInput(HWND hWnd)
{
??????HRESULT hr;
// 創建一個 DIRECTINPUT 對象
?????if( FAILED( hr = DirectInputCreate(hInstanceCopy, DIRECTINPUT_VERSION, &lpDirectInput, NULL)))
?????{
// 失敗提示或處理
???????returnhr;
??????}
// 創建一個 DIRECTINPUTDEVICE 界面
//參數 GUID_SysKeyboard 指明了建立的是鍵盤對象

??????if( FAILED( hr = lpDirectInput->CreateDevice(GUID_SysKeyboard, &lpKeyboard, NULL)))
??????{

????????????// 失敗提示或處理
????????????returnhr;
???????}
// 設定為通過一個 256 字節的數組返回查詢狀態值
??????if( FAILED(hr = lpKeyboard->SetDataFormat(&c_dfDIKeyboard)))
??????{

??????// 失敗提示或處理
????????????return hr;
??????}// 設定協作模式為獨占模式和前臺模式,獨占模式表面本程序在運行中占有所有鍵盤資源,而前臺模式指出當程序具有焦點時才可以占有鍵盤資源
??????if( FAILED( hr = lpKeyboard->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
??????{

??????// 失敗提示或處理
????????????returnhr;
??????}

??????// 設定緩沖區大小
??????// 如果不設定,緩沖區大小默認值為 0,程序就只能按立即模式工作
??????// 如果要用緩沖模式工作,必須使緩沖區大小超過 0
??????// 在此,我們沒有必要設定,因為我們就用立即模式工作(還有一種緩沖模式),所有我們將其注調了

??????/* DIPROPDWORD property;

??????property.diph.dwSize = sizeof(DIPROPDWORD);
??????property.diph.dwHeaderSize = sizeof(DIPROPHEADER);
??????property.diph.dwObj = 0;
??????property.diph.dwHow = DIPH_DEVICE;
??????property.dwData = DINPUT_BUFFERSIZE;

??????if( FAILED(hr = lpKeyboard->SetProperty(DIPROP_BUFFERSIZE, &property.diph)))
??????{
??????// 失敗
????????????return FALSE;
??????}
??????*/

??????//此處是關鍵,我們要通過這個函數來鎖定鍵盤,記住,所有的DirectInput資源在使用前都要鎖定,在此即獲得鍵盤資源,在知識我們剛才設定的鍵盤模式才能起作用
??????hr = lpKeyboard->Acquire();
??????if FAILED(hr)
??????{

????????????// 失敗
????????????return FALSE;
??????}
??????returnTRUE;
??????}

在這段代碼中,我們首先定義了 lpDirectInput 和 lpKeyboard 兩個指針,前者指向 DIRECTINPUT 對象,后者指向一個

DIRECTINPUTDEVICE 界面。其順序就是這樣的。這和其它COM對象的使用方法都一樣,即先創建 COM 對象,然后創建界面,然后再獲得
硬件資源,然后使用資源,然后釋放。

通過 DirectInputCreate(), 我們為 lpDirectInput 創建了一個 DIRECTINPUT 對象。然后我們調用 CreateDevice 來建立一個DIRECTINPUTDEVICE 界面。
  
完成這些工作以后,我們便調用 DIRECTINPUTDEVICE 對象的 Acquire 方法來激活對設備的訪問權限。在此要特別說明一點,任何一個

DIRECTINPUT 設備,如果未經 Acquire,是無法進行訪問的。還有,當系統切換到別的進程時,必須用 Unacquire 方法來釋放訪問權限,在系統切換回本進程時再調用 Acquire 來重新獲得訪問權限。

立即模式的數據查詢

HRESULT ReadImmediateData( HWND hWnd )
{
??????HRESULT hr;
??????BYTE diks[256];
// 創建鍵盤狀態數據緩沖區存取鍵盤信息
??????inti; // 計數器
??????if( NULL == g_pKeyboard )
????????????returnS_OK;// 鍵盤狀態數據緩沖區清0
??????ZeroMemory( &diks, sizeof(diks) );// 獲得鍵盤所有鍵的信息,這只是檢查一次
??????hr = g_pKeyboard->GetDeviceState( sizeof(diks), &diks );
??????if( FAILED(hr) )
??????{

????????????// 如果鍵盤資源丟失,我們要重新獲得
????????????hr = g_pKeyboard->Acquire();
????????????while( hr == DIERR_INPUTLOST )
????????????hr = g_pKeyboard->Acquire();

????????????returnS_OK;
??????}
// 進行一下輪循,處理鍵盤信息。
??????for( i = 0; i < 256; i++ )
??????{

????????????if( diks[i] & 0x80 ) //記錄此鍵的狀態,低字節最高位是 1 表示按下,0 表示松開,一般用 diks[i]&0x80 來測試
????????????{
??????????????????switch(i)
??????????????????{

??????????????????????????????//我們可以通過測試計數器i,來判斷是哪個鍵被按下了。
??????????????????????????????//我們提供幾個數據 UP:200 down:208 left:203 right:205 enter:28 space:57
??????????????????????????????//其實你可以用DirectX中的Samples\C++\DirectInput\Bin\Keyboard.exe程序來測試,只不過那是用
??????????????????????????????//16進制顯示的。
????????????????????????case200:
??????????????????????????????break;
????????????????????????case0xc8:
??????????????????????????????break;
??????????????????}
????????????}
??????}

??????returnS_OK;
}

請注意,上面的這段代碼只是一個示例,重在使你明白其原理,但并不能滿足游戲的需求,因為這其中只查詢了一次鍵盤的全部信息,做了一次輪循,而在游戲中要周期性地查詢,并輪循,這就需要你自己用Win32 API函數 SetTimer和 KillTimer 設置初始化 DirectInput 對象函數中在相應的地方設置計計時器,讓windows定時向程序發送 WM_TIMER消息,你要通過此消息進行周期性地鍵盤查詢,并在相應的地方解除計時器。

最后一個函數是用于釋放指針或DirectInput對象的

void ReleaseDInput(void)
{

??????if(lpDirectInput)
??????{

????????????if(lpKeyboard)
????????????{

??????????????????// Always unacquire the device before calling Release().
??????????????????lpKeyboard->Unacquire();
??????????????????lpKeyboard->Release();
??????????????????lpKeyboard = NULL;
????????????}
????????????lpDirectInput->Release();
????????????lpDirectInput = NULL;
??????}
}

在這些函數中的注釋很明確,關鍵在于理解其原理,而怎樣將他們融入到 Win32 API 程序的基本框架中的,在<<動畫程序編寫——DirectDraw之旅>> 1-3中的示例代碼中已經解釋得很明確了,在此不再贅述。不過我們提供其中的代碼示例下載。同時你也可以去仔細閱讀DirectX 8.0 SDK 包中的 samples\ multimedia\ directdraw\ fullscreenmode\ samples\ multimedia\ directdraw\ windowedmode 這兩個工程中的文件,因為為了我們的示例也是照這兩個工程改編過來的,讀者可以通過仔細閱讀代碼和對比我們的更改,而更加了解 DirectDraw的運行運行原理。(請注意:是 DirectX 8.0 SDK 包中的示例,而在 9.0 中 DirectX SDK 已經不提供 DirectDraw的示例代碼了)

我們就用這七個函數就已經可以創造出一個小游戲了。

我們下面就要利用<<動畫程序編寫——DirectDraw之旅>> 1-3 中所用的代碼進行進一部的游戲開發。
我們先展示一下 DirectX中\ samples\ multimedia\ directdraw\ windowedmode 工程中的截圖
在這個動畫中有黑色背景,并有很多 DirectX 精靈在漂浮。



這是一個全屏的動畫程序,而我們在<<動畫程序編寫——DirectDraw之旅>> 1-3其中做的改動就是為其加了一個背景,改屏幕分辨率 640×480 為 1024×768.注意,因為我們應用的是全屏模式,即可以獨占顯存資源,所以我們可以更改屏幕的分辨率。這只是做的小小的改動,而我們的目的只在于讓大家更加深入了解。且看下面的這副截圖:

而我們還要繼續深入編程,我們的思路是,先將程序由先前的全屏程序改編成一個windows的窗口程序,然后將其所有的界面翻新,并改編 DirectX精靈為許多小蘑菇在漂浮,還要加入DirectInput 的組建,用鍵盤控制一個小娃娃。可以上下左右,并可以斜向飛行。
我們先將此動畫的截圖展現給大家

怎么樣,你有什么想法,是想說:“唉,這還不好辦,就是又多加了一個!”,但不要光看截圖,不要忘記,我們一定讓她動起來,并且是可以控制的,這就不是那么簡單的事了!
什么?若有人看到這里感到有些迷茫和泄氣,不禁想問:“你說了這么多,那么源代碼在那里呢!,光給我們幾個函數,又能做什么呢?”,如果你這么想,你也不要太急迫。我們還是先分析一下程序框架吧。

不過,還有一件重要的事情,我還是要重申一邊。一定要將 DirectX 的頭文件價,和lib文件夾加入到 Visual C++.NET 的默認目錄中去,這樣編譯器就可以正確地找到它們了。
如果你不會加入,就請通過工具欄上的 Tool -> Option… 打開Option 對話框,設置如圖:



好了,這樣我們的準備工作就算已經做好了。

來看看我們的工程文件結構吧,還有工程中的資源。

在工程資源中我們的 ID 號是都用的字符串表示的,筆者認為這樣更加方便。
我想對于工程文件中的 ddutil.cpp 和 dxutil.cpp 文件,讀者如果了解有些 DirectDraw編程是不會感到陌生的,我們只是將其引入到我們的工程中了。而我們自己實際編程的文件是
outfly.cpp 文件。

我們的程序敘述如下:
首先進行宏定義,結構設置,和全局變量的聲明。
后在 WinMain (windows程序的入口點)中首先初始化一切需要初始化的物件(有windows窗口,DirectDraw對象,和 DirectInput對象),在此我們就調用前文講過的函數,但要有寫改動,讀者在會在后面看到的。然后進入消息循環,在其中沒有消息時,程序會自動更新畫面,在有消息時處理消息。
當遇到 WM_QUIT 消息后,結束整個程序。

我們在一些地方有一些小小的改動,我們來看看吧。

1 我們在 HRESULT InitDirectInput( HWND hWnd )
函數中的開始加入了

KillTimer( hWnd, 0 );
FreeDirectInput();

關掉上一次使用的計時器,并釋放 DirectInput 設備。
而在最后加入了

SetTimer( hWnd, 0, 1000 / 100, NULL );

用來重新設置計時器。

2 我們在主窗口的消息處理函數中加入了

case WM_ACTIVATE: //當程序先失去焦點,而現在有重新得到焦點時,要重新鎖定鍵盤資源
??????if( WA_INACTIVE != wParam && g_pKeyboard )
??????{

????????????// Make sure the device is acquired, if we are gaining focus.
????????????g_pKeyboard->Acquire();
??????}

??????break;
caseWM_TIMER: //因為設置了計時器所以要處理此消息
??????if( FAILED( ReadImmediateData( hWnd ) ) )
??????{
????????????KillTimer( hWnd, 0 );
????????????MessageBox( NULL, _T("Error reading input state. ")
????????????_T("The sample will now exit."),
????????????_T("Keyboard"), MB_ICONERROR | MB_OK );
??????}

??????break;
caseWM_DESTROY:// Cleanup and close the app
??????FreeDirectDraw();
??????FreeDirectInput();
// 釋放資源
??????PostQuitMessage( 0 );
??????return 0L;

3 在HRESULT ReadImmediateData( HWND hWnd ) 函數中進行了這樣的處理,來時時改變小娃娃的坐標。

for( i = 0; i < 256; i++ )
{

??????if( diks[i] & 0x80 )
??????{

????????????switch(i)
????????????{

??????????????????case200: //上鍵
????????????????????????if( g_me.fPosY > g_me.fVelY)
??????????????????????????????g_me.fPosY -= g_me.fVelY;

????????????????????????else
??????????????????????????????g_me.fPosY = 0;
????????????????????????break;
??????????????????case208: //下鍵
????????????????????????if( g_me.fPosY <= WINDOW_HEIGHT - SPRITE_DIAMETER - g_me.fVelY)
??????????????????????????????g_me.fPosY += g_me.fVelY;

????????????????????????else
??????????????????????????????g_me.fPosY = WINDOW_HEIGHT- SPRITE_DIAMETER;
????????????????????????break;
??????????????????case203://左鍵
????????????????????????if( g_me.fPosX > g_me.fVelX)
??????????????????????????????g_me.fPosX -= g_me.fVelX;

????????????????????????else
??????????????????????????????g_me.fPosX = 0;
????????????????????????break;
??????????????????case205://右鍵
????????????????????????if( g_me.fPosX <= WINDOW_WIDTH - SPRITE_DIAMETER - g_me.fVelX)
??????????????????????????????g_me.fPosX += g_me.fVelX;

????????????????????????else
??????????????????????????????g_me.fPosX = WINDOW_WIDTH- SPRITE_DIAMETER;
????????????????????????break;
????????????}
??????}
}

這些只是其中一些比較重要的改動,還有許多改動,讀者會在實際的程序中看到的。如果你覺得:“啊!到這里就結束了,可是我還是感到似乎莫不到頭緒,就這樣草草收尾了?”,其實文章并沒有結束,重頭戲還在后面呢,那就不是我的工作了,而是看你有沒有耐心去仔細閱讀代碼了,因為想要把握程序的整體,與其讓我將代碼放在文章中,還不如讀者自己在編譯器中自己運行實踐一下好,其實我們已經在第二個工程代碼中有過詳細的解釋。但記住一定要按照順序閱讀 工程1,工程2 ,工程3。工程1就是 DirectX中提供的原代碼,工程2就是我們改了一個背景的工程,而3就是我們討論的工程。

 

放飛技術網?

posted on 2006-06-20 15:26 楊粼波 閱讀(310) 評論(0)  編輯 收藏 引用 所屬分類: 文章收藏

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国精产品99永久一区一区| 亚洲一区黄色| 中文精品在线| 亚洲精品久久在线| 欧美了一区在线观看| 中文精品在线| 午夜欧美精品久久久久久久| 极品裸体白嫩激情啪啪国产精品| 欧美成人国产| 欧美成人资源| 亚洲欧美日本日韩| 久久精品国产视频| 亚洲人成绝费网站色www| 国产精品人人做人人爽 | 国产精品久久久久久久久久免费 | 在线视频一区观看| 国产精品免费久久久久久| 久久色中文字幕| 欧美福利视频在线观看| 亚洲你懂的在线视频| 香蕉精品999视频一区二区| 在线看视频不卡| 一区二区三区国产盗摄| 精品电影在线观看| 亚洲午夜激情| 亚洲国产精品久久久久秋霞影院| 亚洲午夜国产一区99re久久 | 亚洲老司机av| 亚洲天堂偷拍| 亚洲国产精品va在线看黑人| 在线一区二区三区四区| 精品91免费| 亚洲午夜精品| 99在线热播精品免费| 久久精品官网| 亚洲欧美影院| 欧美成人精品高清在线播放| 欧美一区二区三区视频在线观看| 宅男噜噜噜66国产日韩在线观看| 鲁大师影院一区二区三区| 亚洲片在线资源| 久久精品视频网| 欧美一区二区三区日韩| 欧美三级视频在线播放| 欧美大片在线观看| 激情一区二区| 亚洲欧美日韩中文播放| 亚洲一区在线播放| 欧美日韩一区在线观看视频| 亚洲电影毛片| 亚洲国产婷婷香蕉久久久久久| 欧美成人69av| 韩国av一区| 欧美亚洲在线观看| 亚洲欧美日韩精品久久奇米色影视| 一二三区精品福利视频| 日韩亚洲欧美一区| 另类图片国产| 欧美国产精品日韩| 亚洲黄色视屏| 欧美高清视频| 日韩视频精品在线| 一区二区三区四区五区精品视频| 亚洲在线电影| 亚洲欧美激情四射在线日| 国产精品高潮呻吟久久| 亚洲图片欧洲图片日韩av| 午夜欧美大尺度福利影院在线看| 欧美亚洲综合另类| 久久精品一区二区国产| 韩国女主播一区| 久久亚洲私人国产精品va| 免费看的黄色欧美网站| 亚洲激情小视频| 免费观看亚洲视频大全| 国产免费观看久久| 欧美一区二区三区精品| 欧美综合国产| 激情成人亚洲| 欧美紧缚bdsm在线视频| 一本色道久久综合亚洲精品高清| 国产一区二区三区精品久久久| 欧美成人国产一区二区| 日韩视频免费在线| 欧美日韩亚洲不卡| 亚洲欧美经典视频| 六月天综合网| 9色精品在线| 国产欧美一区二区精品性| 久久久精品免费视频| 亚洲精品色婷婷福利天堂| 亚洲欧美国产制服动漫| …久久精品99久久香蕉国产| 欧美精品一区二区视频 | 久久免费99精品久久久久久| 亚洲大片精品永久免费| 欧美视频1区| 久久久久久久精| 99精品久久| 免费国产一区二区| 亚洲视频网站在线观看| 影音先锋久久资源网| 欧美午夜不卡视频| 狼狼综合久久久久综合网| 9色国产精品| 蜜臀av性久久久久蜜臀aⅴ| 亚洲一区欧美激情| 亚洲国产成人久久综合| 国产精品日韩久久久| 欧美成人精品一区二区| 欧美一区二区三区视频在线观看| 亚洲欧美日韩一区二区三区在线观看 | 91久久精品久久国产性色也91| 亚洲欧美综合一区| 亚洲欧洲另类国产综合| 久久精品国产久精国产一老狼| 国产欧美日韩91| 欧美日本高清视频| 另类av一区二区| 欧美在线啊v| 亚洲在线观看视频网站| 91久久综合亚洲鲁鲁五月天| 猛男gaygay欧美视频| 午夜精品久久久久久久| 一区二区免费在线视频| 亚洲激情av| 在线观看成人av| 国一区二区在线观看| 国产日本精品| 国产农村妇女毛片精品久久莱园子| 先锋影院在线亚洲| 亚洲永久在线观看| 亚洲一区二区久久| 亚洲图片你懂的| 亚洲无亚洲人成网站77777| 亚洲蜜桃精久久久久久久| 最近中文字幕mv在线一区二区三区四区 | 欧美日韩国产一区二区三区| 欧美伊人影院| 欧美一区二区日韩一区二区| 亚洲欧美国产日韩中文字幕| 亚洲国产综合91精品麻豆| 久久人人爽人人爽| 欧美综合77777色婷婷| 亚洲一区在线免费观看| 亚洲影视在线| 午夜视频一区二区| 欧美中文字幕| 久久久久看片| 欧美不卡视频| 欧美激情综合| 国产精品久久福利| 国产日韩欧美一区| 国产性做久久久久久| 国产日韩欧美不卡在线| 国语自产精品视频在线看一大j8| 噜噜噜噜噜久久久久久91| 久久国产精品免费一区| 久久永久免费| 欧美激情二区三区| 国产精品久久久| 国产欧美视频一区二区| 伊人久久大香线| 亚洲精品一区二区三区婷婷月 | 亚洲国产日韩综合一区| 夜夜精品视频| 亚洲欧美成人一区二区三区| 午夜视频久久久| 快播亚洲色图| 亚洲福利视频网| 日韩一二在线观看| 久久成人精品一区二区三区| 欧美成人性生活| 国产精品美女久久福利网站| 国产欧美短视频| 亚洲福利在线视频| 亚洲欧洲av一区二区三区久久| 国产午夜精品美女毛片视频| 韩国视频理论视频久久| 99国产精品久久久久老师| 欧美在线电影| 亚洲国产一区二区视频| 亚洲一区二区欧美日韩| 女女同性女同一区二区三区91| 亚洲综合精品| 欧美成人国产| 国产欧美日韩一级| 99香蕉国产精品偷在线观看| 久久精品国产综合精品| 亚洲精品小视频| 久久久女女女女999久久| 国产精品扒开腿做爽爽爽视频| 欧美精品福利在线| 黑人一区二区三区四区五区| 一本色道久久综合亚洲精品不| 亚洲三级色网| 久久久综合网| 欧美一级大片在线免费观看| 欧美手机在线视频| 日韩视频在线免费观看|