以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- Direct3D程序设计基础 (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=69839) |
-- 作者:卷积内核 -- 发布时间:11/26/2008 8:24:00 AM -- Direct3D程序设计基础 Direct3D对象 Microsoft Direct3D的一种实现方式是通过组件对象模型(Component Object Model, COM)及其接口实现的,在用C++语言和COM接口方式开发的程序中可以直接访问这些接口和对象。Direct3D对象是Direct3D程序中需要创建的第一个对象,也是需要最后一个释放的对象,这里所说的对象是指COM对象。通过Direct3D对象,可以枚举和检索Direct3D设备,这样应用程序就可以在不需要创建设备对象的前提下选择Direct3D渲染设备。 在用C++语言编写Direct3D程序时,需要先获取一个指向IDirect3D9接口的指针,从而可以通过该接口调用Direct3D对象的功能。
创建Direct3D设备对象 创建Direct3D设备对象时,需要先创建Direct3D对象,然后再调用Direct3D对象的接口函数IDirect3D9::CreateDevice创建Direct3D设备对象。通过同一个Direct3D对象创建的所有Direct3D设备对象共享相同的物理资源(显卡)。因为共享同一硬件,所以如果通过一个Direct3D对象创建多个Direct3D渲染设备对象会明显降低系统性能。 在创建Direct3D设备对象之前,还需要先初始化D3DPRESENT_PARAMETERS结构,该结构用于创建Direct3D设备对象。D3DPRESENT_PARAMETERS结构定义了Direct3D设备对象的相关信息,而这些信息将会影响Direct3D设备的显示方法。该结构的定义如下: Describes the presentation parameters. typedef struct D3DPRESENT_PARAMETERS { UINT BackBufferWidth, BackBufferHeight; D3DFORMAT BackBufferFormat; UINT BackBufferCount; D3DMULTISAMPLE_TYPE MultiSampleType; DWORD MultiSampleQuality; D3DSWAPEFFECT SwapEffect; HWND hDeviceWindow; BOOL Windowed; BOOL EnableAutoDepthStencil; D3DFORMAT AutoDepthStencilFormat; DWORD Flags; UINT FullScreen_RefreshRateInHz; UINT PresentationInterval;} D3DPRESENT_PARAMETERS, *LPD3DPRESENT_PARAMETERS; For windowed applications, the back buffer format no longer needs to match the display-mode format because color conversion can now be done by the hardware (if the hardware supports color conversion). The set of possible back buffer formats is constrained, but the runtime will allow any valid back buffer format to be presented to any desktop format. (There is the additional requirement that the device be operable in the desktop mode; devices typically do not operate in 8 bits per pixel modes.) Full-screen applications cannot do color conversion. BackBufferCount MultiSampleType D3DSWAPEFFECT_DISCARD will be enforced in the debug runtime by filling any buffer with noise after it is presented. hDeviceWindow For a windowed-mode application, this handle will be the default target window for IDirect3DDevice9::Present. If this handle is NULL, the focus window will be taken. Windowed AutoDepthStencilFormat |
-- 作者:卷积内核 -- 发布时间:11/26/2008 8:25:00 AM -- Direct3D程序基本结构 虽然Direct3D功能非常强大,但是Direct3D程序的基本结构非常简单清晰,它主要有5个步骤: (1)创建一个Windows窗口。 (2)初始化Direct3D,包括创建Direct3D对象、Direct3D设备对象以及要渲染的图形对象。 (3)消息循环。 (4)渲染图形。 (5)清除在初始化时创建的所有COM对象,退出程序。 其中消息循环和渲染图形不断进行,如果程序有消息需要处理,则先处理消息,然后再渲染图形;如果没有消息处理,则一直不停地渲染图形,直到退出Direct3D程序。
最简单的Direct3D程序 #include <d3d9.h> #define CLASS_NAME "GameApp" #define release_com(p) { if(p) { (p)->Release(); (p) = NULL; } } IDirect3D9* g_d3d; bool init_d3d(HWND hwnd) if(g_d3d == NULL) D3DPRESENT_PARAMETERS d3dpp; d3dpp.Windowed = TRUE; if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, return true; void cleanup() void render() g_device->BeginScene(); // render game scene here g_device->EndScene(); g_device->Present(NULL, NULL, NULL, NULL); LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_DESTROY: return DefWindowProc(hwnd, msg, wParam, lParam); int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT) wc.cbSize = sizeof(WNDCLASSEX); if(! RegisterClassEx(&wc)) HWND hwnd = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200, 100, 600, 500, if(hwnd == NULL) if(init_d3d(hwnd)) MSG msg; while(msg.message != WM_QUIT) cleanup(); UnregisterClass(CLASS_NAME, wc.hInstance); return 0; |
-- 作者:卷积内核 -- 发布时间:11/26/2008 8:25:00 AM -- 创建窗口 Direct3D是基于Microsoft Windows的图形开发接口,它的使用必须建立在Windows窗口的基础上,这就需要创建一个窗口,而创建窗口首先需要注册一个窗口类。示例程序中注册窗口类并根据窗口类创建窗口的代码如下: WNDCLASSEX wc; |
-- 作者:卷积内核 -- 发布时间:11/26/2008 8:25:00 AM -- 初始化Direct3D 创建了可供绘制图形的窗口后,在使用Direct3D渲染图形前,还需要进行与Direct3D相关的初始化操作,主要包括创建Direct3D对象并获取其接口指针,通过Direct3D对象创建Direct3D设备对象。 bool init_d3d(HWND hwnd){ g_d3d = Direct3DCreate9(D3D_SDK_VERSION); 要创建Direct3D设备,可调用IDirect3D9::CreateDevice()函数。 Creates a device to represent the display adapter. HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresentationParameters, IDirect3DDevice9 ** ppReturnedDeviceInterface); [in, out] For Windows 2000 and Windows XP, the full-screen device display refresh rate is set in the following order: pPresentationParameters is both an input and an output parameter. Calling this method may change several members including: If BackBufferCount, BackBufferWidth, and BackBufferHeight are 0 before the method is called, they will be changed when the method returns. ppReturnedDeviceInterface Remarks When you create a Direct3D device, you supply two different window parameters: a focus window (hFocusWindow) and a device window (the hDeviceWindow in D3DPRESENT_PARAMETERS). The purpose of each window is: The focus window alerts Direct3D when an application switches from foreground mode to background mode (via Alt-Tab, a mouse click, or some other method). A single focus window is shared by each device created by an application. Note that D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, and D3DCREATE_SOFTWARE_VERTEXPROCESSING are mutually exclusive flags, and at least one of these vertex processing flags must be specified when calling this method. Back buffers created as part of the device are only lockable if D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is specified in the presentation parameters. (Multisampled back buffers and depth surfaces are never lockable.) The methods IDirect3DDevice9::Reset, IUnknown, and IDirect3DDevice9::TestCooperativeLevel must be called from the same thread that used this method to create a device. D3DFMT_UNKNOWN can be specified for the windowed mode back buffer format when calling IDirect3D9::CreateDevice, IDirect3DDevice9::Reset, and IDirect3DDevice9::CreateAdditionalSwapChain. This means the application does not have to query the current desktop format before calling IDirect3D9::CreateDevice for windowed mode. For full-screen mode, the back buffer format must be specified. If you attempt to create a device on a 0x0 sized window, IDirect3D9::CreateDevice will fail.
|
-- 作者:卷积内核 -- 发布时间:11/26/2008 8:26:00 AM -- 消息循环 在Direct3D中,渲染图形通常是在消息循环中进行的: MSG msg; ZeroMemory(&msg, sizeof(msg)); 特别需要注意的是,在消息循环中使用的是PeekMessage()函数,而不是GetMessage()函数。函数PeekMessage()和GetMessage()的功能大体相同,作用都是从消息队列中取一条消息出来,唯一不同的是,每当GetMessage()发现消息队列中没有消息时,过门不入,而PeekMessage()发现消息队列中没有消息时,会取回系统控制权,让程序在此停留一段时间,应用程序就是在这时候处理render()函数。也就是说,渲染函数render()都是在程序运行时的空闲时间调用的。 注意理解PeekMessage()和GetMessage()运行机制的区别,这对理解Direct3D程序中如何实现动画是很关键的。 |
-- 作者:卷积内核 -- 发布时间:11/26/2008 8:26:00 AM -- 渲染图形 使用Direct3D绘制三维图形和使用GDI绘制二维图形的方法非常类似,Direct3D程序中的Direct3D设备对象相当于GDI程序中的hdc(设备描述表),使用 GDI绘制图形前,通常需要先利用hdc进行相关设置,然后通过hdc进行绘图。同样在Direct3D程序中通常先通过Direct3D设备接口进行相关的渲染设备设置,然后再渲染图形。而且所有的渲染图形操作必须在函数BeginScene()和EndScene()之间进行。 void render(){ g_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_X#2d32aa, 1.0f, 0); Clears one or more surfaces such as a render target, multiple render targets, a stencil buffer, and a depth buffer. HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil); Remarks IDirect3DDevice9::Clear will fail if you: Try to clear either the depth buffer or the stencil buffer of a render target that does not have an attached depth buffer. 在绘制图形开始之前,必须先调用函数IDirect3DDevice9::BeginScene()函数,通知Direct3D设备开始绘制图形(又称渲染),否则Direct3D程序就会出错返回;渲染程序完成后,也必须调用函数IDirect3DDevice9::EndScene()通知Direct3D设备结束渲染。而且这两个函数必须成对出现,不允许嵌套和交错的情况发生。任何Direct3D渲染函数都必须在函数BeginScene()和函数EndScene()的中间出现。 Direct3D在后台缓冲区进行图形绘制操作,当所有的图形绘制操作结束之后,调用函数IDirect3DDevice9::Present()将在后台缓冲区绘制的内容提交到前台显示,这样绘制的图形就显示在屏幕上了。 Presents the contents of the next buffer in the sequence of back buffers owned by the device. HRESULT Present( CONST RECT * pSourceRect, CONST RECT * pDestRect, HWND hDestWindowOverride, CONST RGNDATA * pDirtyRegion); Remarks IDirect3DDevice9::Present will fail, returning D3DERR_INVALIDCALL, if called between BeginScene and EndScene pairs unless the render target is not the current render target (such as the back buffer you get from creating an additional swap chain). This is a new behavior for Direct3D 9.
|
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
125.000ms |