RoboGame blog [RIP]Статьи

Архив блога: Декабрь 2008

Автор:

Рендер: освещение закончено... вроде

Освещение закончено. Все типы источников отлажены и работают. Хотя я пока не сделал оптимизации со стенсел-буфером, но думаю это подождёт. Теперь буду прикручивать обратно тени в движок :)

Конический:
Изображение

Направленный:
Изображение

Точечный:
Изображение


Рендер: да будут тени!
Ну вот, прикрутил я наконец тени. Не обошлось конечно без проблем (http://www.gamedev.ru/code/forum/?id=88870), но спасибо форумчанам геймдева, помогли найти кое-какие опечатки в коде :)

Вообще в деферреде оказался один такой жирный минус – большая нагрузка на пиксельные шейдеры. Вот из-за этого и получилось так, что PCF размытие тени ни в какую не влезает по количеству инструкций в шейдеры версии 2.0, так что пока пришлось для тенюшек компилировать пиксельные шейдеры в версию 3.0. Это конечно совсем не айс, так как я всё таки решил поддерживать и 2.0, поэтому в будущем постараюсь как-нибудь упихать, хоть простенькие PCF2x2, в версию 2.0.

Также сделал поддержку объектов с альфа-дырками (см. на рисунке ветхий край ржавого заборчика) и рендинг от них теней.

Изображение


Физика: первые тесты
Чтож пока с рендером я решил завязать. На очереди – иерархия объектов.

class ageRenderObject
{
};

class agePhysicsObject
{
};

class ageSceneObject
{
  class ageRenderObject;
  class agePhysicsObject;
};

Вот, поднимаясь по иерархии вверх я создал класс ageSceneObject который включает в себя отрисовочный объект ageRenderObject (с которым я работал ранее) а также объект физического движка agePhysicsObject. В нём (ageSceneObject) происходит их синхронизация. Новонаписанный класс agePhysicsObject является просто обёрткой над классом физикса NxActor, и имеет специфический для моего движка функционал. Как например загрузка физической оболочки из файла.

Естественно вручную задавать оболочки это очень плохая идея. Поэтому я потратил пару дней на изучение плагинов и программ для их визуального создания и остановился бесплатном редакторе Scythe (http://www.physicseditor.com/)

Что я могу про него сказать? Хороший, интуитивно понятный редактор и прозрачный формат выходного файла. Конечно для загрузки оболочек можно использовать и их API, однако там очень много лишнего, поэтому я написал свой загрузчик их формата (благо его описание присутствует на их сайте в разделе downloads)

Вот видео того, что получилось:

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры

И тоже самое но с отладочной информацией:

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры


Иерархия игровых объектов

Работаю над иерархией и общей структурой объектов. Сначала в движке планировал разбить иерархию объектов на два класса – сцена и игровой уровень. Предполагалось, что в сцене мы храним сами пулы простых объектов, а в классе уровня – глобальные ссылки на них и пулы сложных объектов, собирающие несколько ссылок на простые объекты. Кроме того, логически, уровнь будет содержать классы конкретной игры, а сцена – более общие классы.

Вот такая была схема:

class Scene
{
     Lights
     Particles
     Decals
     SceneObjects
}

class GameObject
{
          LightsID
          ParticlesID
          DecalsID
          SceneObjectsID
 }

class GameLevel
{     
     ParticlesType
     DecalsType
     ActorsType
     StaticsType
     DynamicsType


     LightsID
     ParticlesID
     DecalsID

     Actors:GameObject;
     Static:GameObject;
     Dynamic:GameObject;
     
}

Однако, при ближайшем рассмотрении всё пошло пи… короче такая схемка не покатит. И вот почему. Во-первых, отсечение по ок-трии в целях оптимизации надо будет делать в  классе уровня, ибо отсечь один GameObject быстрее чем кучу SceneObjects, Particles и других его составляющих. Во-вторых, сомнительная радость размазывать хранение параметров для типов объекта по двум классам (например партиклы, декалы). В третьих же сериализация опять таки достаётся классу уровня.

Вот таким макаром класс Сцены становится всё худее и худее, а его значимость – всё меньше и меньше.

Вообщем волевым решением я всё перенёс в мега-класс GameScene:

class ageGameScene: public ageSingleton< ageGameScene>
{

  ageResourseManager<ageTypeInfo>  ActorsType;
  ageResourseManager<ageTypeInfo>  DynObjectsType;
  ageResourseManager<ageTypeInfo>  StatObjectsType;
  ageResourseManager<ageTypeInfo>  StatParticlesType;
  ageResourseManager<ageTypeInfo>  StatDecalsType;


  ageCDynArray<ageSceneObject>        SceneObjects; 
  ageCDynArray<ageCamera>          Cameras; 
  ageCDynArray<ageLight>          Lights; 
  ageCDynArray<ageDecal>          Decals; 
  ageCDynArray<ageParticleEmitter>      Particles; 

  ageCDynArray<ageActor>          Actors; 
  ageCDynArray<ageDynObject>        DynObjects; 
  ageCDynArray<ageStatObject>        StatObjects; 


  //world objects
  ageSimpleArray<int>      ActorsID; 
  ageSimpleArray<int>      DynObjectsID; 
  ageSimpleArray<int>      StatObjectsID; 
  ageSimpleArray<int>      LightsID; 
  ageSimpleArray<int>      ParticlesID; 
  ageSimpleArray<int>      DecalsID; 
  int            CameraID;

};

Вот такой жирдяй-класс. В нём же практически вся игра будет :-D

-----
К слову о проектировании. В голове эти все объекты у меня выглядят таким образом :-D
Изображение


Lights & shadows test

Реализую классы сцены, по принципу, рассказанному в предыдущей серии :)
   
    Не всё оказалось гладким. Точнее всё оказалось грубым и с зазубринами. Для начала неожиданно для себя узнал что стандартный вектор STL переалоцирует всю память, при резервировании. Далее оказалось что этот самый вектор требует ещё и конструктор копии для сложных агрегатных классов. В итоге – два дня на исправление моего ageDynArray (основанного на STL векторе) плюс нудное подписывание конструкторов копий для всех сложных агрегатных классов (коих у меня оказалось 12 штук).  Раньше я ничего не замечал ибо клал в свой ageDynArray только относительно простые классы, для которых компилятор генерирует конструктор копии автоматически.

    Напоследок была ещё одна весёлая штука – оказалось если и в базовом классе и в классе наследнике есть перегруженный оператор присваивания, то это отнюдь не означает что при его вызове из класса наследника, он вызовется автоматически и в базовом классе. Раньше я с такой ситуацией не сталкивался, поэтому по простоте душевной был уверен что он, как и конструктор, вызовется автоматически. Надо думаю ещё раз Страуструпа почитать на досуге :)

    В итоге, класс сцены, хоть и со скрипом, но заработал. Добавил в него пока DynObjects, StatObjects и источники света. Для тестирования класса собрал небольшую демку, в которой можно добавлять бочки (DynObjects), которые падают на статический камень (StatObjects). Ну ещё источники света можно добавлять.

Вот:

Изображение

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры

---

+ Показать

8 февраля 2009 (Обновление: 7 фев 2012)