我的DirectX游戏引擎的WPF World Editor

时间:2011-08-29 07:39:07

标签: c++ wpf directx game-engine

我正在使用DirectX在C ++中开发一个小型游戏和游戏引擎。目的是教育和娱乐。

我的下一个目标是构建一个使用游戏引擎的简单世界编辑器。为此,我需要将引擎移动到一个dll中,以便游戏和/或编辑器可以使用它。世界编辑器将是一个独立的工具,而不是游戏的一部分。世界编辑器的主要目的是读入并显示我的(自定义)场景文件,并允许我注释/修改世界对象(网格)上的属性,克隆对象,拾取和移动对象并删除它们,缩放对象等,然后保存修改后的场景,以便以后可以通过游戏阅读。

建议我使用wxWidgets作为编辑器。一些研究让我觉得wxWidgets有点古老而笨重,但我确信可以使用它编写非常精细的GUI。这只是一个我不期待的陡峭的学习曲线。我已经拿到了样本来构建和运行,但这很令人头疼。

稍微研究一下,我发现我可以使用D3DImage将DirectX集成到WPF应用程序中。我用WPF做了一点,并没有发现它太吓人了,并且有很多好书(wxWidgets只有一本旧书),以及网上的大量信息。我已经让旋转三角形示例正常工作,看起来非常简单。

所以我的问题是:

WPF是否允许我构建一个可以重用我的游戏引擎的体面的小世界编辑器应用程序?

我的游戏引擎目前使用RawInput用于鼠标和键盘;如何使用WPF?

WPF如何影响我的消息泵?

看起来我必须编写很多函数(facade模式?)才能让WPF与我的游戏引擎进行交互。有没有一种简单的方法来解决这个问题,所以它不会被编入游戏中?

非常感谢有关如何进行的任何其他提示或想法!

谢谢。

1 个答案:

答案 0 :(得分: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 / Update DXShutdown

那么你可以在你的wpf app构造函数中调用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表格和wpf互操作看这里 http://msdn.microsoft.com/en-us/library/ms742474.aspx