2011-08-29 48 views
4

我正在使用DirectX在C++中使用小遊戲和遊戲引擎。目的是教育&娛樂。我的DirectX遊戲引擎WPF世界編輯器

我的下一個目標是建立一個簡單的使用遊戲引擎的世界編輯器。爲此,我需要將引擎移動到dll中,以便可以由遊戲和/或編輯使用。世界編輯將是一個獨立的工具,而不是遊戲的一部分。世界編輯器的主要目的是讀入並顯示我的(自定義)場景文件,並允許我註釋/修改世界對象(網格)的屬性,克隆對象,拾取和移動對象並放下它們,縮放對象等,然後保存修改過的場景,以便以後可以通過遊戲讀取。

建議我使用wxWidgets作爲編輯器。一些研究讓我覺得wxWidgets有點老舊笨重,但我確信使用它可以編寫非常好的GUI。這只是一個陡峭的學習曲線,我不期待。我已經獲得了樣本來建立和運行,但這是一個令人頭疼的問題。

多一點研究,我發現我可以使用D3DImage將DirectX集成到WPF應用程序中。我對WPF做了一些小小的改動,並沒有覺得它太嚇人,並且有很多好書可用(wxWidgets中只有一本舊書),以及網絡上的大量信息。我已經得到了旋轉三角形的例子,它看起來非常簡單。

所以我的問題是:

威爾WPF讓我建立一個重新使用我的遊戲引擎一個體面的小世界編輯器應用程序?

我的遊戲引擎目前使用RawInput作爲鼠標和鍵盤;這將如何與WPF一起工作?

WPF如何影響我的消息泵?

它看起來像我將不得不寫很多函數(facade pattern?)來允許WPF與我的遊戲引擎進行交互。有沒有簡單的方法來分解這個問題,所以它不會被編譯到遊戲中?

任何其他提示或想法如何進行將不勝感激!

謝謝。

+0

我應該也可以使用SlimDx? – Stomp

回答

3

您需要創建一個包裝類來公開您的遊戲的某些功能。

例如。這個函數在我的C++遊戲引擎編輯器中。

extern "C" _declspec(dllexport) void SetPlayerPos(int id, const float x, const float y, const float z); 

然後在C#WPF應用程序,你可以創建一個靜態類,允許你使用這些功能

[DllImport(editorDllName, CallingConvention = CallingConvention.Cdecl)] 
public static extern void SetPlayerPos(int id, float x, float y, float z); 

你必須具備的功能,通過該dll你的遊戲引擎的基本功能。 之類的東西

EditorMain RenderFrame /更新 DXShutdown

,那麼你可以在你的WPF應用程序構造函數中調用editormain

System.IntPtr hInstance = System.Runtime.InteropServices.Marshal.GetHINSTANCE(this.GetType().Module); 
IntPtr hwnd = this.DisplayPanel.Handle; 
NativeMethods.EditorMain(hInstance, IntPtr.Zero, hwnd, 1, this.DisplayPanel.Width, this.DisplayPanel.Height); 

你需要創建一個消息過濾器類的初始化構造函數以及

m_messageFilter = new MessageHandler(this.Handle, this.DisplayPanel.Handle, this); 

這裏是你的消息過濾呃類可以看看

public class MessageHandler : IMessageFilter 
{ 
    const int WM_LBUTTONDOWN = 0x0201; 
    const int WM_LBUTTONUP = 0x0202; 


    IntPtr m_formHandle; 
    IntPtr m_displayPanelHandle; 
    EngineDisplayForm m_parent; 

    public MessageHandler(IntPtr formHandle, IntPtr displayPanelHandle, EngineDisplayForm parent) 
    { 
     m_formHandle = formHandle; 
     m_displayPanelHandle = displayPanelHandle; 
     m_parent = parent; 
    } 

    public bool PreFilterMessage(ref Message m) 
    { 
     if (m.HWnd == m_displayPanelHandle || m.HWnd == m_formHandle) 
     { 
      switch (m.Msg) 
      { 
       case WM_LBUTTONDOWN: 
       case WM_LBUTTONUP: 
        { 
         NativeMethods.WndProc(m_displayPanelHandle, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32()); 
         if (m.Msg == WM_LBUTTONUP) 
         { 
          m_parent.SelectActor(); 
         } 
         return true; 
        } 
      } 
     } 
     return false; 
    } 

    public void Application_Idle(object sender, EventArgs e) 
    { 
     try 
     { 
      // Render the scene 
      NativeMethods.RenderFrame(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

做贏形式和WPF互操作這裏看看 http://msdn.microsoft.com/en-us/library/ms742474.aspx

+0

很透徹的回答,謝謝!我真的很感激代碼,我想我現在可以從這裏開始:) – Stomp