WPF World Editor для моего игрового движка DirectX - PullRequest
4 голосов
/ 29 августа 2011

Я работаю над небольшим игровым движком на C ++ с использованием DirectX.Цель образовательная и развлекательная.

Моя следующая цель - создать простой редактор мира, использующий игровой движок.Для этого мне нужно будет переместить движок в dll, чтобы он мог использоваться игрой и / или редактором.Редактор мира будет автономным инструментом, а не частью игры.Основная цель редактора мира будет состоять в том, чтобы читать и отображать мой (пользовательский) файл сцены и позволять мне аннотировать / изменять свойства объектов мира (сеток), клонировать объекты, подбирать и перемещать объекты, а также отбрасывать их, масштабироватьобъекты и т. д., а затем сохраните измененную сцену, чтобы потом ее можно было прочитать в игре.

Для редактора рекомендуется использовать wxWidgets.Небольшое исследование заставляет меня чувствовать, что wxWidgets немного стар и неуклюж, хотя я уверен, что с его помощью можно написать очень хороший графический интерфейс.Это просто крутая кривая обучения, которую я не ожидаю.Я получил образцы для сборки и запуска, но это была головная боль.

Немного больше исследований, и я обнаружил, что могу интегрировать DirectX в приложение WPF, используя D3DImage.Я немного поработал с WPF и не нахожу его слишком пугающим, и есть много хороших книг (есть только одна старая для wxWidgets), а также огромное количество информации в Интернете.Я получил пример вращающегося треугольника, и он показался мне довольно простым.

Так что мой вопрос:

Позволит ли WPF создать приложение для небольшого приличного редактора мира, которое повторно использует мой игровой движок?

Мой игровой движок в настоящее время использует RawInput для мыши и клавиатуры;как это будет работать с WPF?

Как WPF влияет на мою рассылку сообщений?

Похоже, мне придется написать множество функций (шаблон фасада?), чтобы позволить WPF взаимодействовать смой игровой движок.Есть ли простой способ разобраться с этим, чтобы он не попал в игру?

Буду признателен за любые советы и идеи о том, как поступить!

Спасибо.

1 Ответ

3 голосов
/ 14 сентября 2011

Вам необходимо создать класс-оболочку, который предоставляет определенные функции вашей игры.

Например. Эта функция в моей оболочке редактора игрового движка 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

Итак, вы можете вызвать editormain в конструкторе приложений wpf

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

...