熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

VC.NET的Direct3D極速入門寶典

2022-06-13   來源: .NET編程 

  聽說DirectX發布了嗎?如果沒有你現在也應該聽我說過了那就去edede/dxbsdkexe下載一個最新的DirectX的SDK因為我將使用DD來進行全文的講解其實DirectX裡有非常詳細的教程和參考大多數人只需要看看這些幫助就可以自己學習DD了我的這篇文章適合那些很懶但想快速入門不懂英文或編程知識很欠缺的人看裝好DirectX打開新建一個Win工程在StdAfxh裡添加下面的語句
  
  #include // DD標准頭文件
  #include // DD數學庫頭文件
  #include // 這個不用我說了吧?
  #pragma comment( lib dd ) // DD的靜態庫
  #pragma comment( lib ddx ) // DD數學庫的靜態庫
  
  然後把winmain所在文件的代碼做如下的修改
  #include stdafxh
  #define MAX_LOADSTRING
  
  HINSTANCE g_hInst;
  HWND g_hWnd;
  IDirectD *g_pDD;
  IDirectDDevice *g_pddDevice;
  IDirectDVertexBuffer *g_pVB;
  
  TCHAR szTitle[MAX_LOADSTRING];
  TCHAR szWindowClass[MAX_LOADSTRING];
  ATOM MyRegisterClass(HINSTANCE hInstance);
  BOOL InitInstance(HINSTANCE int);
  LRESULT CALLBACK WndProc(HWND UINT WPARAM LPARAM);
  LRESULT CALLBACK About(HWND UINT WPARAM LPARAM);
  void OnIdle( void );
  void OnCreate( HWND hWnd );
  HRESULT InitDD( void );
  HRESULT CreateObject( void );
  void ReleaseDD( void );
  HRESULT SetModalMatrix( void );
  HRESULT SetProjMatrix( WORD wWidth WORD wHeight );
  void BeforePaint( void );
  int APIENTRY _tWinMain(HINSTANCE hInstance HINSTANCE hPrevInstance LPTSTR lpCmdLine int nCmdShow)
  {
  MSG msg;
  HACCEL hAccelTable;
  
  LoadString(hInstance IDS_APP_TITLE szTitle MAX_LOADSTRING);
  LoadString(hInstance IDC_DDTEST szWindowClass MAX_LOADSTRING);
  MyRegisterClass(hInstance);
  
  if (!InitInstance (hInstance nCmdShow))
  {
  return FALSE;
  }
  
  hAccelTable = LoadAccelerators(hInstance (LPCTSTR)IDC_DDTEST);
  
  while ( true )
  {
  if ( PeekMessage( &msg NULL PM_REMOVE ) )
  {
  if (!TranslateAccelerator(msghwnd hAccelTable &msg))
  {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
  }
  continue;
  }
  if ( WM_QUIT == ssage )
  {
  break;
  }
  OnIdle();
  }
  UnregisterClass( szWindowClass g_hInst );
  return (int)msgwParam;
  }
  
  ATOM MyRegisterClass( HINSTANCE hInstance )
  {
  WNDCLASSEX wcex;
  wcexcbSize = sizeof(WNDCLASSEX);
  wcexstyle = CS_HREDRAW | CS_VREDRAW;
  wcexlpfnWndProc = (WNDPROC)WndProc;
  wcexcbClsExtra = ;
  wcexcbWndExtra = ;
  wcexhInstance = hInstance;
  wcexhIcon = LoadIcon(hInstance (LPCTSTR)IDI_DDTEST);
  wcexhCursor = LoadCursor(NULL IDC_ARROW);
  wcexhbrBackground = (HBRUSH)(COLOR_WINDOW+);
  wcexlpszMenuName = (LPCTSTR)IDC_DDTEST;
  wcexlpszClassName = szWindowClass;
  wcexhIconSm = LoadIcon(wcexhInstance (LPCTSTR)IDI_SMALL);
  return RegisterClassEx(&wcex);
  }
  
  BOOL InitInstance( HINSTANCE hInstance int nCmdShow )
  {
  g_hInst = hInstance;
  CreateWindow( szWindowClass szTitle WS_OVERLAPPEDWINDOWCW_USEDEFAULT CW_USEDEFAULT NULL NULL hInstance NULL );
  if ( !g_hWnd )
  {
  return FALSE;
  }
  ShowWindow( g_hWnd nCmdShow );
  UpdateWindow( g_hWnd );
  return TRUE;
  }
  
  LRESULT CALLBACK WndProc(HWND hWnd UINT message WPARAM wParam LPARAM lParam)
  {
  int wmId wmEvent;
  switch (message)
  {
  case WM_CREATE:
  OnCreate( hWnd );
  break;
  case WM_COMMAND:
  wmId = LOWORD(wParam);
  wmEvent = HIWORD(wParam);
  switch (wmId)
  {
  case IDM_EXIT:
  DestroyWindow(hWnd);
  break;
  default:
  return DefWindowProc(hWnd message wParam lParam);
  }
  break;
  case WM_SIZE:
  SetProjMatrix( LOWORD( lParam ) HIWORD( lParam ) );
  break;
  case WM_DESTROY:
  ReleaseDD();
  PostQuitMessage();
  break;
  default:
  return DefWindowProc(hWnd message wParam lParam);
  }
  return ;
  }
  
  void OnCreate( HWND hWnd )
  {
  g_hWnd = hWnd;
  InitDD();
  CreateObject();
  }
  
  void ReleaseDD( void )
  {
  }
  
  HRESULT InitDD( void )
  {
  return S_OK;
  }
  
  void BeforePaint( void )
  {
  }
  
  HRESULT CreateObject( void )
  {
  return S_OK;
  }
  
  void OnIdle( void )
  {
  }
  
  HRESULT SetModalMatrix( void )
  {
  return S_OK;
  }
  
  HRESULT SetProjMatrix( WORD wWidth WORD wHeight )
  {
  return S_OK;
  }
  
  
  上面的代碼僅是一個框架仔細研究過上篇文章的朋友應該非常清楚這些代碼的含意不過我還是需要大至講解一下 在InitInstance函數中初始化程序實例的開始我們將該實例的句柄放到全局變量中去以便以後使用
  
  g_hInst = hInstance;
  
  在創建窗體時我並沒有直接將CreateWindow的返回值——創建成功的窗體句柄賦給全局變量g_hWnd因為CreateWindow函數在執行中會引發幾個消息其中有WM_CREATE在這個消息的處理函數中OnCreate中我執行了下面的語句
  
  g_hWnd = hWnd;
  
  這樣我們就可以早一點用到g_hWnd了SetProjMatrix是設置投影矩陣的投影矩形僅受窗口縱橫比影響所以在WM_SIZE事件時調用時就可以了而SetModalMatrix是設置模型矩陣的也就是眼睛點和視點之類的東東所以它一定要在Rander的時候准確的說是在Render之前執行InitDD在窗體創建時調用用於初始化DD設備CreateObject和InitDD一樣是初始化函數它用於創建三維對象
  下面我們來填寫代碼首先是初始化我們在InitDD函數裡填寫下面的代碼
  
  g_pDD = DirectDCreate( DD_SDK_VERSION );
  
  if( NULL == g_pDD )
  
  {
  
  return E_FAIL;
  
  }
  
  DDPRESENT_PARAMETERS ddpp;
  
  ZeroMemory( &ddpp sizeof(ddpp) );
  
  ddppWindowed = TRUE;
  
  ddppSwapEffect = DDSWAPEFFECT_DISCARD;
  
  ddppBackBufferFormat = DDFMT_ARGB;
  
  g_pDD>CreateDevice( DDADAPTER_DEFAULT DDDEVTYPE_HAL g_hWnd
  
  DDCREATE_HARDWARE_VERTEXPROCESSING | DDCREATE_PUREDEVICE
  
  &ddpp &g_pddDevice );
  
  g_pddDevice>SetRenderState( DDRS_LIGHTING TRUE );
  
  g_pddDevice>SetRenderState( DDRS_AMBIENT
  
  DDCOLOR_COLORVALUE( f f f ) );
  
  g_pddDevice>LightEnable( TRUE);
  
  DDMATERIAL mtrl;
  
  ZeroMemory( &mtrl sizeof(mtrl) );
  
  mtrlDiffuser = mtrlAmbientr = f / f;
  
  mtrlDiffuseg = mtrlAmbientg = f / f;
  
  mtrlDiffuseb = mtrlAmbientb = f / f;
  
  mtrlDiffusea = mtrlAmbienta = f;
  
  g_pddDevice>SetMaterial( &mtrl );
  
  return S_OK;
  
  DirectDCreate函數為我們創建了一個DD接口指針並將接口指針返回到全局變量中保存起來參數必須為DD_SDK_VERSIONDDPRESENT_PARAMETERS是一個結構體它就像OpenGL中的PixelFormat一樣是創建時指定設備的一些屬性的
  
  ddppWindowed = TRUE; // 設備是窗口設備而不是全屏
  ddppSwapEffect = DDSWAPEFFECT_DISCARD; // 翻轉緩沖區時不改動後台緩沖
  ddppBackBufferFormat = DDFMT_ARGB; // ARGB顏色模式
  
  在這之後我們就可以調用CreateDevice來創建設備了第一個參數指定使用主顯示驅動第二個參數指定該設備是否使用硬件來處理顯示第三個參數當然是你的窗體句柄第四個參數如果指定DDCREATE_HARDWARE_VERTEXPROCESSING | DDCREATE_
From:http://tw.wingwit.com/Article/program/net/201311/12668.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.