SDK: Улучшаем главное меню


В этой статье будет показан процесс отрисовки 3D моделей в главном меню и воспроизведение музыки.

Добавление 3D моделей в меню


Откройте файл GameMP/Game.cpp В начале файла включим заголовочный файл модели, которую будем использовать. Это необходимо для использования аттачментов через удобные макро-имена.

#include <Models/Enemies/Headman/headman.h>

 

В глобальной области необходимо определить несколько переменных:

static CModelObject g_ModelObject;
static CPlacement3D g_ModelPlacement = CPlacement3D(FLOAT3D(0, -1.0, -1.75), ANGLE3D(16000));
static FLOAT3D      g_LightDirection = FLOAT3D(0.2f, -0.2f, -0.2f).Normalize();
static COLOR        g_LightDiffuseColor = C_GRAY;
static COLOR        g_LightAmbientColor = C_vdGRAY;

 

По их именам легко понять их назначение. Определяются эти переменные в глобальной области для того, чтобы их значение сохранялось между вызовами отрисовки. Сами значения подобраны случайно, их можно менять любым образом.

Для удобства также добавим следующую вспомогательную функцию, которая поможет добавлять модели аттачменты с текстурами:

CModelObject& AddAttachmentToModel
(
  CModelObject&     parentModel,
  INDEX             attachmentIndex,
  const CTFileName& modelFilename,
  const CTFileName& diffuseTextureFilename,
  const CTFileName& reflectionTextureFilename = CTFILENAME(""),
  const CTFileName& specularTextureFilename = CTFILENAME("")
)
{
  CAttachmentModelObject* pamo = parentModel.AddAttachmentModel(attachmentIndex);
  ASSERT(pamo != NULL);
  pamo->amo_moModelObject.SetData_t(modelFilename);
  pamo->amo_moModelObject.mo_toTexture.SetData_t(diffuseTextureFilename);
 
  if (reflectionTextureFilename.Length() > 0)
    pamo->amo_moModelObject.mo_toReflection.SetData_t(reflectionTextureFilename);
 
  if (specularTextureFilename.Length() > 0)
    pamo->amo_moModelObject.mo_toSpecular.SetData_t(specularTextureFilename);
 
  return pamo->amo_moModelObject;
}

 

Сама отрисовка происходит в следующей функции:

void CGame::LCDRenderClouds1(void)

В самом ее конце поочередно добавляем следующие строчки кода:

if (_bPopup)
  return;

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

Следующий блок кода:

if (g_ModelObject.GetData() == NULL)
{
  g_ModelObject.SetData_t(CTFILENAME("Models\\Enemies\\Headman\\Headman.mdl"));
  g_ModelObject.mo_toTexture.SetData_t(CTFILENAME("Models\\Enemies\\Headman\\Rocketman.tex"));
  AddAttachmentToModel(
    g_ModelObject,
    HEADMAN_ATTACHMENT_HEAD,
    CTFILENAME("Models\\Enemies\\Headman\\Head.mdl"),
    CTFILENAME("Models\\Enemies\\Headman\\Head.tex"));
  AddAttachmentToModel(
    g_ModelObject,
    HEADMAN_ATTACHMENT_ROCKET_LAUNCHER,
    CTFILENAME("Models\\Enemies\\Headman\\RocketLauncher.mdl"),
    CTFILENAME("Models\\Enemies\\Headman\\RocketLauncher.tex"),
    CTFILENAME("Models\\ReflectionTextures\\LightMetal01.tex"),
    CTFILENAME("Models\\SpecularTextures\\Weak.tex"));
 
  g_ModelObject.PlayAnim(HEADMAN_ANIM_WALKAOF_LOOPING | AOF_NORESTART);
}

Тут производится начальная настройка модели.

Для примера была выбрана модель безголового ракетчика. Используя вспомогательную функцию, к нему сразу добавляются модели головы и оружия. Также у модели запускается проигрывание анимации ходьбы.

 

CPerspectiveProjection3D projection;
projection.FOVL() = AngleDeg(90.0f);
projection.ScreenBBoxL() = FLOATaabbox2D(
  FLOAT2D(0.0f0.0f),
  FLOAT2D(static_cast<float>(_pdp_SE->GetWidth()), static_cast<float>(_pdp_SE->GetHeight())));
projection.AspectRatioL() = 1.0f;
projection.FrontClipDistanceL() = 0.1f;
projection.ViewerPlacementL() = CPlacement3D(FLOAT3D(000), ANGLE3D(000));

Данный блок кода подготавливает проекцию, с помощью которой будет отрисована модель.

В примере проекция будет иметь горизонтальный угол обзора в 90 градусов, обозримая область будет занимать весь экран, а наблюдатель (камера) будет находится в нуле координатной системы.

Ближняя плоскость отсечения помещена на расстоянии 0.1. В общем случае это может быть любое число больше нуля, но желательно чтобы оно было небольшим, чтобы плоскость не отсекала часть видимой модели.

Стоит заметить, что в этой проекции соотношение сторон выставлено в 1. Это сделано по причине того, что размер экрана уже передан в обозримую область, и соотношение будет автоматически учтено.

 

_pdp_SE->FillZBuffer(1.0f);
CAnyProjection3D genericProjection;
genericProjection = projection;
BeginModelRenderingView(genericProjection, _pdp_SE);
 
CRenderModel renderModel;
renderModel.rm_vLightDirection = g_LightDirection;
renderModel.SetObjectPlacement(g_ModelPlacement);
renderModel.rm_colLight = g_LightDiffuseColor;
renderModel.rm_colAmbient = g_LightAmbientColor;
 
g_ModelObject.SetupModelRendering(renderModel);
g_ModelObject.RenderModel(renderModel);
EndModelRenderingView();

В этом блоке кода произведена отрисовка модели.

Перед самой отрисовкой, буфер глубины очищается, это необходимо для того, чтобы модель рисовалась поверх фона.

Остальные строки кода заполняют заранее подготовленую информацию об отрисовке (положение модели, направление света, цвет).

После сборки и запуска, результат должен быть следующий:

 

Воспроизведение музыки


Для воспроизведения музыки необходимо ей выделить один из доступных каналов.

#define MUSIC_CHANNEL 0

Всего их доступно MAX_SCRIPTSOUNDS, причем последний ( MAX_SCRIPTSOUNDS-1) зарезервирован.

Перейдите к определению следующей функции:

void CGame::StopGame(void)

В ее начало необходимо добавить следующие строки:

if (IsScriptSoundPlaying(MUSIC_CHANNEL))
  StopScriptSound(MUSIC_CHANNEL);

Они остановят воспроизведение музыки, когда показывается экран титров.

Также этот блок необходимо вставить в конце функции

void CGame::GameMainLoop(void)

Конец этой функции должен выглядить следующим образом:

if (gm_bGameOn) {
  // do main loop procesing
  if (IsScriptSoundPlaying(MUSIC_CHANNEL))
    StopScriptSound(MUSIC_CHANNEL);
 
  _pNetwork->MainLoop();
}

Осталось только воспроизвести музыку. Для этого необходимо перейти к определению следующей функции:

void CGame::LCDRenderClouds1(void)

И в самом ее начале добавить следующий блок кода:

if (!IsScriptSoundPlaying(MUSIC_CHANNEL))
{
  FLOAT volume = 1.0f;
  FLOAT pitch = 1.0f;
  BOOL looping = TRUE;
  PlayScriptSound(MUSIC_CHANNELCTFILENAME("Music\\Fight\\Fight05.ogg"), volume, pitch, looping);
}

Тут можно выбрать необходимый файл музыки, настроить высоту, громкость и включить либо выключить ее зацикленность.


Таким образом возможно улучшить главное меню, разнообразив его моделями с анимацией на фоне (либо вовсе заменив фон на модель) и добавив музыки.



Комментарии   

[Материал]  |  № 17  |  29.04.2012  |  0  
Хорошая статья пригодится в моде!
Ответ Цитата

[Материал]  |  № 16  |  16.04.2012  |  +1  
Жаль что статьи по сдк часто не выходят
Ответ Цитата

[Материал]  |  № 15  |  13.04.2012  |  0  
Полезная статья.Мне очень пригодилась :)
Ответ Цитата

[Материал]  |  № 10  |  07.04.2012  |  +1  
Хорошо, практично, молодёжно! ))
Только у тебя в первом большом блоке кода есть html теги после "Это наша модель", хорошо бы было их выпилить. =)
Ответ Цитата

[Материал]  |  № 11  |  07.04.2012  |  0  
Спасибо, поправил)
Ответ Цитата

[Материал]  |  № 9  |  06.04.2012  |  0  
Чувак! Ты великолепен!
Ответ Цитата

[Материал]  |  № 7  |  06.04.2012  |  0  
СПАСИБО ЗА СТАТЬЮ!!!!!1! ХОЧУ В МОД СДЕЛАТЬ!!!
:D
Ответ Цитата

[Материал]  |  № 6  |  06.04.2012  |  0  
Quote (CREATER)
Сам давно ничего не строишь и ни SED, ни SDK не юзаешь


А мне типо это надо?
Ответ Цитата

[Материал]  |  № 14  |  09.04.2012  |  0  
эээ что? а другим типа не надо?
Ответ Цитата

[Материал]  |  № 19  |  01.05.2012  |  +1  
Статья делалась не по твоему заказу, так что помолчи.
Ответ Цитата

[Материал]  |  № 5  |  06.04.2012  |  0  
А обязательно шестая версия? у меня десятая просто.
А так кому не лень поюзать СДК и поднять свою жопу на изучение С++ то статья вери гут) Ну а кому лень те уже высказались.
Ответ Цитата

[Материал]  |  № 12  |  07.04.2012  |  0  
Если смогу настроить на 2010, то обязательно скажу :)
Ответ Цитата

[Материал]  |  № 13  |  07.04.2012  |  0  
Кстати да, скажи.
Ответ Цитата

[Материал]  |  № 3  |  05.04.2012  |  0  
Вообще-то, это - моя первая статья по СДК. Спасибо за такие положительные комментарии :|
Ответ Цитата

[Материал]  |  № 18  |  01.05.2012  |  +1  
Не обращай внимания, ты крут
Ответ Цитата

[Материал]  |  № 1  |  05.04.2012  |  0  
...и опять SDK - да ёклмн,без него никуда чтоли? <_<
Ответ Цитата

[Материал]  |  № 2  |  05.04.2012  |  0  
Наверное. X_X
Ответ Цитата

[Материал]  |  № 4  |  06.04.2012  |  0  
Не понимаю причину негодования. У тебя баттхёрт от его незнания? Сам давно ничего не строишь и ни SED, ни SDK не юзаешь, зато как поворчать на статью по SKD - ты тут как тут X_X
Ответ Цитата

[Материал]  |  № 8  |  06.04.2012  |  0  
SDK*
Ответ Цитата

Оставьте комментарий

Мини-профиль

Гость

Вы в группе: Гости
Ваш IP: 3.238.70.175

Информация

Прочее

Категории раздела

Croteam [4]
Материалы по студии разработчика игр CroTeam.
Интервью с разработчиками [9]
Интервью с разработчиками, а также их издателями.
Serious Sam 1 [10]
Статьи о Serious Sam 1
Serious Sam 2 [6]
Статьи о Serious Sam 2
Serious Sam HD [4]
Статьи о HD-серии, ремейков классических версий Сэма.
Serious Sam 3: BFE [9]
Статьи о Serious Sam 3: BFE
Уроки по Serious Editor 1 [58]
Уроки по Serious Editor 2 [2]
Самое серьёзное редактирование, на русском!
Уроки по Serious Editor 3 [33]
Уроки по работе с редактором.
Serious Engine [6]
Описание возможностей всех движков компании Croteam
Разное [28]
Всё что не подошло не под одну из вышеупомянутых категорий.
Serious Sam: Revolution [1]
Материалы по SS: Revolution, серьёзном обновлении классических Крутых Сэмов.
Serious Sam 1.05/1.07 SDK [9]
SDK - набор исходников для Serious Sam: The Second Encounter 1.05/1.07.

Статистика



На сайте: 13
Гостей: 10
Пользователей: 3
artem-predator, mynameisdax, Cat_N_Flammen