Четверг, 19.06.2025, 13:27
Приветствую Вас Гость | RSS
Поиск
Главная | Каталог статей | Регистрация | Вход
Direct3D. Разработка игр
Форма входа
Меню сайта

Категории каталога
Мои статьи [3]
Ваши статьи [37]
Сюда вы можете выставлять свои статьи (только для зарегистрированных пользователей)

Друзья сайта

Наш опрос
Как вам этот сайт?
Всего ответов: 188

Кто онлайн

Статистика

Главная » Статьи » Ваши статьи

Система Частиц - Часть 1: Основы

Система Частиц

Часть 1:Основы

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

В нашей системе частиц мы будем использовать точечный спрайт. Почему точечный спрайт, а не billboard например. Да потому что для billboard’а нужно 4 точки, а для точечного спрайта одну!

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

 

С++

struct Particle
{
     D3DXVECTOR3  _v;
     D3DCOLOR     _color;
     static const DWORD FVF;
};
const DWORD Particle::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
 

Delphi

const

 FVF = D3DFVF_XYZ or D3DFVF_DIFFUSE;

type

 

 PParticle = ^TParticle;

 TParticle = packed record

  v: TD3DXVector3;

  color: TD3DColor;

 end;

 PParticleArray = ^TParticleArray;

 TParticleArray = array [0..0] of TParticle;

 

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

Итак, приступим к написанию компонента частиц.

Хотя  различные системы частиц ведут себя по разному, мы можем выделить общее между всеми частиц.

 

C++

 

class PSystem
{
public:
     PSystem();
     virtual ~PSystem();
     virtual bool init(IDirect3DDevice9* device);
     virtual void reset();
     virtual void resetParticle(Attribute* attribute) = 0;
     virtual void addParticle();
     virtual void update(float timeDelta) = 0;
 
     virtual void render();
     virtual void loadtexturefromfile(char* texFileName);
     
 
protected:
     virtual void removeDeadParticles();
 
protected:
     IDirect3DDevice9*       _device;
     D3DXVECTOR3             _origin;
     d3d::BoundingBox        _boundingBox;
     float                   _emitRate;
     float                   _size;
     IDirect3DTexture9*      _tex;
     IDirect3DVertexBuffer9* _vb;
     std::list<Attribute>    _particles;
     int                     _maxParticles;
     
 
     DWORD _vbSize;
     DWORD _vbOffset;
     DWORD _vbBatchSize;
};
 
Delphi
TBoundingBox=record
min,max:d3dvector;
end;
 
PSystem=class
  private
   FDevice:IDirect3DDevice9
   FOrigin:D3DVector;
   FBoundingBox:TBoundingBox;
   FEmitRate:single;
   FSize:single;
   FTex:TEngineTexture;
   FVB:IDirect3DVertexBuffer9;
   FMaxParticles:integer;
   FParticle:PAttribute;
 
   vbSize:DWord;
   vbOffset:DWord;
   vbBatchSize:DWord;
 
  
  public
   function Init(device:IDirect3DDevice9):HResult;
   procedure ResetParticle(p:PAttribute);virtual;abstract;
   procedure Update(dt:single);virtual;abstract;
   procedure Reset;
   procedure AddParticle;
   procedure RemoveDeadParticles;
 
   property Particle:PAttribute read FParticle write FParticle;
   property Origin:d3dvector read FOrigin write FOrigin;
   property BB:TBoundingBox read  FBoundingBox write FBoundingBox;
   property Size:single read FSize write FSize;
   property Texture:TEngineTexture read FTex write FTex;
 
   function Render:HResult;virtual;
 
 
   property Effect:ID3DXEffect read FEffect write FEffect;
   procedure LoadTextureFromFile(filename:string);
 end;
 
Итак,
origin – местоположение системы
boundingBox – ограничивающий систему BB;
emitRate – частота добавления частиц(частицы в секунду)
size – размер частицы
tex - текстура
particles – в случае для C++ я использую маркер, в Delphi же использую просто одну частицу с чайлдом.
maxParticles – максимальное число частиц
 
vbSize – кол-во частиц, которое может поместиться в вертексный буфер
vbOffset – кол-во обработанных частиц
vbBatchSize – кол-во обрабатываемых частиц за один проход
 
init – инициализация
resetParticle – процедура сброса одной частицы к стандартным настройкам
addParticle – добавление частицы
update - процедура обновления данных всех частиц
render – процедура прорисовки всех частиц
removeDeadParticles – удаление мертвых частиц
 
Частица имеет следующий вид:
C++
struct Attribute
{
     D3DXVECTOR3 _position;
     D3DXVECTOR3 _velocity;
     D3DXVECTOR3 _acceleration;
     float       _lifeTime;
     float       _age;
     D3DXCOLOR  _color;
     D3DXCOLOR  _colorFade;
     bool       _isAlive;
};
 
Delphi
PAttribute=^Attribute;
Attribute=record
  _position:D3DVector;
  _velocity:D3DVector;
  _acceleration:D3DVector;
  _lifeTime:single;
  _age:single;
  _color:D3DCOLOR;
  _colorFade:D3DCOLOR;
  _isAlive:boolean;
  _next:PAttribute;
end
 
position – позиция частицы
velocity – скорость частицы
acceleration – ускорение частицы
lifetime – время жизни частицы
age – кол-во времени, которое живет частица
color – цвет частицы
colorFade - как цвет частицы меняется с течением времени
isAlive – жива ли частица?
для Delphi
next чайлд
 
Описание базовых функций системы частиц:
 
Init:
 
 
 
C++
void PSystem::init(IDirect3DDevice9* device);)
{
 _devoce = device;
 device->CreateVertexBuffer(
       _vbSize * sizeof(Particle),
       D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS | D3DUSAGE_WRITEONLY,
       Particle::FVF,
       D3DPOOL_DEFAULT,
       &_vb,
       0);
 
 
   }
Delphi
function PSystem.Init(device:IDirect3DDevice9):HResult;
begin
FDevice:= device;
Result:=FDevice.CreateVertexBuffer( vbSize * sizeof(TParticle),
       D3DUSAGE_DYNAMIC or D3DUSAGE_POINTS or D3DUSAGE_WRITEONLY,
       FVF, D3DPOOL_DEFAULT, FVB, 0);
end;
 
Reset:
 
C++
void PSystem::reset()
{
     std::list<Attribute>::iterator i;
     for(i = _particles.begin(); i != _particles.end(); i++)
     {
          resetParticle(&(*i));
     }
}
 
Delphi
 
procedure PSystem.Reset;
var
 i:integer;
 m_particle:PAttribute;
begin
 m_particle:=FParticle;
 while Assigned(m_particle) do begin
  ResetParticle(m_particle);
  m_particle:=m_particle._next;
 end;
end;
 
Add Particle:
 
C++
void PSystem::addParticle()
{
     Attribute attribute;
 
     resetParticle(&attribute);
 
     _particles.push_back(attribute);
}
Delphi
 
procedure PSystem.AddParticle;
var
 m_particle:PAttribute;
 t_particle:Attribute;
begin
 m_particle:=FParticle;
 while Assigned(m_particle) do 
 begin
  m_particle:=m_particle._next;
 end;
 New(m_particle);
 ResetParticle(m_particle);
 m_particle._next:=FParticle;
 FParticle:= m_particle;
end;


Источник: http://qxray.110mb.com/
Категория: Ваши статьи | Добавил: Svake (30.06.2008) | Автор: Вячеслав
Просмотров: 1865 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Doom†Cross Software ® 2025
Создать бесплатный сайт с uCoz