天天看点

Direct3D学习笔记:direct3d的基本知识和初始化

1.表面(Surface)

typedef struct D3DSURFACE_DESC {

  D3DFORMAT           Format;

  D3DRESOURCETYPE     Type;

  DWORD               Usage;

  D3DPOOL             Pool;

  D3DMULTISAMPLE_TYPE MultiSampleType;

  DWORD               MultiSampleQuality;

  UINT                Width;

  UINT                Height;

} D3DSURFACE_DESC, *LPD3DSURFACE_DESC;

表面是像素点阵,在d3d中存储2d图形数据。Surface中每一行的数据不纯是像素颜色,还会有一个缓冲区,Pitch就是一整行的数据的总长度

//header:D3D9Types.h

typedef struct D3DLOCKED_RECT {

       INT  Pitch;//Number of bytes in one row of the surface.

       void *pBits;//pBits will be appropriately offset from the start of the surface.

} D3DLOCKED_RECT, *LPD3DLOCKED_RECT;

接口:

IDirect3DSurface9

Method Description
GetDesc Retrieves a description of the surface.
LockRect Locks a rectangle on a surface.
UnlockRect Unlocks a rectangle on a surface.

LockRect:通过这个方法可以获得一个指向表面内存的指针,从而进行读写操作

//header: D3D9.h

HRESULT LockRect(

  [out]  D3DLOCKED_RECT *pLockedRect,

  [in]   const RECT *pRect,

  [in]   DWORD Flags

);

UnlockRect :通过这个方法来解锁

GetDesc :通过填充D3DLOCKED_RECT结构来返回表面的信息。

HRESULT GetDesc(

  [out]  D3DSURFACE_DESC *pDesc

);

1.1 像素格式

由D3DFORMAT来决定

typedef enum _D3DFORMAT {

...  (values)

} D3DFORMAT

Direct3D学习笔记:direct3d的基本知识和初始化
Direct3D学习笔记:direct3d的基本知识和初始化

1.3 交换链和页面切换,当Front Buffer的内容显示器还没有显示时,就先render to Back Buffer,当front Buffer 的内容显示出来后,front Buffer 就相当于原来的back buffer,back buffer就变为原来的front buffer这个过程称为presenting

1.Render to back buffer

2.Present to back buffer

3.Goto(1)

1.4 设备能力 :通过D3DCAPS9这个结构来判断。

2.初始化directx3d

1.获得一个IDirect3D9接口指针。这个接口用于获得物理设备的信息和创建一个IDirect3DDevice9接口,它是一个代表我们显示3D图形的物理设备的C++对象。

2.检查设备能力(D3DCAPS9),搞清楚主显卡是否支持硬件顶点处理。我们需要知道假如它能支持,我们就能创建IDirect3DDevice9接口。

3.初始化一个D3DPRESENT_PARAMETERS结构实例,这个结构包含了许多数据成员允许我们指定将要创建的IDirect3DDevice9接口的特性。

Direct3D学习笔记:direct3d的基本知识和初始化
Direct3D学习笔记:direct3d的基本知识和初始化
Direct3D学习笔记:direct3d的基本知识和初始化

4.创建一个基于已经初始化好的D3DPRESENT_PARAMETERS结构的IDirect3DDevice9对象。它是一个代表我们显示3D图形的物理设备的C++对象。

HRESULT CreateDevice(

  [in]           UINT Adapter,//指定要对象显示的物理显示设备

  [in]           D3DDEVTYPE DeviceType,//设备类型

  [in]           HWND hFocusWindow,//窗口句柄

  [in]           DWORD BehaviorFlags,//D3DCREATE_HARDWARE_VERTEXPROCESSING或是D3DCREATE_SOFTWARE_VERTEXPROCESSING

  [in, out]      D3DPRESENT_PARAMETERS *pPresentationParameters,//要填充的D3DPRESENT_PARAMETERS实例

  [out, retval]  IDirect3DDevice9 **ppReturnedDeviceInterface//返回创建的设备

);

//清除

//IDirect3DDevice9::Clear Method

//Clears one or more surfaces such as a render target, multiple render targets, a stencil buffer, and a depth buffer.

HRESULT Clear(

  //清除表面的个数

  [in]  DWORD Count,

  //将要清除的矩形数组,这样清除屏幕的某个部分。

  [in]  const D3DRECT *pRects,

  //指定在哪些表面上执行清除表面的操作

  //D3DCLEAR_STENCIL Clear the stencil buffer.

  //D3DCLEAR_TARGET 目标表面,通常为后备表面

  //D3DCLEAR_ZBUFFER Clear the depth buffer.

  [in]  DWORD Flags,

  //用什么颜色填充清除的表面

  [in]  D3DCOLOR Color,

  //设置深度缓冲的值

  [in]  float Z,

  //设置模板缓冲的值

  [in]  DWORD Stencil

);

一般屏幕被填充后要调用present方法进行后备表面的交换。

         if( Device ) // Only use Device methods if we have a valid device.

         {

                   // Instruct the device to set each pixel on the back buffer black -

                   // D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on

                   // the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.

                   Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);

                   // Swap the back and front buffers.

                   Device->Present(0, 0, 0, 0);

         }

Direct3D学习笔记:direct3d的基本知识和初始化

初始化代码:

1.

//

#include"dxdhear.h"

// Globals

//

IDirect3DDevice9* Device = 0;

//

// Framework Functions

//

bool Setup()

{

         // Nothing to setup in this sample.

         return true;

}

void Cleanup()

{

         // Nothing to cleanup in this sample.

}

bool Display(float timeDelta)

{

         if( Device ) // Only use Device methods if we have a valid device.

         {

                   // Instruct the device to set each pixel on the back buffer black -

                   // D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on

                   // the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.

                   Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);

                   // Swap the back and front buffers.

                   Device->Present(0, 0, 0, 0);

         }

         return true;

}

//

// WndProc

//

LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

         switch( msg )

         {

         case WM_DESTROY:

                   ::PostQuitMessage(0);

                   break;

         case WM_KEYDOWN:

                   if( wParam == VK_ESCAPE )

                            ::DestroyWindow(hwnd);

                   break;

         }

         return ::DefWindowProc(hwnd, msg, wParam, lParam);

}

//

// WinMain

//

int WINAPI WinMain(HINSTANCE hinstance,

                                        HINSTANCE prevInstance,

                                        PSTR cmdLine,

                                        int showCmd)

{

         if(!d3d::InitD3D(hinstance,

                   640, 480, true, D3DDEVTYPE_HAL, &Device))

         {

                   ::MessageBox(0, "InitD3D() - FAILED", 0, 0);

                   return 0;

         }

         if(!Setup())

         {

                   ::MessageBox(0, "Setup() - FAILED", 0, 0);

                   return 0;

         }

         d3d::MsgLoop( Display );

         Cleanup();

         Device->Release();

         return 0;

}

2.

#include"dxdhear.h"

bool d3d::InitD3D(

         HINSTANCE hInstance,

         int width, int height,

         bool windowed,

         D3DDEVTYPE deviceType,

         IDirect3DDevice9** device)

{

         //

         // Create the main application window.

         //

         WNDCLASS wc;

         wc.style         = CS_HREDRAW | CS_VREDRAW;

         wc.lpfnWndProc   = (WNDPROC)d3d::WndProc;

         wc.cbClsExtra    = 0;

         wc.cbWndExtra    = 0;

         wc.hInstance     = hInstance;

         wc.hIcon         = LoadIcon(0, IDI_APPLICATION);

         wc.hCursor       = LoadCursor(0, IDC_ARROW);

         wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

         wc.lpszMenuName  = 0;

         wc.lpszClassName = "Direct3D9App";

         if( !RegisterClass(&wc) )

         {

                   ::MessageBox(0, "RegisterClass() - FAILED", 0, 0);

                   return false;

         }

         HWND hwnd = 0;

         hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App",

                  WS_EX_TOPMOST,

                   0, 0, width, height,

                   0 , 0 , hInstance, 0 );

         if( !hwnd )

         {

                   ::MessageBox(0, "CreateWindow() - FAILED", 0, 0);

                   return false;

         }

         ::ShowWindow(hwnd, SW_SHOW);

         ::UpdateWindow(hwnd);

         //

         // Init D3D:

         //

         HRESULT hr = 0;

         // Step 1: Create the IDirect3D9 object.

         IDirect3D9* d3d9 = 0;

    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

    if( !d3d9 )

         {

                   ::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);

                   return false;

         }

         // Step 2: Check for hardware vp.

         D3DCAPS9 caps;

         d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

         int vp = 0;

         if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )

                   vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;

         else

                   vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

         // Step 3: Fill out the D3DPRESENT_PARAMETERS structure.

         D3DPRESENT_PARAMETERS d3dpp;

         d3dpp.BackBufferWidth            = width;

         d3dpp.BackBufferHeight           = height;

         d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;

         d3dpp.BackBufferCount            = 1;

         d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;

         d3dpp.MultiSampleQuality         = 0;

         d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;

         d3dpp.hDeviceWindow              = hwnd;

         d3dpp.Windowed                   = windowed;

         d3dpp.EnableAutoDepthStencil     = true;

         d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;

         d3dpp.Flags                      = 0;

         d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

         d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

         // Step 4: Create the device.

         hr = d3d9->CreateDevice(

                   D3DADAPTER_DEFAULT, // primary adapter

                   deviceType,         // device type

                   hwnd,               // window associated with device

                   vp,                 // vertex processing

             &d3dpp,             // present parameters

             device);            // return created device

         if( FAILED(hr) )

         {

                   // try again using a 16-bit depth buffer

                   d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

                  hr = d3d9->CreateDevice(

                            D3DADAPTER_DEFAULT,

                            deviceType,

                            hwnd,

                            vp,

                            &d3dpp,

                            device);

                   if( FAILED(hr) )

                   {

                            d3d9->Release(); // done with d3d9 object

                            ::MessageBox(0, "CreateDevice() - FAILED", 0, 0);

                            return false;

                   }

         }

         d3d9->Release(); // done with d3d9 object

         return true;

}

int d3d::MsgLoop( bool (*ptr_display)(float timeDelta) )

{

         MSG msg;

         ::ZeroMemory(&msg, sizeof(MSG));

         static float lastTime = (float)timeGetTime();

         while(msg.message != WM_QUIT)

         {

                   if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))

                   {

                            ::TranslateMessage(&msg);

                            ::DispatchMessage(&msg);

                   }

                   else

        {

                            float currTime  = (float)timeGetTime();

                            float timeDelta = (currTime - lastTime)*0.001f;

                            ptr_display(timeDelta);

                            lastTime = currTime;

        }

    }

    return msg.wParam;

}

3.

#ifndef dxdhear_H_

#define dxdhear_H_

#include<d3dx9.h>

#include<string>

#include<comdef.h>

namespace d3d

{

         bool InitD3D

                   (

                   HINSTANCE hInstance,//[in]typedef HANDLE HINSTANCE;Handle to an instance

                   int width,//[in]

                   int height,//[in]

                   bool windowed,//[in] full screen(false) or windowed(true)

                   D3DDEVTYPE deviceType,//[in]设备类型

                   IDirect3DDevice9** device//[out]创建的设备

                   );

         int  MsgLoop(bool (*ptr_display)(float timeDelta));//消息循环

         //回调函数

         LRESULT CALLBACK WndProc(

                   HWND hwnd,

                   UINT msg,

                   WPARAM wparam,

                   LPARAM lparam

                   );

         template<class T>

         void Release(T t)

         {

                   if(t)

                   {

                            t->Release();

                            t=0;

                   }

         }

         template<class T>

         void Delete(T t)

         {

                   if(t)

                   {

                            delete t;

                            t=0;

                   }

         }

}

#endif

继续阅读