这里要讨论的是,DXUT中的一般框架。以前看了很多资料了,讲得十分详细。不过我在这里就把一些简单的东西总结一下,比如DXUT的工作机制以及模式。对只想了解一下并且快速上手使用的人应该很有帮助。
      下面要说的只是我自己自学以及领悟到的内容而已,难免有疏漏和错误,希望读者可以帮我指出。

      DXUT,就是DirectX SDK中附带的一个功能齐全的Direct3D底层框架,有各种语言版本,但其实构架都差不多。这里以C++的为标准,SDK版本为June 2008。

      先把DirectX SDK里的EmptyProject安装了,打开工程。

      简单了解的话,只用来看一下这个DXUT.h,我再稍微说一下就应该大概明白了。
      不要被代码吓住!!!往后看吧。这个代码是拿来对照讲的。
   

  1 // --------------------------------------------------------------------------------------
  2 //  File: DXUT.h
  3 //
  4 //  Copyright (c) Microsoft Corporation. All rights reserved.
  5 // --------------------------------------------------------------------------------------
  6 #pragma once
  7 #ifndef DXUT_H
  8 #define  DXUT_H
  9
 10 #ifndef UNICODE
 11 #error  "DXUT requires a Unicode build. See the nearby comments for details"
 12 //
 13 //  If you are using Microsoft Visual C++ .NET, under the General tab of the project 
 14 //  properties change the Character Set to 'Use Unicode Character Set'.  
 15 //
 16 //  Windows XP and later are native Unicode so Unicode applications will perform better.  
 17 //  For Windows 98 and Windows Me support, consider using the Microsoft Layer for Unicode (MSLU).  
 18 //
 19 //  To use MSLU, link against a set of libraries similar to this
 20 //       /nod:kernel32.lib /nod:advapi32.lib /nod:user32.lib /nod:gdi32.lib /nod:shell32.lib /nod:comdlg32.lib /nod:version.lib /nod:mpr.lib /nod:rasapi32.lib /nod:winmm.lib /nod:winspool.lib /nod:vfw32.lib /nod:secur32.lib /nod:oleacc.lib /nod:oledlg.lib /nod:sensapi.lib UnicoWS.lib kernel32.lib advapi32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib version.lib mpr.lib rasapi32.lib winmm.lib winspool.lib vfw32.lib secur32.lib oleacc.lib oledlg.lib sensapi.lib dxerr.lib dxguid.lib d3dx9d.lib d3d9.lib comctl32.lib dsound.lib
 21 //  and put the unicows.dll (available for download from msdn.microsoft.com) in the exe's folder.
 22 //  
 23 //  For more details see the MSDN article titled:
 24 //  "MSLU: Develop Unicode Applications for Windows 9x Platforms with the Microsoft Layer for Unicode"
 25 //  at  http://msdn.microsoft.com/msdnmag/issues/01/10/MSLU/default.aspx  
 26 //
 27 #endif
 28
 29 // --------------------------------------------------------------------------------------
 30 //  Structs
 31 // --------------------------------------------------------------------------------------
 32 class  CD3DEnumeration;
 33
 34 struct  DXUTDeviceSettings
 35 {
 36    UINT AdapterOrdinal;
 37    D3DDEVTYPE DeviceType;
 38    D3DFORMAT AdapterFormat;
 39    DWORD BehaviorFlags;
 40    D3DPRESENT_PARAMETERS pp;
 41}
;
 42
 43
 44 // --------------------------------------------------------------------------------------
 45 //  Error codes
 46 // --------------------------------------------------------------------------------------
 47 #define  DXUTERR_NODIRECT3D              MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0901)
 48 #define  DXUTERR_NOCOMPATIBLEDEVICES     MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0902)
 49 #define  DXUTERR_MEDIANOTFOUND           MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0903)
 50 #define  DXUTERR_NONZEROREFCOUNT         MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0904)
 51 #define  DXUTERR_CREATINGDEVICE          MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0905)
 52 #define  DXUTERR_RESETTINGDEVICE         MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0906)
 53 #define  DXUTERR_CREATINGDEVICEOBJECTS   MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0907)
 54 #define  DXUTERR_RESETTINGDEVICEOBJECTS  MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0908)
 55 #define  DXUTERR_INCORRECTVERSION        MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0909)
 56
 57
 58 // --------------------------------------------------------------------------------------
 59 //  Callback registration 
 60 // --------------------------------------------------------------------------------------
 61 typedef  bool     (CALLBACK  * LPDXUTCALLBACKISDEVICEACCEPTABLE)( D3DCAPS9 *  pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,  bool  bWindowed,  void *  pUserContext );
 62 typedef  bool     (CALLBACK  * LPDXUTCALLBACKMODIFYDEVICESETTINGS)( DXUTDeviceSettings *  pDeviceSettings,  const  D3DCAPS9 *  pCaps,  void *  pUserContext );
 63 typedef HRESULT (CALLBACK  * LPDXUTCALLBACKDEVICECREATED)( IDirect3DDevice9 *  pd3dDevice,  const  D3DSURFACE_DESC *  pBackBufferSurfaceDesc,  void *  pUserContext );
 64 typedef HRESULT (CALLBACK  * LPDXUTCALLBACKDEVICERESET)( IDirect3DDevice9 *  pd3dDevice,  const  D3DSURFACE_DESC *  pBackBufferSurfaceDesc,  void *  pUserContext );
 65 typedef  void     (CALLBACK  * LPDXUTCALLBACKDEVICEDESTROYED)(  void *  pUserContext );
 66 typedef  void     (CALLBACK  * LPDXUTCALLBACKDEVICELOST)(  void *  pUserContext );
 67 typedef  void     (CALLBACK  * LPDXUTCALLBACKFRAMEMOVE)( IDirect3DDevice9 *  pd3dDevice,  double  fTime,  float  fElapsedTime,  void *  pUserContext );
 68 typedef  void     (CALLBACK  * LPDXUTCALLBACKFRAMERENDER)( IDirect3DDevice9 *  pd3dDevice,  double  fTime,  float  fElapsedTime,  void *  pUserContext );
 69 typedef  void     (CALLBACK  * LPDXUTCALLBACKKEYBOARD)( UINT nChar,  bool  bKeyDown,  bool  bAltDown,  void *  pUserContext );
 70 typedef  void     (CALLBACK  * LPDXUTCALLBACKMOUSE)(  bool  bLeftButtonDown,  bool  bRightButtonDown,  bool  bMiddleButtonDown,  bool  bSideButton1Down,  bool  bSideButton2Down,  int  nMouseWheelDelta,  int  xPos,  int  yPos,  void *  pUserContext );
 71 typedef LRESULT (CALLBACK  * LPDXUTCALLBACKMSGPROC)( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,  bool *  pbNoFurtherProcessing,  void *  pUserContext );
 72 typedef  void     (CALLBACK  * LPDXUTCALLBACKTIMER)( UINT idEvent,  void *  pUserContext );
 73
 74 //  Device callbacks
 75 void  DXUTSetCallbackDeviceCreated( LPDXUTCALLBACKDEVICECREATED pCallbackDeviceCreated,  void *  pUserContext  =  NULL );
 76 void  DXUTSetCallbackDeviceReset( LPDXUTCALLBACKDEVICERESET pCallbackDeviceReset,  void *  pUserContext  =  NULL );
 77 void  DXUTSetCallbackDeviceLost( LPDXUTCALLBACKDEVICELOST pCallbackDeviceLost,  void *  pUserContext  =  NULL );
 78 void  DXUTSetCallbackDeviceDestroyed( LPDXUTCALLBACKDEVICEDESTROYED pCallbackDeviceDestroyed,  void *  pUserContext  =  NULL );
 79 void  DXUTSetCallbackDeviceChanging( LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings,  void *  pUserContext  =  NULL );
 80
 81 //  Frame callbacks
 82 void  DXUTSetCallbackFrameMove( LPDXUTCALLBACKFRAMEMOVE pCallbackFrameMove,  void *  pUserContext  =  NULL );
 83 void  DXUTSetCallbackFrameRender( LPDXUTCALLBACKFRAMERENDER pCallbackFrameRender,  void *  pUserContext  =  NULL );
 84
 85 //  Message callbacks
 86 void  DXUTSetCallbackKeyboard( LPDXUTCALLBACKKEYBOARD pCallbackKeyboard,  void *  pUserContext  =  NULL );
 87 void  DXUTSetCallbackMouse( LPDXUTCALLBACKMOUSE pCallbackMouse,  bool  bIncludeMouseMove  =   false void *  pUserContext  =  NULL );
 88 void  DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallbackMsgProc,  void *  pUserContext  =  NULL );
 89
 90
 91 // --------------------------------------------------------------------------------------
 92 //  Initialization
 93 // --------------------------------------------------------------------------------------
 94 HRESULT DXUTInit(  bool  bParseCommandLine  =   true bool  bHandleDefaultHotkeys  =   true bool  bShowMsgBoxOnError  =   true bool  bHandleAltEnter  =   true  );
 95
 96 //  Choose either DXUTCreateWindow or DXUTSetWindow.  If using DXUTSetWindow, consider using DXUTStaticWndProc
 97 HRESULT DXUTCreateWindow(  const  WCHAR *  strWindowTitle  =  L " Direct3D Window "
 98                           HINSTANCE hInstance  =  NULL, HICON hIcon  =  NULL, HMENU hMenu  =  NULL,
 99                            int  x  =  CW_USEDEFAULT,  int  y  =  CW_USEDEFAULT );
100 HRESULT DXUTSetWindow( HWND hWndFocus, HWND hWndDeviceFullScreen, HWND hWndDeviceWindowed,  bool  bHandleMessages  =   true  );
101 LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
102
103 //  Choose either DXUTCreateDevice or DXUTSetDevice or DXUTCreateDeviceFromSettings
104 HRESULT DXUTCreateDevice( UINT AdapterOrdinal  =  D3DADAPTER_DEFAULT,  bool  bWindowed  =   true
105                            int  nSuggestedWidth  =   0 int  nSuggestedHeight  =   0 ,
106                           LPDXUTCALLBACKISDEVICEACCEPTABLE pCallbackIsDeviceAcceptable  =  NULL,
107                           LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings  =  NULL, 
108                            void *  pUserContext  =  NULL );
109 HRESULT DXUTCreateDeviceFromSettings( DXUTDeviceSettings *  pDeviceSettings,  bool  bPreserveInput  =   false bool  bClipWindowToSingleAdapter  =   true  );
110 HRESULT DXUTSetDevice( IDirect3DDevice9 *  pd3dDevice );
111
112 //  Choose either DXUTMainLoop or implement your own main loop 
113 HRESULT DXUTMainLoop( HACCEL hAccel  =  NULL );
114
115 //  If not using DXUTMainLoop consider using DXUTRender3DEnvironment
116 void  DXUTRender3DEnvironment(); 
117
118
119 // --------------------------------------------------------------------------------------
120 //  Finding valid device settings
121 // --------------------------------------------------------------------------------------
122 enum  DXUT_MATCH_TYPE
123 {
124    DXUTMT_IGNORE_INPUT = 0,  // Use the closest valid value to a default 
125    DXUTMT_PRESERVE_INPUT,    // Use input without change, but may cause no valid device to be found
126    DXUTMT_CLOSEST_TO_INPUT   // Use the closest valid value to the input 
127}
;
128
129 struct  DXUTMatchOptions
130 {
131    DXUT_MATCH_TYPE eAdapterOrdinal;
132    DXUT_MATCH_TYPE eDeviceType;
133    DXUT_MATCH_TYPE eWindowed;
134    DXUT_MATCH_TYPE eAdapterFormat;
135    DXUT_MATCH_TYPE eVertexProcessing;
136    DXUT_MATCH_TYPE eResolution;
137    DXUT_MATCH_TYPE eBackBufferFormat;
138    DXUT_MATCH_TYPE eBackBufferCount;
139    DXUT_MATCH_TYPE eMultiSample;
140    DXUT_MATCH_TYPE eSwapEffect;
141    DXUT_MATCH_TYPE eDepthFormat;
142    DXUT_MATCH_TYPE eStencilFormat;
143    DXUT_MATCH_TYPE ePresentFlags;
144    DXUT_MATCH_TYPE eRefreshRate;
145    DXUT_MATCH_TYPE ePresentInterval;
146}
;
147
148 HRESULT DXUTFindValidDeviceSettings( DXUTDeviceSettings *  pOut, DXUTDeviceSettings *  pIn  =  NULL, DXUTMatchOptions *  pMatchOptions  =  NULL );
149
150
151 // --------------------------------------------------------------------------------------
152 //  Common Tasks 
153 // --------------------------------------------------------------------------------------
154 void     DXUTSetCursorSettings(  bool  bShowCursorWhenFullScreen,  bool  bClipCursorWhenFullScreen );
155 void     DXUTSetMultimonSettings(  bool  bAutoChangeAdapter );
156 void     DXUTSetShortcutKeySettings(  bool  bAllowWhenFullscreen  =   false bool  bAllowWhenWindowed  =   true  );  //  Controls the Windows key, and accessibility shortcut keys
157 void     DXUTSetWindowSettings(  bool  bCallDefWindowProc  =   true  );
158 void     DXUTSetConstantFrameTime(  bool  bConstantFrameTime,  float  fTimePerFrame  =   0.0163f  );
159 HRESULT DXUTSetTimer( LPDXUTCALLBACKTIMER pCallbackTimer,  float  fTimeoutInSecs  =   1.0f , UINT *  pnIDEvent  =  NULL,  void *  pCallbackUserContext  =  NULL );
160 HRESULT DXUTKillTimer( UINT nIDEvent );
161 HRESULT DXUTToggleFullScreen();
162 HRESULT DXUTToggleREF();
163 void     DXUTPause(  bool  bPauseTime,  bool  bPauseRendering );
164 void     DXUTResetFrameworkState();
165 void     DXUTShutdown(  int  nExitCode  =   0  );
166
167
168 // --------------------------------------------------------------------------------------
169 //  State Retrieval  
170 // --------------------------------------------------------------------------------------
171 IDirect3D9 *              DXUTGetD3DObject();  //  Does not addref unlike typical Get* APIs
172 IDirect3DDevice9 *        DXUTGetD3DDevice();  //  Does not addref unlike typical Get* APIs
173 DXUTDeviceSettings      DXUTGetDeviceSettings(); 
174 D3DPRESENT_PARAMETERS   DXUTGetPresentParameters();
175 const  D3DSURFACE_DESC *   DXUTGetBackBufferSurfaceDesc();
176 const  D3DCAPS9 *          DXUTGetDeviceCaps();
177 HINSTANCE               DXUTGetHINSTANCE();
178 HWND                    DXUTGetHWND();
179 HWND                    DXUTGetHWNDFocus();
180 HWND                    DXUTGetHWNDDeviceFullScreen();
181 HWND                    DXUTGetHWNDDeviceWindowed();
182 RECT                    DXUTGetWindowClientRect();
183 RECT                    DXUTGetWindowClientRectAtModeChange();  //  Useful for returning to windowed mode with the same resolution as before toggle to full screen mode
184 RECT                    DXUTGetFullsceenClientRectAtModeChange();  //  Useful for returning to full screen mode with the same resolution as before toggle to windowed mode
185 double                   DXUTGetTime();
186 float                    DXUTGetElapsedTime();
187 bool                     DXUTIsWindowed();
188 float                    DXUTGetFPS();
189 LPCWSTR                 DXUTGetWindowTitle();
190 LPCWSTR                 DXUTGetFrameStats(  bool  bIncludeFPS  =   false  );
191 LPCWSTR                 DXUTGetDeviceStats();
192 bool                     DXUTIsRenderingPaused();
193 bool                     DXUTIsTimePaused();
194 bool                     DXUTIsActive();
195 int                      DXUTGetExitCode();
196 bool                     DXUTGetShowMsgBoxOnError();
197 bool                     DXUTGetHandleDefaultHotkeys();
198 bool                     DXUTIsKeyDown( BYTE vKey );  //  Pass a virtual-key code, ex. VK_F1, 'A', VK_RETURN, VK_LSHIFT, etc
199 bool                     DXUTIsMouseButtonDown( BYTE vButton );  //  Pass a virtual-key code: VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_XBUTTON1, VK_XBUTTON2
200 bool                     DXUTGetAutomation();   //  Returns true if -automation parameter is used to launch the app
201
202 #endif
203
204
205
206
207

千万别被代码吓住。对于不需要深入理解的我们来说,大多数都是不需要关心的。如果您需要深入理解的话,我非常抱歉我帮不上忙。在CPPBLOG里面有个标题为“天行健 君子当自强不息”的一个BLOG里面有专门详细解析DXUT的文章。链接请自己百度一下吧。

于是我们来关注一下这个优美的框架。它定义了很多回调函数,以及留了许多接口。
我们需要关心的是这几个:
DXUTSetCallbackDeviceCreated
      为框架挂接上Direct3D设备创建后的回调函数
DXUTSetCallbackDeviceReset
      挂接Direct3D设备重置后的回调函数
DXUTSetCallbackDeviceLost
      挂接Direct3D设备丢失后的回调函数
DXUTSetCallbackDeviceDestroyed
      挂接Direct3D设备销毁后的回调函数
DXUTSetCallbackFrameRender
      挂接每帧渲染场景时的回调函数
DXUTSetCallbackFrameMove
      挂接每帧渲染前需要更新场景时的回调函数
DXUTSetCallbackMouse
      挂接鼠标事件的回调函数
DXUTSetCallbackKeyboard
      挂接键盘事件的回调函数

于是我们打开EmptyProject.cpp
看着WinMain函数
 1 // --------------------------------------------------------------------------------------
 2 //  Initialize everything and go into a render loop
 3 // --------------------------------------------------------------------------------------
 4 INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR,  int  )
 5 {
 6
 7    //设置回调函数
 8    DXUTSetCallbackDeviceCreated( OnCreateDevice );
 9    DXUTSetCallbackDeviceReset( OnResetDevice );
10    DXUTSetCallbackDeviceLost( OnLostDevice );
11    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
12    DXUTSetCallbackMsgProc( MsgProc );
13    DXUTSetCallbackFrameRender( OnFrameRender );
14    DXUTSetCallbackFrameMove( OnFrameMove );
15    DXUTSetCallbackMouse( OnMouseEvent ,true);//第二个参数是指是否包含鼠标移动事件
16    DXUTSetCallbackKeyboard( OnKeyEvent );
17   
18    // 这里写在程序底层初始化前需要的代码
19
20
21    // 初始化DXUT、程序窗口、Direct3D设备
22    DXUTInit( truefalsetrue ); // Parse the command line, handle the default hotkeys, and show msgboxes
23    DXUTSetCursorSettings( truetrue ); // Show the cursor and clip it when in full screen
24    DXUTCreateWindow( “EmptyProject”);//窗口标题
25    DXUTCreateDevice( D3DADAPTER_DEFAULT, true640480, IsDeviceAcceptable, ModifyDeviceSettings );//创建设备
26    // 开始DXUT主循环
27    DXUTMainLoop();
28
29    // 这里写清理底层的代码
30    return DXUTGetExitCode();
31}

看见了么,在这里挂接了需要的回调函数,不如我们将他们叫做“事件”,这样更好理解。
自己看一下就能明白那些代码的意思了

OnCreateDevice OnResetDevice OnLostDevice OnDestroyDevice MSgProc OnFrameRender OnFrameMove OnMouseEvent OnKetEvent
这些都是已经定义好的CALLBACK,我们的框架将从DXUTMainLoop()这里开始

简单来说,我们需要了解的就只有这些事件的触发顺序了。
HRESULT CALLBACK OnCreateDevice( Device* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
      这个事件在设备创建完毕时就会触发,最先触发的东西。第一个参数是创建后的设备,第二个是设备的表面参数。pUserContext不需要关心,因此不讨论。下同。

HRESULT CALLBACK OnResetDevice( Device* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
      这个事件在设备重置的时候会触发。那么什么叫做设备重置呢?等下会和设备丢失一起说。第一个参数是重置后的设备,第二个是重置后设备的表面参数。

void CALLBACK OnLostDevice( void* pUserContext )
      这个事件在设备丢失的时候会触发。举个简单的例子,把窗口最小化的时候设备会丢失,而恢复的时候设备会重置。从全屏换为窗口的时候也会丢失并且重置。大概就是改变窗口的大小、位置、是否全屏的时候,会导致设备丢失,随后恢复的时候会重置。这两个事件的触发就是为了在窗口改变的时候重新设置一些参数,让画面适应当前窗口设置。

void CALLBACK OnFrameMove( Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
      这个事件在每帧绘制前会触发,为的是更新场景信息。第一个参数是传入的Direct3D设备,第二个参数是从第一次触发这个事件到现在为止的时间,第三个参数是这次触发此事件距上次的时间。

void CALLBACK OnFrameRender( Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
      这个事件在每帧渲染屏幕的时候触发。参数意义和OnFrameMove一样。

void CALLBACK OnMouseEvent(bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, bool bSideButton1Down,
         bool bSideButton2Down, int nMouseWheelDelta, int xPos, int yPos, void* pUserContext)
      这个事件在鼠标有动作的时候触发。bLeftButtonDown:左键是否按下,bRighButtonDown:右键是否按下,bMiddleButtonDown:中间键是否按下,bSidebutton1Down:边键1是否按下,bSideButton2Down:边键2是否按下,nMouseWheelDelta:滚轮的滚动值,向手指指的方向滚动一格是-120,反之则为120,xPos:在窗口中的X坐标,yPos:在窗口中的Y坐标。

void CALLBACK OnKeyEvent( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
      这个事件在键盘有动作的时候触发。nChar:发生动作的键,bKeyDown:发生动作的键是被按下还是被抬起,bAltDown:Alt键是否同时被按下。



这些了解了后,你就可以开始干事儿了。你可以把上面的回调函数都当做事件来看,而且是多线程的,这样更方便。
总结一下事件顺序:
                                    DXUT工作模式的简单解析-底层框架_第1张图片

如上图所示,DXUT的工作顺序大概就是这样。对于不需要深入了解DXUT工作细节来说,已经差不多了。


现在应该对框架的工作机制有一定得认识了,这篇简单的文章也就这样结束了。下一篇还是预告了吧,是在DXUT框架下,关于2D方面的东西。

顺便说一些DXUT.h中比较实用的接口
163行:void    DXUTPause( bool bPauseTime, bool bPauseRendering ); 让OnFrameMove和OnFrameRender事件暂停或恢复触发,第一个参数为是否停止计时,第二个为是否停止绘制。
178行:HWND DXUTGetHWND();获取目前窗口句柄
182行:RECT DXUTGetWindowClientRect();
188行:float DXUTGetFPS();获取当前的FPS(Frame Per second 每秒帧数)
差不多就这些。

以上的代码在EmptyProject里面全部都有,这篇文章只是帮还没有接触过的新手入门而已。请勿鄙视,有任何意见和建议请提出,谢谢了。

现在已经傻瓜式地把框架搭建好了,并且可以简单使用了。那么下一步该干嘛?干事儿呗。
下一篇:Direct3D中的简单2D运用。有空再写了,先预告了吧。