Готовый перевод Ogre3D Basic Tutorials / Базовые туториалы Ogre3D: Basic Tutorial 7: CEGUI and Ogre
КРАТКОЕ СОДЕРЖАНИЕ
В этом туториале мы изучим, как использовать CEGUI совместно с Ogre.
К концу этого раздела руководства вы должны быть способны добавить основной функционал CEGUI к вашему приложению.
Замечание: этот раздел руководства не планировался, чтобы полностью обучить вас использованию CEGUI. Этот раздел руководства планировался, чтобы вы его начали изучать.
Все дальнейшие вопросы и помощь по CEGUI следует направлять на их домашнюю страницу.
Намного более глубоко и лучше изложенное руководство по CEGUI найдено в документации по CEGUI или здесь, доступные он-лайн.
ДЛЯ НАЧАЛА
ПЕРВОНАЧАЛЬНЫЙ КОД
Измените ваш файл заголовков классов в Базового Руководства 7 таким образом:
Убедитесь, что файл реализации Базового Руководства 7 выглядит так:
НАСТРОЙКИ ПРОЕКТА
Вы будете нуждаться в CEGUI с Ogre CEGUI рендерером компилированным в Ogre 1.7 - то есть та версия Ogre, которую Вы используете.
См. "Building CEGUI" для инструкций.
Тогда Вы должны добавить местоположение заголовков CEGUI к каталогам включения вашего проекта
Этот код предполагает, что Вы подготовили CEGUI SDK со следующим расположением директорий:
После компилирования CEGUI Вы можете скопировать файлы, чтобы сделать SDK.
Это является полностью дополнительным, хотя инструкции здесь основаны на этом расположении.
Если у Вас нет своих заголовков CEGUI в справочнике под названием 'CEGUI', удалите часть 'CEGUI' из каталогов включения в заголовке Основной Обучающей программе 7.
Добавьте следующие две строки к Вашему списку проектов включённых директорий
ДВИЖЕНИЕ DLLs
В Windows Вы должны скопировать следующие DLLs к своему OGRE_HOME/bin/debug каталогу:
Последний DLL предполагает, что Вы используете по умолчанию Expat XML синтаксический анализатор с CEGUI.
КОМПИЛИРОВАНИЕ КОДА
Убедитесь, что Вы можете компилировать и запустить этот код перед продолжением.
в приложении ничего не будет кроме пустого экрана (нажмите esc, чтобы выйти).
Если Вы сталкиваетесь с ошибками компилятора или компоновщика, проверьте свои настройки.
КРАТКОЕ ВВЕДЕНИЕ В CEGUI
CEGUI - полнофункциональная библиотека GUI, которая может быть включена в трехмерные приложения, такие как Ogre (он также поддерживает OpenGL, DirectX, и Irrlicht).
Во многом как и Ogre, который является только графической библиотекой(и не делает такие вещи как проигрывание звука, расчет физики и так далее), CEGUI - это только библиотека GUI, это означает, что он не производит свой собственный рендеринг, как и не подключается к событиям мыши или клавиатуры.
Фактически, для CEGUI, чтобы рендерить вообще, Вы должны обеспечить рендерер для этого (который является библиотекой CEGUIOgreRenderer, отправленной с CEGUI), и для этого, чтобы даже понять события мыши и клвиатуры , Вы должны вручную ввести их в систему.
Поначалу это может выглядеть зубодробительно, но в реальность понадобится совсем немного кода, чтобы это случилось.
Это также позволяет Вам иметь полный контроль над рендерингом и входом; CEGUI никогда не будет помехой.
У CEGUI есть много аспектов и много причуд, которые будут вам чужды(даже если вы уже использовали GUI системы прежде)
Я попытаюсь не торопясь представить их Вам по мере того, как мы будем двигаться вместе.
ИНТЕГРАЦИЯ С OGRE
ОПРЕДЕЛЕНИЕ ГРУПП РЕСУРСОВ CEGUI
У CEGUI как у Ogre есть несколько типов ресурсов нужных для функционирования.
У него есть несколько менеджеров ресурсов(как и у OGRE), которые должны найти соответствующее место, где ресурсы будут расположены.
Таким образом, вам нужно определить необходимые группы ресурсов и их местонахождение внутри файла resources.cfg.
Дистрибутив CEGUI инсталлирует свои ресурсы в разные места, в зависимости от вашей платформы.
При обычной инсталляции Linux они все устанавливаются в /usr/local/share/CEGUI или /usr/share/CEGUI.
Добавьте следующее к файлу resources.cfg - замените 'путь_к_cegui' путем к файлам данных CEGUI:
ИНИЦИАЛИЗАЦИЯ CEGUI
Найдите функцию createScene и добавьте следующий код:
Теперь, поскольку CEGUI инициализирован, нам нужно установить так называемые группы ресурсов по умолчанию для каждого из менеджеров ресурсов CEGUI. Добавьте следующее:
Как вы видите, мы использовали те группы ресурсов, которые мы описали внутри файла resources.cfg.
CEGUI в высокой степени настраиваема, и позволяет вам определить то, как ваше приложение выглядит и как комфортно в нем себя чувствуют, при помощи изменения его "кожурки"(схема, с точки зрения CEGUI).
Мы не будем писать, как делать скины для библиотеки CEGUI в этом руководстве, поэтому если вы желаете узнать больше об этом, обратитесь за советом на сайт CEGUI.
Следующие строки кода выбирают скины:
Следующая вещь, которую нам нужно сделать - это определить курсор мыши по умолчанию:
Первый параметр определяет Imageset, а второй определяет имя используемой картинки Image, для использования из Imageset.
Сквозь все части этого руководства, мы будем использовать CEGUI для вывод мышиного курсора, даже когда нам нужно будет использовать GUI библиотеку.
Можно использовать и другую GUI библиотеку для отображения мыши, или просто создать ваш собственный курсор мыши, используя Ogre напрямую (хотя последний вариант может быть немного применен).
Если вы используете только CEGUI для мышиного курсора и вы беспокоитесь об использовании памяти или дискового пространства, которые ваша игра берет, вы можете посмотреть в одну из этих опция, чтобы заменить CEGUI.
Наконец отметим, что в этом последнем фрагменте кода мы установили курсор мыши по умолчанию, но мы не видели курсор мыши используя непосредственно функцию MouseCursor:: setImage, как мы увидим в следующих руководствах.
Это потому, что в этом руководстве мы постоянно находимся над некоторого типа окном CEGUI(хотя он может быть и невидимым), поэтому установления курсора по умолчанию, будет, по сути, делать курсор мыши таким, какой картинкой мы его выбрали.
Если мы выберем курсор мыши напрямую и не установим курсор по умолчанию, курсор мыши будет невидим каждый раз, когда он будет проходить над окном CEGUI(которое в этом руководстве будет все время).
С другой стороны, установление картинки мыши по умолчанию не делает ничего если у нас нет никаких выведенных окон CEGUI, как происходит в следующих руководствах.
В этой ситуации, вызов MouseCursor::setImage будет выводить курсор для этого приложения. Например:
УБОРКА SDKTRAYS
До тех пор, пока мы не начнем двигаться дальше, нам нужно убрать OgreBites SDKTrays из нашего приложения.
Мы сделаем это переопрелив две функции createFrameListener и frameRenderingQueued.
Копирование содержимого функции BaseApplication::createFrameListener в BasicTutorial7::createFrameListener и удаление той части, где создается SDKTrays и поднимается отладка оверлея.
Это должно выглядит так, когда мы избавимся от него:
Нам также нужно переопределить BaseApplication::frameRenderingQueued.
Чтобы он выглядел так:
Мы просто убираем части mTrayMgr и mDetailsPanel.
ВКЛЮЧЕНИЕ СОБЫТИЙ КЛАВИШ
CEGUI никаким образом не управляет вводом. Она не читает движения мыши или клавиатурный ввод.
Напротив он полагается на пользователя, чтобы он инжектировал клавишное или мышиное событие в систему.
Следующая вещь, которую нам нужно сделать - это управление событиями клавиш.
Если вы работаете с CEGUI, у вас должна быть мышь и клавиатура в буферизованном режими, чтобы вы могли получать события напрямую и инжектировать их по мере того, как они случаются.
Найдите функцию keyPressed и добавьте следующий код в нее (заменив то, что находится здесь):
После получение системных объектов, мы должны сделать две вещи.
Первое, что мы сделаем - выполним инъекцию события нажатия клавиши в CEGUI.
Второе - инжектируем тот символ, который был нажат.
Очень важно правильно инъектировать символ потому, что инъекция нажатия клавиши не всегда приведет к желаемым резутатам, когда используете не английскую клавиатуру. injectChar был разработан с учетом поддержки Unicode.
Теперь нам нужно инъекторовать событие отпускания клавиши в эту систему.
Найдите функцию keyReleased и добавьте следующий код (убрав то, что находится здесь):
Теперь, поскольку нам не нужно инъектировать символ при отпускании клавиши, требуется только событие отпускании клавиши.
КОНВЕРТИРОВАНИЕ И ИНЪЕКЦИИ СОБЫТИЙ MOUSW
Теперь, поскольку мы закончили работать с клавиатурным вводом, нам нужно уделить внимание вводу с мыши.
Однако, у нас есть небольшая проблема, которую нам придется решить.
Когда мы инъектировали событие отпускания клавиши в CEGUI, нам еще не приходился преобразовывать клавиши.
И OIS, и CEGUI используют одни те же коды, для ввода с клавиатуры. Но это не так для клавиш мыши.
До тех пор пока мы не сможем инъектировать нажатые клавиши мыши в CEGUI, нам нужно будет записать функцию, которая преобразовывает идентификаторы кнопок OIS в идентификаторы кнопок CEGUI.
Добавьте следующий код в BasicTutorial7.cpp:
Может стоят локальная статическая функция, поэтому нам нужно определить ее в заголовок.
Теперь мы может инъектировать события мыши.
Найдите функцию mousePressed и добавьте следующий код(заменив то, что там находится):
Это должно условно говорить само за себя.
Мы преобразовываем идентификаторы кнопки, которые переданы, и передаем результат в CEGUI.
Найдите функцию mouseReleased и добавьте эту строка кода(заменив то, что там находится):
И наконец, нам нужно инъектировать движение мыши в CEGUI.
У объекта CEGUI::System есть функция injectMouseMove, которая ожидает относительные перемещения мыши.
Обработчик OIS::mouseMoved передает нам его относительные перемещения в переменные state.X.rel и state.Y.rel.
Найдите функцию mouseMoved и добавьте следующий код(заменив то, что там находится):
120 это разновидность "магического числа" используемого Microsoft давным-давно и в довольно много в теперешних системах.
OIS использует то же магическое число. GLUT, например, его не использует. Используйте Google, чтобы узнать больше.
Вот и все. Теперь CEGUI полностью установлен и получает события клавиатуры и мыши.
ОКНА, ЛИСТЫ и ВИДЖЕТЫ
ВВЕДЕНИЕ
CEGUI очень отличается от большинства GUI систем.
В CEGUI, все что выводится это подкласс класса CEGUI::Window, и у окна может быть любое число дочерних окон.
Это означает, что вы создаете фрейм, чтобы содержать многочисленные кнопки, и этот фрейм - объект Window.
Это приводит к тому, что случаются странные вещи.
Вы можете поставить кнопку внутрь другой кнопки, хотя это может на самом деле никогда не случиться на практике.
Причина по которой я упомянул это все, такая, когда вы смотрите на определенный widget, который вы расположили в приложении, они все называются Window, и доступ к ним осуществляется функцией которая вызывает их по существу .
В большинстве случаев использования CEGUI, вам не нужно создавать каждый индивидуальный объект по всему коду.
Напротив вы создаете выводное окно GUI для вашего приложения в редакторе, таком как CEGUI Layout Editor(редактор вывода CEGUI).
После того, как разместите все ваши окна, кнопки и другие виджеты на экране, как вам нравиться, редактор сохранит вывод в текстовый файл.
Затем, вы можете загрузить этот вывод в то, чем CEGUI вызывает лист GUI (который также является подклассом CEGUI::Window ).
Наконец, знайте, что CEGUI содержит большое количество виджетов, которые вы можете использовать в вашем приложении.
Мы не будем описывать их в этом руководстве, поэтому если вы решите использовать CEGUI, удостоверьтесь, что вы можете внимательно посмотреть на их сайт, для дополнительной информации.
ЗАГРУЗКА ЛИСТА
В CEGUI загрузить лист очень просто.
Класс WindowManager предоставляет функцию "loadWindowLayout", которая загружает лист и кладет его в объект CEGUI::Window.
Затем вы вызываете CEGUI::System::setGUISheet, чтобы вывести его на экран.
Мы не будет использовать его в этом руководстве, но я бы чувствовал, что я невнимательный к вам, если бы хотя бы не показал пример его использования.
Не добавляйте этот пример в этом руководство(или если вы это сделайте, уберите его после того как увидите результаты):
Так устанавливается лист, который сейчас используется.
Позже, вы можете вернуть этот лист, вызвав фунцкию System::getGUISheet.
Вы также можете плавно поменять лист GUI, вызвав setGUISheet с любым листом, на который вы хотите его поменять(хотя будьте уверены, что держите указатель на этот лист, если вы хотите вернуть его обратно ).
СОЗДАНИЕ ОБЪЕКТА ВРУЧНУЮ
Как я уже говорил ранее, в большинстве раз, когда вы используете CEGUI, вы будете использовать листы GUI, которые вы создаете, использую редактор.
Однако иногда, вам нужно будет вручную создать виджет, который вы разместите на экране.
В этом примере, мы добавим кнопку Quit , в которую далее мы добавим функциональность.
Поскольку мы будем добавлять больше, чем просто кнопку Quit на экран к тому времени, когда закончиться это руководство, нам нужно во-первых будет создать основной объект CEGUI::Window, который будет содержать все виджеты, которые мы сделаем.
Добавьте это в конец функции createScene:
Она использует WindowManager, для того, чтобы создать окно "DefaultWindow", называемое "CEGUIDemo/Sheet".
Хотя мы можем обозвать окно как нам хочется, очень часто(и поощряется) название виджета на иерархический манер, так, например, как "SomeApp/MainMenu/Submenu3/CancelButton".
Следующее что мы сделаем, это создадим кнопку Quit и установим ее размер:
Это очень близко к тому, чтобы быть загадочным.
CEGUI использует "единообразное измерение" системы, для задания ее размеров и позиций.
Когда вы устанавливаете размер, то должны создать объект UDim, чтобы сообщить ему, какой размер должен быть.
Первый параметр - это относительный размер объект в зависимости от его родителей.
Второй параметр - это абсолютный размер объекта (в пикселях).
Важная вещь, которую нужно реализовать состоит в том, что вы предполагаете только набор из одного или двух параметров в UDim.
Другой параметр должен быть 0.
Поэтому в этом случае мы делаем кнопку, у которой 15% ширина и высота 5%, ширины и высоты родителя соответственно.
Если вы хотите определить, что она должна быть 20 пикселей на 5 пикселей, мы сделаем это установим, чтобы второй параметр в обоих вызовах UDim был 20 на соответственно.
Последняя вещь, которую мы собираемся сделать - это прикрепить кнопку Quit к листу, который мы сделали, и затем установить, чтобы текущей лист GUI для системы был именно этим листом.
Теперь, если вы скомпилируете и запустите ваше приложение, то вы увидите кнопку Quit в верхнем левом углу вашего экрана, но он до сих пор ничего не делает, когда вы по нажимаете на него.
СОБЫТИЯ
События в CEGUI очень гибкие.
Вместо использования интерфейса, который вы реализуете для получения событий, он использует механизм вызова который биндит любую публичную функцию(с соответствующим методом подписи) на указатель события.
К сожалению, это означает только, что регистрация события всего лишь немногим более сложная.
Теперь мы зарегистрируем кнопку Quit, чтобы она управляла событием click(щелчок), для выхода из программы, когда она нажата.
Чтобы это сделать, вам нужен указатель на кнопку Quit, который мы сделали в предыдущей секции.
Добавьте следующий код к BasicTutorial7::createScene, после того как вы создадите кнопку выхода из окна:
Это будет присоединяться к события выхода.
У каждого виджета в CEGUI есть набор событий, который он поддерживает, и они все начинаются с "Event".
Первый параметр переданный subscribeEvent - это само событие.
Второй параметр - это объект Event::Subscriber.
Когда вы создаете объект Subcriber (подписчик), первая вещь, которую вам нужно передать - это указатель на функцию, который будет управлять этим событием(отметим символ &, который дает нам указатель на функцию).
Вторая вещь, которую мы передаем подписчику - это объект BasicTutorial7, который будет управлять событием(который является объектом "this")
Вот оно!
Наша функцию BasicTutorial7::quit (которая уже была определена) будет управлять щелчком мыши и завершать программу.
Добавьте следующий код в BasicTutorial7::quit (заменяя его содержимое):
Скомпилируйте и запустите наше приложение, чтобы протестировать это.
Одна вещь, которую отметим - это то, что мы можем создать любое количество функций для управления событиями в CEGUI.
Единственное ограничение, накладываемое на них, состоит в том, что они могут вернуть булево значение или могут принять один параметр типа "const CEGUI::EventArgs &".
Если вы хотите больше информации о событиях(и как отписываться от них), обязательно почитайте еще и на сайте CEGUI.
РЕНДЕР В ТЕКСТУРУ
Одна более интересная вещь, которую мы можем сделать с CEGUI - это создание окна рендеринга текстур
Это позволяет нам создать второй Viewport , который может быть отрендерен напрямую в нашем виджите CEGUI.
Чтобы это сделать, во-первых нам нужно установить сцену, на которую будем смотреть.
Добавьте следующий код к функции createScene:
Теперь мы создали RenderTexture.
Объект RenderSystem дает функциональную возможность рендеринга текстур.
Чтобы это сделать мы создаем текстуру с функцией TextureManager::createManual.
Для этой программы мы создадим текстуру 512 x 512:
Смотрите справочное руководство по API, чтобы получить больше информации об этой функции.
Затем нам нужно создать Camera и Viewport, чтобы смотреть на сцену, которую мы создали.
Отметим, что мы изменили пару опций Viewport, включая выключение оверлейев... что более важно сделать или вы получите оверлеи CEGUI и Ogre внутри мини-окна.
Отметим, что мы добавили Viewport к самой текстуре(в отличии от RenderWindow, который находится там, где мы обычно добавляем объекты Viewport).
Теперь, поскольку мы создали сцену и нашу текстуру, нам нужно встроить ее внутрь CEGUI.
Вы можете создать CEGUI::Texture из любой текстуры Ogre, вызвав фукнцию CEGUI::OgreRenderer::createTexture:
К сожалению, это то место где становится сложно.
В CEGUI вам никогда не нужно иметь дело с единичной текстурой или единичным изображением.
CEGUI работает с набором картинок вместо индивидуальных изображений.
Очень полезно работать с целыми сетками изображений, где вы пытаетесь определить впечатление и ощущения от скина, который вы создали(например, взгляните на TaharezLook.tga в папке datafiles/imagesets из CEGUI SDK, чтобы увидеть как набор картинок выглядит).
Однако, даже когда вы просто пытаетесь определить одно изображение, вам нужно сделать целое набор изображений для него.
Это то, что мы будем делать:
Первая линия делает набор изображений(называемый "RTTImageset") из текстуры, которой мы его предоставили.
Следующая строка(которая вызывает defineImage), определяет, что первая и единственная картинка называется "RTTImage" и она настолько большая как вся текстура guiTex, которую мы предоставили.
Наконец, нам нужно создать виджет StaticImage, который будет домом для текстуры рендеринга.
Первая часть не отличается от создания любого окна:
Теперь нам нужно определить, какую картинку виджет StaticImage будет выводить.
Еще раз, поскольку CEGUI работает с набором картинка а не с отдельными картинками, нам нужно возвратить определенное имя картинки из набора картинок, и чтобы ее вывести сделать это:
Это выглядит как будто бы мы упакавали текстуру в набор картинок только чтобы распаковать их снова потому, что это именно то, что нам нужно сделать.
Управление картинками в CEGUI - это не самая простая или наиболее прямолинейная вещь в этой библиотеке.
Последняя вещь, которую нам нужно сделать - это добавить виджет StaticImage к листу GUI, который мы сделали ранее:
Теперь мы закончили. Скомпилируйте и запустите это приложение.
Переведено на Нотабеноиде
http://notabenoid.org/book/19615/64005
Переводчики: wuffur, ghostintheshell, proVIDec, cin
Настройки
Готово:
