2011-08-29 47 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