D3D学习笔记(我的第一个D3D程序)

来源:互联网 发布:网络悬疑推理电视剧 编辑:程序博客网 时间:2024/05/22 01:49

原文出处点击打开链接

 

        首先申明这个程序是根据翁云兵翻译的<<3D游戏程序设计入门(DirectX® 9.0>>修改的;

下面那个程序什么都没有完成,就是创建一个窗口.但是麻雀虽小,里面的所有的D3D基本功能都包含了.

不怕笑话,这个程序我研究了2

把这个坎过去了就好办了,接下来要学的东西就应该轻松点了.起码理解起来没什么问题了.

 

        利用D3D做程序无非是两步:

        1)创建设备

       2)利用创建的设备来完成要做的任务,然后释放设备

 

        还有下面的程序主要是研究这样创建设备的,至于利用这样利用设备是下次文章的主题了;

-----------------------------------------------------------------------------------------------------------------------

******test.cpp


#include"d3dUtility.h"


//全局变量,定义设备

IDirect3DDevice9* Device = 0;

//在这个程序中,我们不需要使用任何资源或触发任何事件,所以这两个函数都为空

bool Setup()

{

      return true;

}

void Cleanup()

{

}

 

          //HRESULT IDirect3DDevice9::Clear(DWORD Count,const D3DRECT* pRects,DWORD Flags,D3DCOLOR Color

                                                                           ,float Z,DWORD Stencil);

         //IDirect3DDevice9::Clear函数的声名

         /*下面是对CLEAR的各个参数的说明

                     Count——pRects组中的矩形的个数;

                     pRects——将要清除的屏幕矩形的数组,这使我们可以清除屏幕的某一部分;

                     Flags——指定在哪些表面上执行清除表面的操作;

                                      D3DCLEAR_TARGET——目的表面,通常为后备表面;

                                      D3DCLEAR_ZBUFFER——深度缓冲;

                                      D3DCLEAR_STENCIL——模版缓冲;

                     Color——使用什么颜色填充清除的表面;

                    Z——设置深度缓冲的值;

                     Stencil——设置模版缓冲的值*/

         //屏幕被填充后,要调用IDirecte3DDevice9::Present方法进行后备表面的交换

bool Display(float timeDelta)

{

      if( Device )

       {

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

              Device->Present(0, 0, 0, 0);// present backbuffer

       }

      return true;

} 

LRESULT CALLBACKd3d::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);     

}


int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE prevInstance,PSTR cmdLine,int showCmd)

{

      //初始化主显示窗口和Direct3D

      if(!d3d::InitD3D(hinstance, 800, 600,true, D3DDEVTYPE_HAL, &Device)      

       {

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

             return 0;

       }

      //调用Setup进行程序的准备工作

      if(!Setup())

       {

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

             return 0;

       }

      //使用Display函数作为参数进入消息循环

      d3d::EnterMsgLoop( Display );

      //清除应用程序最后释放IDirecte3DDevice9对象

       Cleanup();

       Device->Release();

      return 0;

}

--------------------------------------------------------------------------------------------------------------------------------

***********d3dUtility.h


#ifndef__d3dUtilityH__

#define__d3dUtilityH__


#include<d3dx9.h>

#include<string>


namespaced3d

{

      bool InitD3D(

              HINSTANCE hInstance,      // [in] Application instance.

             int width, int height,    // [in] Backbuffer dimensions.

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

              D3DDEVTYPE deviceType,    // [in] HAL or REF

              IDirect3DDevice9** device);// [out]The created device.


      int EnterMsgLoop ( 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 // __d3dUtilityH__

 

#include"d3dUtility.h"

 

//InitD3D主要功能是注册和创建主窗口,检查设备的兼容性,决定是用硬件支持方式还是软件支持方式

//

boold3d::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(BLACK_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/*parent hwnd*/,

              0/* menu */,

              hInstance,

              0/*extra*/);


      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.

       //1获得一个IDirect3D9接口指针。

      //这个接口用于获得物理设备的信息和创建一个IDirect3DDevice9接口,

      //它是一个代表我们显示3D图形的物理设备的C++对象。

       IDirect3D9* d3d9 = 0;

       d3d9 = Direct3DCreate9(D3D_SDK_VERSION);


       if( !d3d9 )

       {

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

             return false;

       }

       // Step 2: Check for hardware vp.

      //检查硬件是否支持,要是不支持那么使用软件方式,并且得到硬件信息

      //deviceType 来记录DeviceType的类型

       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结构

 

       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;

}


intd3d::EnterMsgLoop( 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;

}

原创粉丝点击