bb_processor.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. #ifndef _XBOX
  2. #include <xmmintrin.h>
  3. #endif
  4. #include "bb_processor.h"
  5. #include "..\..\icommon\names.h"
  6. #include "..\..\icommon\IEmitter.h"
  7. #include "..\datasource\datagraph.h"
  8. #include "..\datasource\datacolor.h"
  9. #include "..\datasource\datauv.h"
  10. #include "..\..\..\common_h\render.h"
  11. #include "..\..\..\common_h\core.h"
  12. #include "..\particlesystem\particlesystem.h"
  13. #include "..\..\manager\particlemanager.h"
  14. #include "physic.h"
  15. #include "nameparser.h"
  16. #include "..\..\..\common_h\gmx.h"
  17. extern ParticleService* PService;
  18. /*
  19. Коэфицент лодирования партиклов, чем выше тем меньше нагрузка на Filrate
  20. Должен быть > 0 !!!!!!
  21. 0.001 нет лодов .. 10000000 супер лоды (все партиклы в 1 пиксель)
  22. */
  23. //=============================================================
  24. //#define PLOD 0.001f
  25. //=============================================================
  26. BillBoardProcessor* BillBoardProcessor::singleton = NULL;
  27. IRender* BillBoardProcessor::pRS = NULL;
  28. CritSection BillBoardProcessor::draw_particles;
  29. BillBoardProcessor::BillBoardProcessor () : ParticlesIdx(_FL_, PARTICLE_CHUNK),
  30. freeParticlesIdx(_FL_, PARTICLE_CHUNK),
  31. particlesData(_FL_, PARTICLE_CHUNK)
  32. {
  33. pGEOServ = NULL;
  34. //pMemArray = NEW BB_ParticleData[_MAX_BILLBOARDS];
  35. AllocParticles();
  36. BillBoardProcessor::pRS = (IRender*)api->GetService("DX9Render");
  37. Assert (BillBoardProcessor::pRS);
  38. pRS->GetShaderId("Particles", shader_particles[0]);
  39. pRS->GetShaderId("ParticlesXZ", shader_particlesXZ[0]);
  40. pRS->GetShaderId("ParticlesDistor", shader_particles_distor[0]);
  41. pRS->GetShaderId("ParticlesDistXZ", shader_particlesXZ_distor[0]);
  42. pRS->GetShaderId("Particles_overdraw", shader_particles[1]);
  43. pRS->GetShaderId("ParticlesXZ_overdraw", shader_particlesXZ[1]);
  44. pRS->GetShaderId("ParticlesDistor_overdraw", shader_particles_distor[1]);
  45. pRS->GetShaderId("ParticlesDistXZ_overdraw", shader_particlesXZ_distor[1]);
  46. pRS->GetShaderId("Particles_simple", shader_particles[2]);
  47. pRS->GetShaderId("ParticlesXZ_simple", shader_particlesXZ[2]);
  48. int RectVertexSize = sizeof(RECT_VERTEX);
  49. BillBoardProcessor::singleton = this;
  50. }
  51. BillBoardProcessor::~BillBoardProcessor ()
  52. {
  53. }
  54. //"Выделить" память для хранения партикла
  55. dword BillBoardProcessor::AllocParticle ()
  56. {
  57. if (freeParticlesIdx.IsEmpty())
  58. {
  59. if(particlesData.Size() > 16384)
  60. {
  61. return NULL;
  62. }
  63. AllocParticles();
  64. if (freeParticlesIdx.IsEmpty())
  65. {
  66. return NULL;
  67. }
  68. }
  69. dword dwIdx = freeParticlesIdx.Top();
  70. freeParticlesIdx.Pop();
  71. particlesData[dwIdx].index_in_array = dwIdx;
  72. return dwIdx;
  73. }
  74. //"Убить" партикл
  75. void BillBoardProcessor::FreeParticle (dword dwIndex)
  76. {
  77. freeParticlesIdx.Push(dwIndex);
  78. }
  79. void BillBoardProcessor::AddParticle (const Vector& addVel, ParticleSystem* pSystem, const Vector& velocity_dir, const Vector& pos, const Matrix& matWorld, float EmitterTime, float EmitterLifeTime, FieldList* pFields, DWORD* pActiveCount, IEmitter* dwGUID, float fTimeScale, float fScale, bool bForceLocalMode)
  80. {
  81. SyncroCode sync(access_to_particles);
  82. dword dwParticleIdx = AllocParticle ();
  83. BB_ParticleData* pData = &particlesData[dwParticleIdx];
  84. //Сработает если партиклов будет > MAX_BILLBOARDS, столько их быть не должно :))))
  85. if (!pData)
  86. {
  87. *(pActiveCount) = (*(pActiveCount)-1);
  88. return;
  89. }
  90. pData->localMode = pFields->GetBool(GUID_PARTICLE_LOCAL_SYSTEM, false);;
  91. if (bForceLocalMode)
  92. {
  93. pData->localMode = true;
  94. }
  95. pData->fTimeScale = fTimeScale;
  96. pData->fAllsystemScale = fScale;
  97. /*
  98. //запоминаем все force field'ы
  99. dword dwForceFieldActive = pFields->GetForceFieldsCountFromCache();
  100. for (dword q = 0; q < 4; q++)
  101. {
  102. dword dwGuid = 0xFFFFFFFF;
  103. if (q < dwForceFieldActive) dwGuid = pFields->GetForceFieldGUIDFromCache(q);
  104. pData->dwForceFields_GUID[q] = dwGuid;
  105. }
  106. */
  107. Vector initPos;
  108. initPos.x = pFields->GetRandomGraphVal(GUID_PARTICLE_INITPOSX, EmitterTime, EmitterLifeTime);
  109. initPos.y = pFields->GetRandomGraphVal(GUID_PARTICLE_INITPOSY, EmitterTime, EmitterLifeTime);
  110. initPos.z = pFields->GetRandomGraphVal(GUID_PARTICLE_INITPOSZ, EmitterTime, EmitterLifeTime);
  111. pData->distorted = pFields->GetBool(GUID_PARTICLE_DISTORTED, false);
  112. pData->distorted_pow = pFields->FindGraphByGUID(GUID_PARTICLE_DISTORTED_POWER);
  113. pData->Graph_SpinDrag = pFields->FindGraphByGUID(GUID_PARTICLE_SPIN_DRAG);
  114. pData->Graph_Size = pFields->FindGraphByGUID(GUID_PARTICLE_SIZE);
  115. pData->Graph_SizeInc = pFields->FindGraphByGUID(GUID_PARTICLE_SIZEINC);
  116. pData->Graph_LightK = pFields->FindGraphByGUID(GUID_PARTICLE_LIGHTPOWER);
  117. pData->Graph_AmbientK = pFields->FindGraphByGUID(GUID_PARTICLE_AMBIENTPOWER);
  118. pData->Graph_Frames = pFields->FindGraphByGUID(GUID_PARTICLE_ANIMFRAME);
  119. pData->Graph_Color = pFields->FindColorByGUID(GUID_PARTICLE_COLOR);
  120. pData->Graph_ColorMul = pFields->FindGraphByGUID(GUID_PARTICLE_COLORMULTIPLY);
  121. pData->Graph_UV = pFields->FindUVByGUID(GUID_PARTICLE_FRAMES);
  122. pData->Graph_Transparency = pFields->FindGraphByGUID(GUID_PARTICLE_TRANSPARENCY);
  123. pData->Graph_Drag = pFields->FindGraphByGUID(GUID_PARTICLE_DRAG);
  124. pData->graph_GravK = pFields->FindGraphByGUID(GUID_PARTICLE_GRAVITATION_K);
  125. pData->graph_AddPower = pFields->FindGraphByGUID(GUID_PARTICLE_ADDPOWER);
  126. pData->distorted_pow_K = FRAND (1.0f);
  127. pData->xz_align = pFields->GetBool(GUID_PARTICLE_ZXALIGN, false);
  128. /*
  129. if (pFields->GetBool(GUID_PARTICLE_AFFECT_AMBIENT, false))
  130. {
  131. pData->alwaysAmbient = 0.0f;
  132. } else
  133. {
  134. pData->alwaysAmbient = 1.0f;
  135. }
  136. */
  137. pData->exForce = pFields->GetPosition(GUID_PARTICLE_EXTERNALFORCE);
  138. pData->SpeedOriented = pFields->GetBool(GUID_PARTICLE_DIR_ORIENT, false);
  139. pData->EmitterGUID = dwGUID;
  140. pData->ActiveCount = pActiveCount;
  141. if (!pData->localMode)
  142. {
  143. pData->RenderPos = (pos+initPos) * matWorld;
  144. pData->Velocity = matWorld.MulNormal(velocity_dir);
  145. pData->matWorld = matWorld;
  146. pData->matWorldInv = matWorld;
  147. pData->matWorldInv.Inverse();
  148. } else
  149. {
  150. pData->RenderPos = (pos+initPos);
  151. pData->Velocity = velocity_dir;
  152. pData->matWorld = Matrix();
  153. pData->matWorldInv = Matrix();
  154. }
  155. pData->ElapsedTime = 0.0f;
  156. pData->ExternalForce = Vector(0.0f, 0.0f, 0.0f);
  157. pData->PhysPos = pData->RenderPos;
  158. pData->OldRenderPos = pData->RenderPos;
  159. pData->OldRenderAngle = pData->RenderAngle;
  160. pData->LifeTime = pFields->GetRandomGraphVal(GUID_PARTICLE_LIFE_TIME, EmitterTime, EmitterLifeTime);
  161. pData->Mass = pFields->GetRandomGraphVal(GUID_PARTICLE_MASS, EmitterTime, EmitterLifeTime);
  162. if (pData->Mass < 0.01) pData->Mass = 0.01f;
  163. float VelocityPower = pFields->GetRandomGraphVal(GUID_PARTICLE_VELOCITY_POWER, EmitterTime, EmitterLifeTime);
  164. pData->Velocity = (pData->Velocity * VelocityPower) + addVel;
  165. pData->fInitialSize = pFields->GetRandomGraphVal(GUID_PARTICLE_INITSIZE, EmitterTime, EmitterLifeTime);
  166. pData->Spin = pFields->GetRandomGraphVal(GUID_PARTICLE_SPIN, EmitterTime, EmitterLifeTime);
  167. pData->Spin = pData->Spin * MUL_DEGTORAD;
  168. pData->Angle = pFields->GetRandomGraphVal(GUID_PARTICLE_INITIALSPIN, EmitterTime, EmitterLifeTime);
  169. pData->Angle = pData->Angle * MUL_DEGTORAD;
  170. pData->RenderAngle = pData->Angle;
  171. pData->DragK = FRAND (1.0f);
  172. pData->SpinDragK = FRAND (1.0f);
  173. pData->SizeK = FRAND (1.0f);
  174. pData->ColorK = FRAND (1.0f);
  175. pData->AlphaK = FRAND (1.0f);
  176. pData->FrameK = FRAND (1.0f);
  177. pData->GravKK = FRAND (1.0f);
  178. pData->AddPowerK = FRAND (1.0f);
  179. pData->TrackXK = FRAND (1.0f);
  180. pData->TrackYK = FRAND (1.0f);
  181. pData->TrackZK = FRAND (1.0f);
  182. pData->PhysBlendK = FRAND (1.0f);
  183. pData->LightK_K = FRAND (1.0f);
  184. const char* pEmitterName = pFields->GetString(GUID_ATTACHEDEMITTER_NAME);
  185. if (pEmitterName[0] == 'n' && pEmitterName[1] == 'o' && pEmitterName[2] == 'n' && pEmitterName[3] == 'e')
  186. //if (crt_stricmp (pEmitterName, "none") == 0)
  187. {
  188. pData->AttachedEmitter = NULL;
  189. } else
  190. {
  191. pData->AttachedEmitter = pSystem->FindEmitter(pEmitterName);
  192. if (pData->AttachedEmitter) pData->AttachedEmitter->SetAttachedFlag(true);
  193. }
  194. ParticlesIdx.Add(dwParticleIdx);
  195. }
  196. void BillBoardProcessor::DeleteDeadParticles ()
  197. {
  198. for (DWORD n = 0; n < ParticlesIdx.Size(); n++)
  199. {
  200. dword dwParticleIdx = ParticlesIdx[n];
  201. BB_ParticleData* pData = &particlesData[dwParticleIdx];
  202. float Time = pData->ElapsedTime;
  203. float LifeTime = pData->LifeTime;
  204. //Сразу убиваем дохлые...
  205. if (Time > LifeTime)
  206. {
  207. *(pData->ActiveCount) = (*(pData->ActiveCount)-1);
  208. FreeParticle (dwParticleIdx);
  209. ParticlesIdx.ExtractNoShift(n);
  210. n--;
  211. continue;
  212. }
  213. }
  214. }
  215. //Считает физику, треки и т.д.
  216. void BillBoardProcessor::UpdateParticles (float RealDeltaTime)
  217. {
  218. DWORD dwFrom = 0;
  219. DWORD dwTo = ParticlesIdx.Size();
  220. Matrix m_temp(false);
  221. DWORD processCount = 0;
  222. for (DWORD n = dwFrom; n < dwTo; n++)
  223. {
  224. dword dwParticleIdx = ParticlesIdx[n];
  225. BB_ParticleData* pData = &particlesData[dwParticleIdx];
  226. float DeltaTime = RealDeltaTime * pData->fTimeScale;
  227. pData->ElapsedTime += DeltaTime;
  228. float Time = pData->ElapsedTime;
  229. float LifeTime = pData->LifeTime;
  230. //Сразу дохлые пропускаем...
  231. if (Time > LifeTime)
  232. {
  233. continue;
  234. }
  235. float Drag = pData->Graph_Drag->GetValue(Time, LifeTime, pData->DragK);
  236. float GravK = pData->graph_GravK->GetValue(Time, LifeTime, pData->GravKK);
  237. AddGravityForce (pData->ExternalForce, pData->Mass, GravK);
  238. //pData->ExternalForce.y += GravK*pData->Mass;
  239. //внешняя сила
  240. pData->ExternalForce += pData->exForce;
  241. SolvePhysic (pData->PhysPos, pData->Velocity, pData->ExternalForce, pData->Mass, Drag, DeltaTime);
  242. pData->ExternalForce = 0.0f;
  243. float SpinDrag = pData->Graph_SpinDrag->GetValue(Time, LifeTime, pData->SpinDragK);
  244. SpinDrag = 1.0f -(SpinDrag * 0.01f);
  245. if (SpinDrag < 0.0f) SpinDrag = 0.0f;
  246. if (SpinDrag > 1.0f) SpinDrag = 1.0f;
  247. pData->Angle += (pData->Spin * SpinDrag) * DeltaTime;
  248. //Save old positions
  249. pData->OldRenderPos = pData->RenderPos;
  250. //JOKER SCALE
  251. /*
  252. pData->EmitterGUID->GetSystemTransform(pData->matWorld);
  253. pData->RenderPos = (pData->PhysPos * pData->fAllsystemScale) * pData->matWorld;
  254. */
  255. if (!pData->localMode)
  256. {
  257. pData->EmitterGUID->GetSystemTransform(m_temp);
  258. pData->RenderPos = ((pData->PhysPos - m_temp.pos) * pData->fAllsystemScale) + m_temp.pos;
  259. } else
  260. {
  261. pData->EmitterGUID->GetSystemTransform(pData->matWorld);
  262. pData->RenderPos = (pData->PhysPos * pData->fAllsystemScale) * pData->matWorld;
  263. }
  264. pData->RenderAngle = pData->Angle;
  265. /*
  266. if (pData->dwForceFields_GUID[0] != 0xFFFFFFFF ||
  267. pData->dwForceFields_GUID[1] != 0xFFFFFFFF ||
  268. pData->dwForceFields_GUID[2] != 0xFFFFFFFF ||
  269. pData->dwForceFields_GUID[3] != 0xFFFFFFFF)
  270. {
  271. bool bNeedKill = pMasterManager->ExecuteForceFields( pData->dwForceFields_GUID[0],
  272. pData->dwForceFields_GUID[1],
  273. pData->dwForceFields_GUID[2],
  274. pData->dwForceFields_GUID[3],
  275. pData->OldRenderPos,
  276. pData->RenderPos,
  277. pData->ExternalForce);
  278. if (bNeedKill)
  279. {
  280. *(pData->ActiveCount) = (*(pData->ActiveCount)-1);
  281. FreeParticle (pData);
  282. Particles.ExtractNoShift(n);
  283. n--;
  284. continue;
  285. }
  286. }
  287. */
  288. processCount++;
  289. } // цикл на Particles.Size()
  290. //Рождаем партиклы, которые привязанны к нашему партиклу...
  291. Matrix mat;
  292. Vector dir;
  293. processCount = 0;
  294. for (DWORD n = dwFrom; n < dwTo; n++)
  295. {
  296. dword dwParticleIdx = ParticlesIdx[n];
  297. BB_ParticleData* pData = &particlesData[dwParticleIdx];
  298. if (pData->AttachedEmitter)
  299. {
  300. dir = pData->OldRenderPos - pData->RenderPos;
  301. mat.BuildView(Vector(0.0f, 0.0f, 0.0f), dir, Vector(0.0f, 1.0f, 0.0f));
  302. mat.pos = pData->OldRenderPos;
  303. pData->AttachedEmitter->Teleport(mat);
  304. mat.pos = pData->RenderPos;
  305. pData->AttachedEmitter->SetTransform(mat);
  306. pData->AttachedEmitter->BornParticles(RealDeltaTime, pData->fTimeScale, pData->fAllsystemScale, 0.0f);
  307. }
  308. processCount++;
  309. } // цикл на Particles.Size()
  310. //RDTSC_E (t);
  311. //api->Trace("Time - %d", t);
  312. }
  313. //Считает расстояние до билбоардов
  314. DWORD BillBoardProcessor::CalcDistanceToCamera (const Matrix& mView)
  315. {
  316. DWORD VisParticles = 0;
  317. Vector vCamPos = mView.GetCamPos();
  318. for (DWORD j = 0; j < ParticlesIdx.Size(); j++)
  319. {
  320. dword dwParticleIdx = ParticlesIdx[j];
  321. BB_ParticleData* pData = &particlesData[dwParticleIdx];
  322. pData->CamDistance = ((pData->RenderPos - vCamPos) | (pData->RenderPos - vCamPos));
  323. pData->Visible = true;
  324. }
  325. return ParticlesIdx.Size();
  326. }
  327. void BillBoardProcessor::BuildVertexBuffers(SyncParams & threadParams)
  328. {
  329. const Matrix & matView = threadParams.mView;
  330. const Plane* pFrustum = threadParams.planes;
  331. RECT_VERTEX * pParticlesVerts = threadParams.updateData->pParticlesVerts;
  332. RECT_VERTEX * pParticlesXZVerts = threadParams.updateData->pParticlesXZVerts;
  333. RECT_VERTEX * pDistortedParticlesVerts = threadParams.updateData->pDistortedParticlesVerts;
  334. RECT_VERTEX * pDistortedParticlesXZVerts = threadParams.updateData->pDistortedParticlesXZVerts;
  335. bool bHaveDistortParticles = false;
  336. if (CalcDistanceToCamera(matView) == 0)
  337. {
  338. //нет партиклов вообще...
  339. return;
  340. }
  341. ParticleSorter.QSort(CompareFunction, &ParticlesIdx[0], ParticlesIdx.Size(), this);
  342. VbMarkup & markup = threadParams.updateData->markup;
  343. Assert(pParticlesVerts);
  344. Assert(pParticlesXZVerts);
  345. Assert(pDistortedParticlesVerts);
  346. Assert(pDistortedParticlesXZVerts);
  347. bHaveDistortParticles = UniformBuild<PTYPE_NORMAL>(pFrustum, matView, pParticlesVerts, markup.particles_count);
  348. UniformBuild<PTYPE_NORMAL_XZ>(pFrustum, matView, pParticlesXZVerts, markup.particlesXZ_count);
  349. if (bHaveDistortParticles)
  350. {
  351. UniformBuild<PTYPE_DISTORTED>(pFrustum, matView, pDistortedParticlesVerts, markup.distortedParticles_count);
  352. UniformBuild<PTYPE_DISTORTED_XZ>(pFrustum, matView, pDistortedParticlesXZVerts, markup.distortedParticlesXZ_count);
  353. }
  354. }
  355. DWORD BillBoardProcessor::GetCount ()
  356. {
  357. SyncroCode sync(access_to_particles);
  358. return ParticlesIdx.Size();
  359. }
  360. void BillBoardProcessor::DeleteWithGUID (IEmitter* dwGUID)
  361. {
  362. SyncroCode sync(access_to_particles);
  363. for (DWORD j = 0; j < ParticlesIdx.Size(); j++)
  364. {
  365. dword dwParticleIdx = ParticlesIdx[j];
  366. BB_ParticleData* pR = &particlesData[dwParticleIdx];
  367. if (pR->EmitterGUID == dwGUID)
  368. {
  369. *(pR->ActiveCount) = (*(pR->ActiveCount)-1);
  370. FreeParticle (dwParticleIdx);
  371. ParticlesIdx.ExtractNoShift(j);
  372. j--;
  373. }
  374. }
  375. }
  376. void BillBoardProcessor::Clear ()
  377. {
  378. SyncroCode sync(access_to_particles);
  379. for (DWORD j = 0; j < ParticlesIdx.Size(); j++)
  380. {
  381. dword dwParticleIdx = ParticlesIdx[j];
  382. BB_ParticleData* pR = &particlesData[dwParticleIdx];
  383. *(pR->ActiveCount) = (*(pR->ActiveCount)-1);
  384. FreeParticle (dwParticleIdx);
  385. }
  386. ParticlesIdx.DelAll();
  387. }
  388. bool BillBoardProcessor::Draw (const ParticleVB & renderVB, IIBuffer * pIBuffer, bool bSoftParticlesSupport)
  389. {
  390. SyncroCode sync(BillBoardProcessor::draw_particles);
  391. BillBoardProcessor::pRS->SetWorld(Matrix());
  392. long mode = 0;
  393. if (bSoftParticlesSupport == false)
  394. {
  395. mode = 2;
  396. }
  397. #ifndef STOP_DEBUG
  398. if (pGEOServ)
  399. {
  400. IGMXService::HackMode hackMode = pGEOServ->GetHackMode();
  401. if (hackMode == IGMXService::HM_SHOW_OVERDRAW)
  402. {
  403. mode = 1;
  404. }
  405. } else
  406. {
  407. pGEOServ = (IGMXService*)api->GetService("GMXService");
  408. }
  409. #endif
  410. DWORD dwParticlesCount = renderVB.markup.particles_count;
  411. if (dwParticlesCount > 0)
  412. {
  413. dword dwEvt = BillBoardProcessor::pRS->pixBeginEvent(_FL_, "SimpleParticles");
  414. BillBoardProcessor::pRS->SetStreamSource(0, renderVB.pParticles_VB);
  415. #ifndef _XBOX
  416. BillBoardProcessor::pRS->SetIndices(pIBuffer, 0);
  417. BillBoardProcessor::pRS->DrawIndexedPrimitive(shader_particles[mode], PT_TRIANGLELIST, 0, dwParticlesCount*4, 0, dwParticlesCount*2);
  418. #else
  419. BillBoardProcessor::pRS->DrawPrimitive(shader_particles[mode], PT_QUADLIST, 0, dwParticlesCount);
  420. #endif
  421. BillBoardProcessor::pRS->pixEndEvent(_FL_, dwEvt);
  422. }
  423. //api->SetPerformanceCounter("Particles::Billboards draw", (float)drawParticleBuffer.ParticlesCount0);
  424. DWORD dwParticlesXZCount = renderVB.markup.particlesXZ_count;
  425. if (dwParticlesXZCount > 0)
  426. {
  427. dword dwEvt = BillBoardProcessor::pRS->pixBeginEvent(_FL_, "XZSimpleParticles");
  428. BillBoardProcessor::pRS->SetStreamSource(0, renderVB.pParticlesXZ_VB);
  429. #ifndef _XBOX
  430. BillBoardProcessor::pRS->SetIndices(pIBuffer, 0);
  431. BillBoardProcessor::pRS->DrawIndexedPrimitive(shader_particlesXZ[mode], PT_TRIANGLELIST, 0, dwParticlesXZCount*4, 0, dwParticlesXZCount*2);
  432. #else
  433. BillBoardProcessor::pRS->DrawPrimitive(shader_particlesXZ[mode], PT_QUADLIST, 0, dwParticlesXZCount);
  434. #endif
  435. BillBoardProcessor::pRS->pixEndEvent(_FL_, dwEvt);
  436. }
  437. //api->SetPerformanceCounter("Particles::ZBillboards draw", (float)drawParticleBuffer.ParticlesCount1);
  438. BillBoardProcessor::pRS->SetStreamSource(0, NULL);
  439. if (renderVB.markup.distortedParticles_count > 0) return true;
  440. if (renderVB.markup.distortedParticlesXZ_count > 0) return true;
  441. return false;
  442. }
  443. void BillBoardProcessor::DrawDistorted (const ParticleVB & renderVB, IIBuffer * pIBuffer)
  444. {
  445. SyncroCode sync(BillBoardProcessor::draw_particles);
  446. BillBoardProcessor::pRS->SetWorld(Matrix());
  447. long mode = 0;
  448. #ifndef STOP_DEBUG
  449. if (pGEOServ)
  450. {
  451. IGMXService::HackMode hackMode = pGEOServ->GetHackMode();
  452. if (hackMode == IGMXService::HM_SHOW_OVERDRAW)
  453. {
  454. mode = 1;
  455. }
  456. } else
  457. {
  458. pGEOServ = (IGMXService*)api->GetService("GMXService");
  459. }
  460. #endif
  461. DWORD dwDistortedParticlesCount = renderVB.markup.distortedParticles_count;
  462. if (dwDistortedParticlesCount > 0)
  463. {
  464. dword dwEvt = BillBoardProcessor::pRS->pixBeginEvent(_FL_, "DistorParticles");
  465. BillBoardProcessor::pRS->SetStreamSource(0, renderVB.pDistortedParticles_VB);
  466. #ifndef _XBOX
  467. BillBoardProcessor::pRS->SetIndices(pIBuffer, 0);
  468. BillBoardProcessor::pRS->DrawIndexedPrimitive(shader_particles_distor[mode], PT_TRIANGLELIST, 0, dwDistortedParticlesCount*4, 0, dwDistortedParticlesCount*2);
  469. #else
  470. BillBoardProcessor::pRS->DrawPrimitive(shader_particles_distor[mode], PT_QUADLIST, 0, dwDistortedParticlesCount);
  471. #endif
  472. BillBoardProcessor::pRS->pixEndEvent(_FL_, dwEvt);
  473. }
  474. //api->SetPerformanceCounter("Particles::Billboards distorted draw", (float)drawParticleBuffer.ParticlesCount2);
  475. DWORD dwDistortedParticlesXZCount = renderVB.markup.distortedParticlesXZ_count;
  476. if (dwDistortedParticlesXZCount > 0)
  477. {
  478. dword dwEvt = BillBoardProcessor::pRS->pixBeginEvent(_FL_, "XZDistorParticles");
  479. BillBoardProcessor::pRS->SetStreamSource(0, renderVB.pDistortedParticlesXZ_VB);
  480. #ifndef _XBOX
  481. BillBoardProcessor::pRS->SetIndices(pIBuffer, 0);
  482. BillBoardProcessor::pRS->DrawIndexedPrimitive(shader_particlesXZ_distor[mode], PT_TRIANGLELIST, 0, dwDistortedParticlesXZCount*4, 0, dwDistortedParticlesXZCount*2);
  483. #else
  484. BillBoardProcessor::pRS->DrawPrimitive(shader_particlesXZ_distor[mode], PT_QUADLIST, 0, dwDistortedParticlesXZCount);
  485. #endif
  486. BillBoardProcessor::pRS->pixEndEvent(_FL_, dwEvt);
  487. }
  488. //api->SetPerformanceCounter("Particles::ZBillboards distorted draw", (float)drawParticleBuffer.ParticlesCount3);
  489. BillBoardProcessor::pRS->SetStreamSource(0, NULL);
  490. }