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

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

Друзья сайта

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

Кто онлайн

Статистика

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

Система Частиц - Часть 2: Реализация

 Часть 2:Реализация

 
 
Render:
 
void PSystem::render()
{
 _D3DMATRIX  worldMoveMatrix;
 _D3DMATRIX  worldMatrix;
 
 D3DXMatrixIdentity(worldMatrix);
 D3DXMatrixTranslation(worldMoveMatrix,_origin->x,_origin->y,_origin->z);
 D3DXMatrixMultiply(worldMatrix,worldMatrix,worldMoveMatrix);
 _device->SetTransform(D3DTS_WORLD, worldMatrix);
 
     
     
          // Установка режимов визуализации
       _device->SetRenderState(D3DRS_LIGHTING, false);
       _device->SetRenderState(D3DRS_POINTSPRITEENABLE, true);
       _device->SetRenderState(D3DRS_POINTSCALEENABLE, true);
       _device->SetRenderState(D3DRS_POINTSIZE, d3d::FtoDw(_size));
       _device->SetRenderState(D3DRS_POINTSIZE_MIN, d3d::FtoDw(0.0f));
 
       // Управление изменением размера частицы
       // в зависимости от расстояния до нее
       _device->SetRenderState(D3DRS_POINTSCALE_A, d3d::FtoDw(0.0f));
       _device->SetRenderState(D3DRS_POINTSCALE_B, d3d::FtoDw(0.0f));
       _device->SetRenderState(D3DRS_POINTSCALE_C, d3d::FtoDw(1.0f));
 
       // Для текстуры используется альфа-смешивание
       _device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
       _device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
       _device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
       _device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
       _device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
 
          _device->SetTexture(0, _tex);
          _device->SetFVF(Particle::FVF);
          _device->SetStreamSource(0, _vb, 0, sizeof(Particle));
 
          // Если мы достигли конца буфера вершин,
          // возвращаемся к его началу
          if(_vbOffset >= _vbSize)
               _vbOffset = 0;
 
          Particle* v = 0;
 
          _vb->Lock(
                _vbOffset * sizeof(Particle),
                _vbBatchSize * sizeof(Particle),
                (void**)&v,
                _vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);
 
          DWORD numParticlesInBatch = 0;
 
          //
          // Пока все частицы не будут визуализированы
          //
          std::list<Attribute>::iterator i;
          for(i = _particles.begin(); i != _particles.end(); i++)
          {
               if(i->_isAlive)
               {
                    //
                    // Копируем партию живых частиц в
                    // очередной сегмент буфера вершин
                    //
                    v->_position = i->_position;
                    v->_color = (D3DCOLOR)i->_color;
                    v++; // следующий элемент;
 
                    numParticlesInBatch++; // увеличиваем счетчик партий
 
                    // партия полная?
                    if(numParticlesInBatch == _vbBatchSize)
                    {
                         //
                         // Рисуем последнюю партию частиц, которая
                         // была скопирована в буфер вершин.
                         //
                         _vb->Unlock();
 
                         _device->DrawPrimitive(
                                      D3DPT_POINTLIST,
                                      _vbOffset,
                                      _vbBatchSize);
                         //
                         // Пока партия рисуется, начинаем заполнять
                         // следующую партию частиц.
                         //
                         // Увеличиваем смещение к началу следующей партии
 
                         _vbOffset += _vbBatchSize;
 
                         // Проверяем не вышли ли мы за пределы буфера вершин.
                         // Если да, то возвращаемся к началу буфера.
                         if(_vbOffset >= _vbSize)
                              _vbOffset = 0;
 
                         _vb->Lock(
                               _vbOffset * sizeof(Particle),
                               _vbBatchSize * sizeof(Particle),
                               (void**)&v,
                               _vbOffset ? D3DLOCK_NOOVERWRITE :
                                                     D3DLOCK_DISCARD);
 
                         numParticlesInBatch = 0; // обнуляем количество частиц в партии
                    }//конец инструкции if
               }//конец инструкции if
          }//конец инструкции for
 
          _vb->Unlock();
 
          // Возможно, ПОСЛЕДНЯЯ партия частиц начала заполняться,
          // но не была визуализирована, потому что условие
          // (numParticlesInBatch == _vbBatchSize) не было выполнено.
          // Сейчас мы нарисуем эту последнюю частично заполненную партию частиц
          if( numParticlesInBatch )
          {
               _device->DrawPrimitive(
                              D3DPT_POINTLIST,
                              _vbOffset,
                              numParticlesInBatch);
          }
 
          // Следующий блок
          _vbOffset += _vbBatchSize;
 
     _device->SetRenderState(D3DRS_LIGHTING,          true);
     _device->SetRenderState(D3DRS_POINTSPRITEENABLE, false);
     _device->SetRenderState(D3DRS_POINTSCALEENABLE,  false);
     _device->SetRenderState(D3DRS_ALPHABLENDENABLE,  false);
     
}// конец метода render()
 
Delphi
 
 
 
function PSystem.Draw:HResult;
var
 Flags: DWord;
 numParticlesInBatch: DWord;
 v:PPointVertex;
 m_particle:PAttribute;
 WorldMoveMatrix:TD3DMatrix;
 WorldMatrix:TD3DMatrix;
begin
 D3DXMatrixIdentity(WorldMatrix);
 D3DXMatrixTranslation(WorldMoveMatrix,FOrigin.x,FOrigin.y,FOrigin.z);
 D3DXMatrixMultiply(WorldMatrix,WorldMatrix,WorldMoveMatrix);
 FDevice.SetTransform(D3DTS_WORLD, WorldMatrix);
 with FDevice do begin
  SetRenderState(D3DRS_LIGHTING, ifalse);
  SetRenderState(D3DRS_POINTSPRITEENABLE, itrue);
  SetRenderState(D3DRS_POINTSCALEENABLE, itrue);
  SetRenderState(D3DRS_POINTSIZE, FToDW(FSize));
  SetRenderState(D3DRS_POINTSIZE_MIN, FToDW(0.0));
 
  // Управление изменением размера частицы
  // в зависимости от расстояния до нее
  SetRenderState(D3DRS_POINTSCALE_A, FToDW(0.0));
  SetRenderState(D3DRS_POINTSCALE_B, FToDW(0.0));
  SetRenderState(D3DRS_POINTSCALE_C, FToDW(1.0));
 
  // Для текстуры используется альфа-смешивание
  SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  SetRenderState(D3DRS_ALPHABLENDENABLE, itrue);
  
  SetStreamSource(0, FVB, 0, SizeOf(TPointVertex));
  SetFVF(FVFPoint);
  FTex.SetToDevice(0);
 end;
 
 m_particle:=FParticle;
 
 //inc(vbOffset,vbBatchSize);
 vbOffset:=0;
 if(vbOffset >= vbSize) then
  vbOffset:= 0;
 if vbOffset=0 then Flags:= D3DLOCK_DISCARD else Flags:= D3DLOCK_NOOVERWRITE;
 numParticlesInBatch:=0;
 FVB.Lock( vbOffset * sizeof(v),vbBatchSize * sizeof(v),
                               pointer(v), Flags);
 
 while Assigned(m_particle) do begin
  if m_particle._isAlive then begin
   v.v:=m_particle._position;
   v.color:=m_particle._color;
   Inc(v);
   Inc(numParticlesInBatch);
   if numParticlesInBatch=vbBatchSize then begin
    FVB.Unlock;
        FEngine.Device.DrawPrimitive(D3DPT_PointList,vbOffset,vbBatchSize) ;
 
    Inc(vbOffset,vbBatchSize);
 
    if(vbOffset >= vbSize) then
     vbOffset:= 0;
    if vbOffset=0 then Flags:= D3DLOCK_DISCARD else Flags:= D3DLOCK_NOOVERWRITE;
 
    FVB.Lock( vbOffset * sizeof(v),vbBatchSize * sizeof(v),
                               pointer(v), Flags);
    numParticlesInBatch:=0;
   end;
  end;
  m_particle:=m_particle._next;
 end;
 FVB.Unlock;
 
 
 if numParticlesInBatch <> 0 then
   FEngine.Device.DrawPrimitive(D3DPT_PointList,vbOffset,vbBatchSize
 
 Inc(vbOffset,vbBatchSize);
 
 with FEngine.Device do begin
  SetRenderState(D3DRS_LIGHTING,          itrue);
  SetRenderState(D3DRS_POINTSPRITEENABLE, ifalse);
  SetRenderState(D3DRS_POINTSCALEENABLE,  ifalse);
  SetRenderState(D3DRS_ALPHABLENDENABLE,  ifalse);
 end;
 
end;
 
Load Texture From File:
 
C++
void PSystem::loadtexturefromfile(char* texFileName);
{
 D3DXCreateTextureFromFile(_device, texFileName ,_tex);
}
 
Delphi
procedure PSystem.LoadTextureFromFile(filename:string);
begin
 D3DXCreateTextureFromFile(FDevice,PChar(filename),FTexture);;
end;
 
 
Теперь добавим несколько функций.
C++ 
 
DWORD d3d::FtoDw(float f)
{
 return *((DWORD*)&f);
}
 
 
float d3d::GetRandomFloat(float lowBound, float highBound)
{
     if(lowBound >= highBound) // неправильные параметры
          return lowBound;
 
     // Получаем случайное число в диапазоне [0, 1]
     float f = (rand() % 10000) * 0.0001f;
 
     // Возвращаем число из диапазона [lowBound, highBound]
     return (f * (highBound - lowBound)) + lowBound;
}
void d3d::GetRandomVector(
                 D3DXVECTOR3* out,
                 D3DXVECTOR3* min,
                 D3DXVECTOR3* max)
{
     out->x = GetRandomFloat(min->x, max->x);
     out->y = GetRandomFloat(min->y, max->y);
     out->z = GetRandomFloat(min->z, max->z);
}
 
Delphi
 
function FToDW(f:single):DWord;
begin
 Result:= PDWord(@f)^;
end;
 
function GetRandomFloat(low,hight:single):single;
var
 f:single;
begin
 if (low >= hight) then begin
  result:=low;
  exit;
 end;
 f:= (Random(10000)) * 0.0001;
 Result:= (f * (hight - low)) + low;
end;
 
procedure GetRandomVector(min,max:d3dvector;out v:d3dvector);
begin
 v.x := GetRandomFloat(min.x, max.x);
 v.y := GetRandomFloat(min.y, max.y);
 v.z := GetRandomFloat(min.z, max.z);
end;
 
 
GetRandomFloat - Функция возвращает случайное число с плавающей точкой.

GetRandomVector - функция возвращает случайный вектор в параллелепипеде, заданном двумя углами min и max.

Ну вот впринцыпи и все.


Источник: http://qxray.110mb.com/
Категория: Ваши статьи | Добавил: Svake (30.06.2008) | Автор: Вячеслав
Просмотров: 1623 | Комментарии: 1 | Рейтинг: 0.0/0 |
Всего комментариев: 1
1 ecOnceica  
0
http://www.formspring.me/fastbuyonline - buy clonazepam with mastercard

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

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