4.12.2010, 18.12.2010 Разбор кода примера MultiAnimation (F:\GameDev\Microsoft DirectX SDK (August 2008)\Samples\C++\Direct3D\MultiAnimation) |
||
Основные моменты, которые представлены в примере модуль - MultiAnimation.cpp //имя файла для земной поверхности, количество тайлов по вертикали и горизонтали #define
TXFILE_FLOOR L"\\Media\\Textures\\floor.jpg" |
||
CFirstPersonCamera g_Camera; // игровая камера | ||
Исполнение любого WinAPI приложения начинается с функции WinMain поэтому в первую очередь смотрим - wWinMain |
||
OnCreateDevice - функция вызывается модулем DXUT, непосредственно сразу же после создания Direct3DDevice (это происходит внутри DXUT). Загружаемые здесь ресурсы являются - D3DPOOL_MANAGED, т. е. загружаемые непосредственно в память видеокарты и зависящие от её состояния (от состояния объекта IDirect3DDevice). загрузка моделей и текстур происходит в функции - OnResetDevice, эта функция вызывается специализированным объектом модуля DXUT. |
||
После того, как будет полностью выполнена функция wWinMain приложение перейдет в цикл последовательного вызова двух функций - OnFrameMove - метода подготовки сцены (анимации сцены); OnFrameRender - метода отрисовки сцены. Поступающие от системы сообщения обрабатываются в MsgProc OnGUIEvent - обрабатывает сообщения элементов GUI (кнопок, полей ввода и т. п., эти элементы - классы DXUTgui) KeyboardProc - обрабатываются сообщения от клавиатуры, но рассчитанные не на управление игрой, а более медленные операции, например вызов помощи/подсказки по клавише [F1] - Help. Управление игрой требует достаточно оперативного отклика, поэтому должно происходить внутри OnFrameMove |
||
Давайте сначала более детально проясним основные моменты работы кода. Создадим резервные копии файлов MultiAnimation.h и MultiAnimation.cpp и смело начнём. Первым шагом Я убрал (закомментировал) весь код, который относится к элементам GUI (g_DialogResourceManager, g_SettingsDlg, g_HUD), чтобы не усложнять и без того сложный код. |
||
Откомпилировал и убедился что всё работает. | ||
Далее я выяснил, что в функции MsgProc строки кода - if(
-1 == g_dwFollow ) - это управление камерой от клавиатуры и мыши, если их закомментировать, то управление камерой становится невозможным. |
||
Далее я поставил режим компиляции Debug, расставил контрольные точки во всех значимых функциях и начал отслеживать как работает код в режиме отладки. | ||
InitApp() - выполняется в первую очередь, здесь выставляется начальное положение камеры. | ||
ModifyDeviceSettings - проверяются возможности d3d9device, необходимые для работы данного примера. А также выставляется начальный режим работы по отрисовке геометрии на аппаратном уровне (D3DDEVTYPE_HAL). | ||
OnCreateDevice - создается шрифт для вывода отладочной информации, загружается текстура для пола, шейдер, рассчитываются параметры расположения пола и инициализируется материал для него. | ||
OnResetDevice - выполняется загрузка кода шейдера, геометрии, параметры камеры, освещения, сбрасывается таймер | ||
OnFrameMove - анимируются персонажи, камера | ||
OnFrameRender - отрисовывается сцена | ||
далее снова вызывается функция OnFrameMove, затем OnFrameRender и этот процесс повторяется бесконечно, пока не будет выполнено закрытие приложения. | ||
В коде собственного примера я создал аналогичные функции, поэтому вызываться они должны в такой же последовательности, иначе будут ошибки. Это и предстоит проверить. | ||
InitApp() - в моём коде вызову данной процедуры соответствует метод CAdventure::InitCamera() | ||
сразу же была выявлена ошибка - первым был вызван метод CAdventure::LoadMedia() что соответствует OnCreateDevice вот и первая ошибка ! Из-за отсутствия вызова InitCamera() сцена рисовалась некорректно. Решение - вызов метода InitCamera() был вставлен первой строчкой в реализации метода LoadMedia() |
||
Для реализации управления камерой, а также управления персонажами и добавления их в сцену нужно написать аналогичные методы для обработки и направления сообщений метода MsgProc камере. В примере MultiAnimation управление персонажами (их добавлением) и некоторые другие опции реализованы кнопками GUI. Можно поступить так же, а можно перевести результат действия этих кнопок, привязав их к каким-либо клавишам и обрабатывая нажатия посредством DirectInput. |
||
На этом наш краткий обзор завершен. | ||