我的DirectX游戏引擎需要一个WPF世界编辑器

6
我正在使用DirectX用C++编写一个小型游戏和游戏引擎。目的是教育和娱乐。
我的下一个目标是构建一个简单的世界编辑器,它使用游戏引擎。为此,我需要将引擎移动到dll中,以便游戏和/或编辑器可以使用它。世界编辑器将是一个独立的工具,而不是游戏的一部分。主要目的是读取并显示我的(自定义)场景文件,并允许我在世界对象(网格)上注释/修改属性,克隆对象,拾起和移动对象并放置它们,缩放对象等,然后保存修改后的场景,以便稍后由游戏读取。
有人建议我在编辑器中使用wxWidgets。经过一些研究,我发现wxWidgets有点老旧且笨重,虽然我相信可以使用它编写非常好的GUI。但这是一个陡峭的学习曲线,我不期待它。我已经成功构建并运行了示例,但是这很麻烦。
我做了更多的研究,发现我可以使用D3DImage将DirectX集成到WPF应用程序中。我在WPF方面做了一些尝试,没有发现太大难度,而且有很多好的书籍可供使用(只有一个旧版本的wxWidgets),以及大量的网络信息。我已经成功运行了旋转三角形示例,它似乎非常简单。
所以我的问题是:
WPF能否让我构建一个很好的小型世界编辑器应用程序来重用我的游戏引擎?
我的游戏引擎目前使用RawInput进行鼠标和键盘输入;这将如何与WPF一起工作?
WPF如何影响我的消息泵?
看起来我将不得不编写很多函数(外观模式?)以使WPF与我的游戏引擎交互。是否有一种简单的方法将其分离出来,以便它不会被编译到游戏中?
如果您对如何继续进行有任何其他提示或想法,将不胜感激!
谢谢。

我是否也应该使用SlimDx? - Stomp
1个回答

5
你需要创建一个包装类,以公开你的游戏的某些功能。例如,这个函数在我的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提供函数,这些内容包括:
- 编辑器主要功能 - 渲染框架/更新 - DirectX关闭
然后您可以在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);
        }
    }

关于如何进行Win Forms和WPF互操作,请看这里:http://msdn.microsoft.com/en-us/library/ms742474.aspx


非常详细的回答,谢谢!我真的很感谢这段代码,我想我现在可以入门了 :) - Stomp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接