電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
[C++/CLI][討論] DirectX 範例 with .NET

 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
babu61509
散播福音的祭司


註冊時間: 2007-08-26
文章: 142

681.01 果凍幣

發表發表於: 2008-12-29, AM 11:39 星期一    文章主題: [C++/CLI][討論] DirectX 範例 with .NET 引言回覆

將 DirectX範例CreateDevice 稍微修改了一下(其實還沒有改的很好...),把視窗跟事件都改用成呼叫.NET :
(重新改好了= = 把.NET部分和DX部分分開寫就沒問題了)

在整合的時候要注意一個問題,managed的類別可以使用unmanaged的類別,但是不能反過來用。
不過也沒什麼關係,只有主視窗類別是用mangaed,其他類別按照原本C++的方式寫就可以了。

代碼:

#using <System.dll>                     // 引用 System.dll (專案的參照有設定的話可以不用加)
#using <System.Windows.Forms.dll>         // 引用 System.Windows.Forms.dll (專案的參照有設定的話可以不用加)

#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#pragma warning( disable : 4996 ) // disable deprecated warning
#pragma warning( default : 4996 )

using namespace System;                  // 偷懶不用打 System:: 用
using namespace System::Windows::Forms;      // 偷懶不用打 System::Windows::Forms 用

// DirectX部分
public class Dxpart{
   public:
      IDirect3D9*         g_pD3D; // Used to create the D3DDevice
      IDirect3DDevice9*   g_pd3dDevice; // Our rendering device

      Dxpart(){
         g_pD3D = NULL;
         g_pd3dDevice = NULL;
      }

      ~Dxpart(){
         if( g_pd3dDevice != NULL )
            g_pd3dDevice->Release();

         if( g_pD3D != NULL )
            g_pD3D->Release();
      }

      int CreateDevice(HWND hWnd){
         if( SUCCEEDED( InitD3D( hWnd ) ) )
         {
            return 1;
         }
         return 0;
      }

      HRESULT InitD3D( HWND hWnd )
      {
      // Create the D3D object, which is needed to create the D3DDevice.
      if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
         return E_FAIL;

      // Set up the structure used to create the D3DDevice. Most parameters are
      // zeroed out. We set Windowed to TRUE, since we want to do D3D in a
      // window, and then set the SwapEffect to "discard", which is the most
      // efficient method of presenting the back buffer to the display.  And
      // we request a back buffer format that matches the current desktop display
      // format.
      D3DPRESENT_PARAMETERS d3dpp;
      ZeroMemory( &d3dpp, sizeof( d3dpp ) );
      d3dpp.Windowed = TRUE;
      d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
      d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

      // Create the Direct3D device. Here we are using the default adapter (most
      // systems only have one, unless they have multiple graphics hardware cards
      // installed) and requesting the HAL (which is saying we want the hardware
      // device rather than a software one). Software vertex processing is
      // specified since we know it will work on all cards. On cards that support
      // hardware vertex processing, though, we would see a big performance gain
      // by specifying hardware vertex processing.
      if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                         &d3dpp, &g_pd3dDevice ) ) )
         {
            return E_FAIL;
         }
      
      // Device state would normally be set here

      return S_OK;
      }

      void Render(){
         if( NULL == g_pd3dDevice )
         return;

         // Clear the backbuffer to a blue color
         g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

         // Begin the scene
         if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
         {
            // Rendering of scene objects can happen here
      
            // End the scene
            g_pd3dDevice->EndScene();
         }
      
         // Present the backbuffer contents to the display
         g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
      }
};

// .NET 部分

namespace Clr01{

public ref class Form1: public System::Windows::Forms::Form
{
private:
   Dxpart* dxins;

public:
   Form1()
   {
     this->dxins = new Dxpart();
     this->Text = "D3D Tutorial 01: CreateDevice";
     this->dxins->CreateDevice((HWND)this->Handle.ToPointer());
      this->Paint += gcnew PaintEventHandler(this, &Form1::Render);
   }

private:
   void Form1::Render(Object^ sender, PaintEventArgs^ e)
{
   dxins->Render();
}

};
// 進入點
int main(void)
{
   Application::Run( gcnew Form1 );
   return 0;
}

}

_________________
已經畢業了!!


babu61509 在 2009-4-8, AM 11:14 星期三 作了第 6 次修改
回頂端
檢視會員個人資料 發送私人訊息
babu61509
散播福音的祭司


註冊時間: 2007-08-26
文章: 142

681.01 果凍幣

發表發表於: 2008-12-29, PM 12:50 星期一    文章主題: 引言回覆

DirectX 的 Vertices 範例 :

代碼:

#using <System.dll>                     // 引用 System.dll (專案的參照有設定的話可以不用加)
#using <System.Windows.Forms.dll>         // 引用 System.Windows.Forms.dll (專案的參照有設定的話可以不用加)

#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#pragma warning( disable : 4996 ) // disable deprecated warning
#pragma warning( default : 4996 )

using namespace System;                  // 偷懶不用打 System:: 用
using namespace System::Windows::Forms;      // 偷懶不用打 System::Windows::Forms 用


struct CUSTOMVERTEX
{
    FLOAT x, y, z, rhw; // The transformed position for the vertex
    DWORD color;        // The vertex color
};

// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)

// DirectX部分
public class Dxpart{
   public:
      IDirect3D9*         g_pD3D; // Used to create the D3DDevice
      IDirect3DDevice9*   g_pd3dDevice; // Our rendering device
      LPDIRECT3DVERTEXBUFFER9 g_pVB;

      Dxpart(){
         g_pD3D = NULL;
         g_pd3dDevice = NULL;
         g_pVB = NULL;
      }

      ~Dxpart(){
         if( g_pVB != NULL )
            g_pVB->Release();
         if( g_pd3dDevice != NULL )
            g_pd3dDevice->Release();

         if( g_pD3D != NULL )
            g_pD3D->Release();
      }

      int CreateDevice(HWND hWnd){
         if( SUCCEEDED( InitD3D( hWnd ) ) )
         {
            if( SUCCEEDED( InitVB() ) )
            {
               return 2;
            }
            return 1;
         }
         return 0;
      }

      HRESULT InitVB()
      {
         // Initialize three Vertices for rendering a triangle
         CUSTOMVERTEX Vertices[] =
         {
            { 150.0f,  50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
            { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
            {  50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
         };

         // Create the vertex buffer. Here we are allocating enough memory
         // (from the default pool) to hold all our 3 custom Vertices. We also
         // specify the FVF, so the vertex buffer knows what data it contains.
         if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
                                            0, D3DFVF_CUSTOMVERTEX,
                                            D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
         {
            return E_FAIL;
         }

         // Now we fill the vertex buffer. To do this, we need to Lock() the VB to
         // gain access to the Vertices. This mechanism is required becuase vertex
         // buffers may be in device memory.
         VOID* pVertices;
         if( FAILED( g_pVB->Lock( 0, sizeof( Vertices ), ( void** )&pVertices, 0 ) ) )
            return E_FAIL;
         memcpy( pVertices, Vertices, sizeof( Vertices ) );
         g_pVB->Unlock();

         return S_OK;
      }

      HRESULT InitD3D( HWND hWnd )
      {
      // Create the D3D object, which is needed to create the D3DDevice.
      if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
         return E_FAIL;

      // Set up the structure used to create the D3DDevice. Most parameters are
      // zeroed out. We set Windowed to TRUE, since we want to do D3D in a
      // window, and then set the SwapEffect to "discard", which is the most
      // efficient method of presenting the back buffer to the display.  And
      // we request a back buffer format that matches the current desktop display
      // format.
      D3DPRESENT_PARAMETERS d3dpp;
      ZeroMemory( &d3dpp, sizeof( d3dpp ) );
      d3dpp.Windowed = TRUE;
      d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
      d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

      // Create the Direct3D device. Here we are using the default adapter (most
      // systems only have one, unless they have multiple graphics hardware cards
      // installed) and requesting the HAL (which is saying we want the hardware
      // device rather than a software one). Software vertex processing is
      // specified since we know it will work on all cards. On cards that support
      // hardware vertex processing, though, we would see a big performance gain
      // by specifying hardware vertex processing.
      if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                         &d3dpp, &g_pd3dDevice ) ) )
         {
            return E_FAIL;
         }
      
      // Device state would normally be set here

      return S_OK;
      }

      void Render(){
          // Clear the backbuffer to a blue color
         g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

         // Begin the scene
         if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
         {
            // Draw the triangles in the vertex buffer. This is broken into a few
            // steps. We are passing the Vertices down a "stream", so first we need
            // to specify the source of that stream, which is our vertex buffer. Then
            // we need to let D3D know what vertex shader to use. Full, custom vertex
            // shaders are an advanced topic, but in most cases the vertex shader is
            // just the FVF, so that D3D knows what type of Vertices we are dealing
            // with. Finally, we call DrawPrimitive() which does the actual rendering
            // of our geometry (in this case, just one triangle).
            g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
            g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
            g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );

            // End the scene
            g_pd3dDevice->EndScene();
         }

         // Present the backbuffer contents to the display
         g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
      }
};

// .NET 部分

namespace Clr01{

public ref class Form1: public System::Windows::Forms::Form
{
private:
   Dxpart* dxins;

public:
   Form1()
   {
     this->dxins = new Dxpart();
     this->Text = "D3D Tutorial 02: Vertices";
     this->dxins->CreateDevice((HWND)this->Handle.ToPointer());
      this->Paint += gcnew PaintEventHandler(this, &Form1::Render);
   }

private:
   void Form1::Render(Object^ sender, PaintEventArgs^ e)
{
   dxins->Render();
}

};
// 進入點
int main(void)
{
   Application::Run( gcnew Form1 );
   return 0;
}

}

_________________
已經畢業了!!
回頂端
檢視會員個人資料 發送私人訊息
babu61509
散播福音的祭司


註冊時間: 2007-08-26
文章: 142

681.01 果凍幣

發表發表於: 2008-12-29, PM 6:32 星期一    文章主題: 引言回覆

DirectX 範例 Matrices :
(在這個範例中 我改用計時器來render圖,因為對於WndProc的東西還不到家,不知道怎麼判斷是否為idle狀態,其實用一個執行緒來跑也是可以的)
代碼:

#using <System.dll>                     // 引用 System.dll (專案的參照有設定的話可以不用加)
#using <System.Windows.Forms.dll>         // 引用 System.Windows.Forms.dll (專案的參照有設定的話可以不用加)

#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "winmm.lib")
#pragma warning( disable : 4996 ) // disable deprecated warning
#pragma warning( default : 4996 )

using namespace System;                  // 偷懶不用打 System:: 用
using namespace System::Windows::Forms;      // 偷懶不用打 System::Windows::Forms 用


struct CUSTOMVERTEX
{
    FLOAT x, y, z, rhw; // The transformed position for the vertex
    DWORD color;        // The vertex color
};

// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

// DirectX部分
public class Dxpart{
   public:
      IDirect3D9*         g_pD3D; // Used to create the D3DDevice
      IDirect3DDevice9*   g_pd3dDevice; // Our rendering device
      LPDIRECT3DVERTEXBUFFER9 g_pVB;

      Dxpart(){
         g_pD3D = NULL;
         g_pd3dDevice = NULL;
         g_pVB = NULL;
      }

      ~Dxpart(){
         if( g_pVB != NULL )
            g_pVB->Release();
         if( g_pd3dDevice != NULL )
            g_pd3dDevice->Release();

         if( g_pD3D != NULL )
            g_pD3D->Release();
      }

      int CreateDevice(HWND hWnd){
         if( SUCCEEDED( InitD3D( hWnd ) ) )
         {
            if( SUCCEEDED( InitGeometry() ) )
            {
               return 2;
            }
            return 1;
         }
         return 0;
      }

      HRESULT InitGeometry()
      {
         // Initialize three vertices for rendering a triangle
         CUSTOMVERTEX g_Vertices[] =
         {
            { -1.0f,-1.0f, 0.0f, 0xffff0000, },
            {  1.0f,-1.0f, 0.0f, 0xff0000ff, },
            {  0.0f, 1.0f, 0.0f, 0xffffffff, },
         };

         // Create the vertex buffer.
         if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
                                            0, D3DFVF_CUSTOMVERTEX,
                                            D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
         {
            return E_FAIL;
         }

         // Fill the vertex buffer.
         VOID* pVertices;
         if( FAILED( g_pVB->Lock( 0, sizeof( g_Vertices ), ( void** )&pVertices, 0 ) ) )
            return E_FAIL;
         memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
         g_pVB->Unlock();

         return S_OK;
      }

      HRESULT InitD3D( HWND hWnd )
      {
          // Create the D3D object.
         if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
            return E_FAIL;

         // Set up the structure used to create the D3DDevice
         D3DPRESENT_PARAMETERS d3dpp;
         ZeroMemory( &d3dpp, sizeof( d3dpp ) );
         d3dpp.Windowed = TRUE;
         d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
         d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

         // Create the D3DDevice
         if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                   &d3dpp, &g_pd3dDevice ) ) )
         {
            return E_FAIL;
         }

         // Turn off culling, so we see the front and back of the triangle
         g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

         // Turn off D3D lighting, since we are providing our own vertex colors
         g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

         return S_OK;
      }

      void Render(){
         // Clear the backbuffer to a black color
         g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );

         // Begin the scene
         if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
         {
            // Setup the world, view, and projection Matrices
            SetupMatrices();

            // Render the vertex buffer contents
            g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
            g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
            g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );

            // End the scene
            g_pd3dDevice->EndScene();
         }

         // Present the backbuffer contents to the display
         g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
      }

      void SetupMatrices()
      {
         // For our world matrix, we will just rotate the object about the y-axis.
         D3DXMATRIXA16 matWorld;

         // Set up the rotation matrix to generate 1 full rotation (2*PI radians)
         // every 1000 ms. To avoid the loss of precision inherent in very high
         // floating point numbers, the system time is modulated by the rotation
         // period before conversion to a radian angle.
         UINT iTime = timeGetTime() % 1000;
         FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
         D3DXMatrixRotationY( &matWorld, fAngle );
         g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

         // Set up our view matrix. A view matrix can be defined given an eye point,
         // a point to lookat, and a direction for which way is up. Here, we set the
         // eye five units back along the z-axis and up three units, look at the
         // origin, and define "up" to be in the y-direction.
         D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
         D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
         D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
         D3DXMATRIXA16 matView;
         D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
         g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

         // For the projection matrix, we set up a perspective transform (which
         // transforms geometry from 3D view space to 2D viewport space, with
         // a perspective divide making objects smaller in the distance). To build
         // a perpsective transform, we need the field of view (1/4 pi is common),
         // the aspect ratio, and the near and far clipping planes (which define at
         // what distances geometry should be no longer be rendered).
         D3DXMATRIXA16 matProj;
         D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
         g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
      }
};

// .NET 部分

namespace Clr01{

public ref class Form1: public System::Windows::Forms::Form
{
private:
   Dxpart* dxins;
   System::Windows::Forms::Timer t1;

public:
   Form1()
   {
     this->dxins = new Dxpart();
     this->t1.Interval = 10;
     t1.Tick += gcnew EventHandler(this, &Form1::Render);
     t1.Start();
     this->Text = "D3D Tutorial 03: Matrices";
     this->dxins->CreateDevice((HWND)this->Handle.ToPointer());
   }

private:
   void Form1::Render(Object^ sender, EventArgs^ e)
   {
      dxins->Render();
   }

};
// 進入點
int main(void)
{
   Application::Run( gcnew Form1 );
   return 0;
}

}

_________________
已經畢業了!!
回頂端
檢視會員個人資料 發送私人訊息
songfat
時常出沒的會員


註冊時間: 2008-01-25
文章: 34

192.68 果凍幣

發表發表於: 2009-4-7, AM 12:34 星期二    文章主題: 引言回覆

由於小弟我之前一直使用win32 api的方式來產生控制項@@",在研究室做實驗時相當麻煩,想換成windows form的c++/cli + native dx,剛好看到有大大寫了個範例,感謝大大啊@@讓我省了好多時間。
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作