particle batching almost good

This commit is contained in:
d1str4ught
2025-08-26 03:18:09 +02:00
parent f78aa5bbc8
commit 5db6e9c3d9
13 changed files with 386 additions and 113 deletions

View File

@@ -95,7 +95,7 @@ void CEffectInstance::OnUpdate()
void CEffectInstance::OnRender()
{
STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_TEX1);
STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
@@ -106,19 +106,30 @@ void CEffectInstance::OnRender()
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
/////
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
std::for_each(m_ParticleInstanceVector.begin(),m_ParticleInstanceVector.end(),std::mem_fn(&CEffectElementBaseInstance::Render));
STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_TEX1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
std::for_each(m_ParticleInstanceVector.begin(),m_ParticleInstanceVector.end(),std::mem_fn(&CEffectElementBaseInstance::Render));
std::for_each(m_MeshInstanceVector.begin(),m_MeshInstanceVector.end(),std::mem_fn(&CEffectElementBaseInstance::Render));
/////
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_MINFILTER);
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_MAGFILTER);
@@ -128,6 +139,7 @@ void CEffectInstance::OnRender()
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
++ms_iRenderingEffectCount;
}
@@ -271,6 +283,16 @@ void CEffectInstance::Clear()
__Initialize();
}
void CEffectInstance::BatchParticles()
{
std::for_each(m_ParticleInstanceVector.begin(), m_ParticleInstanceVector.end(), std::mem_fn(&CParticleSystemInstance::BatchParticles));
}
void CEffectInstance::RenderMeshes()
{
std::for_each(m_MeshInstanceVector.begin(), m_MeshInstanceVector.end(), std::mem_fn(&CEffectElementBaseInstance::Render));
}
void CEffectInstance::__Initialize()
{
m_isAlive = FALSE;

View File

@@ -1,8 +1,8 @@
#pragma once
#include "../eterlib/GrpObjectInstance.h"
#include "../eterlib/Pool.h"
#include "../mileslib/Type.h"
#include "UserInterface/Locale_inc.h"
#include "Eterlib/GrpObjectInstance.h"
#include "Eterlib/Pool.h"
#include "Mileslib/Type.h"
#include "EffectElementBaseInstance.h"
#include "EffectData.h"
@@ -55,6 +55,9 @@ class CEffectInstance : public CGraphicObjectInstance
void OnRenderShadow() {} // Not used
void OnRenderPCBlocker() {} // Not used
void BatchParticles();
void RenderMeshes();
protected:
void __Initialize();

View File

@@ -3,7 +3,7 @@
#include "../eterlib/StateManager.h"
#include "EffectManager.h"
extern std::unordered_map<LPDIRECT3DTEXTURE9, std::vector<TPDTVertex>> g_particleVertexBatch;
void CEffectManager::GetInfo(std::string* pstInfo)
{
@@ -82,50 +82,15 @@ void CEffectManager::Update()
}
}
struct CEffectManager_LessEffectInstancePtrRenderOrder
{
bool operator() (CEffectInstance* pkLeft, CEffectInstance* pkRight)
{
return pkLeft->LessRenderOrder(pkRight);
}
};
struct CEffectManager_FEffectInstanceRender
{
inline void operator () (CEffectInstance * pkEftInst)
{
pkEftInst->Render();
}
};
void CEffectManager::Render()
{
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetTexture(1, NULL);
if (m_isDisableSortRendering)
{
for (TEffectInstanceMap::iterator itor = m_kEftInstMap.begin(); itor != m_kEftInstMap.end();)
{
CEffectInstance * pEffectInstance = itor->second;
pEffectInstance->Render();
++itor;
}
}
else
{
static std::vector<CEffectInstance*> s_kVct_pkEftInstSort;
s_kVct_pkEftInstSort.clear();
g_particleVertexBatch.clear();
TEffectInstanceMap& rkMap_pkEftInstSrc=m_kEftInstMap;
TEffectInstanceMap::iterator i;
for (i=rkMap_pkEftInstSrc.begin(); i!=rkMap_pkEftInstSrc.end(); ++i)
s_kVct_pkEftInstSort.push_back(i->second);
std::sort(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CEffectManager_LessEffectInstancePtrRenderOrder());
std::for_each(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CEffectManager_FEffectInstanceRender());
}
__RenderParticles();
__RenderMeshes();
}
BOOL CEffectManager::RegisterEffect(const char * c_szFileName,bool isExistDelete,bool isNeedCache)
@@ -439,6 +404,112 @@ void CEffectManager::__DestroyEffectDataMap()
m_kEftDataMap.clear();
}
void CEffectManager::__RenderParticles()
{
STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
for (auto itor = m_kEftInstMap.begin(); itor != m_kEftInstMap.end(); ++itor) {
itor->second->BatchParticles();
}
for (auto& [pTexture, vtxBatch] : g_particleVertexBatch) {
if (vtxBatch.empty())
continue;
STATEMANAGER.SetTexture(0, pTexture);
STATEMANAGER.DrawPrimitiveUP(
D3DPT_TRIANGLELIST,
vtxBatch.size() / 3,
vtxBatch.data(),
sizeof(TPDTVertex));
}
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_MINFILTER);
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_MAGFILTER);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
}
void CEffectManager::__RenderMeshes()
{
STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_TEX1);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
for (auto itor = m_kEftInstMap.begin(); itor != m_kEftInstMap.end(); ++itor) {
itor->second->RenderMeshes();
}
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_MINFILTER);
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_MAGFILTER);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
}
void CEffectManager::Destroy()
{
__DestroyEffectInstanceMap();

View File

@@ -76,6 +76,9 @@ class CEffectManager : public CScreen, public CSingleton<CEffectManager>
void __DestroyEffectCacheMap();
void __DestroyEffectDataMap();
void __RenderParticles();
void __RenderMeshes();
protected:
bool m_isDisableSortRendering;
TEffectDataMap m_kEftDataMap;

View File

@@ -167,8 +167,7 @@ void CEffectMeshInstance::OnRender()
}
Color.a = fAlpha * rFrameData.fVisibility;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, DWORD(Color));
STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_TEX1);
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, Color);
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLELIST,
rFrameData.dwIndexCount/3,
&rFrameData.PDTVertexVector[0],

View File

@@ -155,7 +155,13 @@ void CParticleInstance::UpdateColor(float time, float elapsedTime)
if (m_pParticleProperty->m_TimeEventColor.empty())
return;
m_dcColor = GetTimeEventBlendValue(time, m_pParticleProperty->m_TimeEventColor);
m_Color = GetTimeEventBlendValue(time, m_pParticleProperty->m_TimeEventColor);
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
for (auto& vtx : m_ParticleMesh) {
vtx.diffuse = m_Color;
}
#endif
}
void CParticleInstance::UpdateGravity(float time, float elapsedTime)
@@ -179,12 +185,9 @@ void CParticleInstance::UpdateAirResistance(float time, float elapsedTime)
void CParticleInstance::Transform(const D3DXMATRIX * c_matLocal)
{
#ifdef WORLD_EDITOR
#ifndef ENABLE_BATCHED_PARTICLE_RENDERING
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_Color);
#else
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_dcColor);
#endif
/////
D3DXVECTOR3 v3Up;
@@ -319,27 +322,60 @@ void CParticleInstance::Transform(const D3DXMATRIX * c_matLocal)
{
D3DXVECTOR3 v3Position;
D3DXVec3TransformCoord(&v3Position, &m_v3Position, c_matLocal);
m_ParticleMesh[0].position = v3Position - v3Up + v3Cross;
m_ParticleMesh[1].position = v3Position - v3Up - v3Cross;
m_ParticleMesh[2].position = v3Position + v3Up + v3Cross;
m_ParticleMesh[3].position = v3Position + v3Up - v3Cross;
D3DXVECTOR3 p0 = v3Position - v3Up + v3Cross; // bottom-left
D3DXVECTOR3 p1 = v3Position - v3Up - v3Cross; // bottom-right
D3DXVECTOR3 p2 = v3Position + v3Up + v3Cross; // top-left
D3DXVECTOR3 p3 = v3Position + v3Up - v3Cross; // top-right
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
// triangle 1: p0, p1, p2
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
// triangle 2: p2, p1, p3
m_ParticleMesh[3].position = p2;
m_ParticleMesh[4].position = p1;
m_ParticleMesh[5].position = p3;
#else
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
m_ParticleMesh[3].position = p3;
#endif
}
else
{
m_ParticleMesh[0].position = m_v3Position - v3Up + v3Cross;
m_ParticleMesh[1].position = m_v3Position - v3Up - v3Cross;
m_ParticleMesh[2].position = m_v3Position + v3Up + v3Cross;
m_ParticleMesh[3].position = m_v3Position + v3Up - v3Cross;
D3DXVECTOR3 p0 = m_v3Position - v3Up + v3Cross; // bottom-left
D3DXVECTOR3 p1 = m_v3Position - v3Up - v3Cross; // bottom-right
D3DXVECTOR3 p2 = m_v3Position + v3Up + v3Cross; // top-left
D3DXVECTOR3 p3 = m_v3Position + v3Up - v3Cross; // top-right
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
// triangle 1: p0, p1, p2
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
// triangle 2: p2, p1, p3
m_ParticleMesh[3].position = p2;
m_ParticleMesh[4].position = p1;
m_ParticleMesh[5].position = p3;
#else
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
m_ParticleMesh[3].position = p3;
#endif
}
}
void CParticleInstance::Transform(const D3DXMATRIX * c_matLocal, const float c_fZRotation)
{
#ifdef WORLD_EDITOR
#ifndef ENABLE_BATCHED_PARTICLE_RENDERING
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_Color);
#else
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, (DWORD)m_dcColor);
#endif
/////
@@ -474,17 +510,52 @@ void CParticleInstance::Transform(const D3DXMATRIX * c_matLocal, const float c_f
{
D3DXVECTOR3 v3Position;
D3DXVec3TransformCoord(&v3Position, &m_v3Position, c_matLocal);
m_ParticleMesh[0].position = v3Position - v3Up + v3Cross;
m_ParticleMesh[1].position = v3Position - v3Up - v3Cross;
m_ParticleMesh[2].position = v3Position + v3Up + v3Cross;
m_ParticleMesh[3].position = v3Position + v3Up - v3Cross;
D3DXVECTOR3 p0 = v3Position - v3Up + v3Cross; // bottom-left
D3DXVECTOR3 p1 = v3Position - v3Up - v3Cross; // bottom-right
D3DXVECTOR3 p2 = v3Position + v3Up + v3Cross; // top-left
D3DXVECTOR3 p3 = v3Position + v3Up - v3Cross; // top-right
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
// triangle 1: p0, p1, p2
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
// triangle 2: p2, p1, p3
m_ParticleMesh[3].position = p2;
m_ParticleMesh[4].position = p1;
m_ParticleMesh[5].position = p3;
#else
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
m_ParticleMesh[3].position = p3;
#endif
}
else
{
m_ParticleMesh[0].position = m_v3Position - v3Up + v3Cross;
m_ParticleMesh[1].position = m_v3Position - v3Up - v3Cross;
m_ParticleMesh[2].position = m_v3Position + v3Up + v3Cross;
m_ParticleMesh[3].position = m_v3Position + v3Up - v3Cross;
D3DXVECTOR3 p0 = m_v3Position - v3Up + v3Cross; // bottom-left
D3DXVECTOR3 p1 = m_v3Position - v3Up - v3Cross; // bottom-right
D3DXVECTOR3 p2 = m_v3Position + v3Up + v3Cross; // top-left
D3DXVECTOR3 p3 = m_v3Position + v3Up - v3Cross; // top-right
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
// triangle 1: p0, p1, p2
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
// triangle 2: p2, p1, p3
m_ParticleMesh[3].position = p2;
m_ParticleMesh[4].position = p1;
m_ParticleMesh[5].position = p3;
#else
m_ParticleMesh[0].position = p0;
m_ParticleMesh[1].position = p1;
m_ParticleMesh[2].position = p2;
m_ParticleMesh[3].position = p3;
#endif
}
}
@@ -500,20 +571,31 @@ void CParticleInstance::__Initialize()
m_v3Velocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v2Scale = D3DXVECTOR2(1.0f, 1.0f);
#ifdef WORLD_EDITOR
m_Color = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
#else
m_dcColor.m_dwColor = 0xffffffff;
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
for (auto& vtx : m_ParticleMesh) {
vtx.diffuse = m_Color;
}
#endif
m_byFrameIndex = 0;
m_rotationType = CParticleProperty::ROTATION_TYPE_NONE;
m_fFrameTime = 0;
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
m_ParticleMesh[0].texCoord = D3DXVECTOR2(0.0f, 1.0f);
m_ParticleMesh[1].texCoord = D3DXVECTOR2(0.0f, 0.0f);
m_ParticleMesh[2].texCoord = D3DXVECTOR2(1.0f, 1.0f);
m_ParticleMesh[3].texCoord = D3DXVECTOR2(1.0f, 1.0f);
m_ParticleMesh[4].texCoord = D3DXVECTOR2(0.0f, 0.0f);
m_ParticleMesh[5].texCoord = D3DXVECTOR2(1.0f, 0.0f);
#else
m_ParticleMesh[0].texCoord = D3DXVECTOR2(0.0f, 1.0f);
m_ParticleMesh[1].texCoord = D3DXVECTOR2(0.0f, 0.0f);
m_ParticleMesh[2].texCoord = D3DXVECTOR2(1.0f, 1.0f);
m_ParticleMesh[3].texCoord = D3DXVECTOR2(1.0f, 0.0f);
#endif
}
CParticleInstance::CParticleInstance()
@@ -526,7 +608,11 @@ CParticleInstance::~CParticleInstance()
Destroy();
}
TPTVertex * CParticleInstance::GetParticleMeshPointer()
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
const std::array<TPDTVertex, 6>& CParticleInstance::GetParticleMeshPointer()
#else
const std::array<TPTVertex, 4>& CParticleInstance::GetParticleMeshPointer()
#endif
{
return m_ParticleMesh;
}

View File

@@ -1,8 +1,11 @@
#pragma once
#include "UserInterface/Locale_inc.h"
#include "Type.h"
#include "Eterlib/GrpBase.h"
#include "EterLib/Pool.h"
#include <array>
class CParticleProperty;
class CEmitterProperty;
@@ -38,11 +41,8 @@ class CParticleInstance
D3DXVECTOR2 m_v2Scale;
float m_fRotation;
#ifdef WORLD_EDITOR
D3DXCOLOR m_Color;
#else
DWORDCOLOR m_dcColor;
#endif
BYTE m_byTextureAnimationType;
float m_fLastFrameTime;
@@ -68,7 +68,11 @@ class CParticleInstance
void Transform(const D3DXMATRIX * c_matLocal=NULL);
void Transform(const D3DXMATRIX * c_matLocal, const float c_fZRotation);
TPTVertex * GetParticleMeshPointer();
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
const std::array<TPDTVertex, 6>& GetParticleMeshPointer();
#else
const std::array<TPTVertex, 4>& GetParticleMeshPointer();
#endif
void DeleteThis();
@@ -76,7 +80,12 @@ class CParticleInstance
protected:
void __Initialize();
TPTVertex m_ParticleMesh[4];
#ifdef ENABLE_BATCHED_PARTICLE_RENDERING
std::array<TPDTVertex, 6> m_ParticleMesh;
#else
std::array<TPTVertex, 4> m_ParticleMesh;
#endif
public:
static CDynamicPool<CParticleInstance> ms_kPool;

View File

@@ -262,7 +262,7 @@ BOOL CParticleSystemData::OnLoadScript(CTextFileLoader & rTextFileLoader)
c.g = fG;
c.b = fB;
c.a = fA;
t.m_Value.m_dwColor = /*(DWORD)*/ (DWORD)c;
t.m_Value = c;
m_ParticleProperty.m_TimeEventColor.push_back(t);
}
}

View File

@@ -5,6 +5,8 @@
#include "ParticleSystemInstance.h"
#include "ParticleInstance.h"
std::unordered_map<LPDIRECT3DTEXTURE9, std::vector<TPDTVertex>> g_particleVertexBatch;
CDynamicPool<CParticleSystemInstance> CParticleSystemInstance::ms_kPool;
void CParticleSystemInstance::DestroySystem()
@@ -254,7 +256,7 @@ void CParticleSystemInstance::CreateParticles(float fElapsedTime)
pInstance->m_Color.b = m_pParticleProperty->m_TimeEventColorBlue.front().m_Value;
pInstance->m_Color.a = m_pParticleProperty->m_TimeEventAlpha.front().m_Value;
#else
pInstance->m_dcColor = m_pParticleProperty->m_TimeEventColor.front().m_Value;
pInstance->m_Color = m_pParticleProperty->m_TimeEventColor.front().m_Value;
#endif
}
@@ -348,13 +350,16 @@ namespace NParticleRenderer
{
}
inline void operator () (CParticleInstance * pInstance)
inline void operator () (CParticleInstance * pInstance, LPDIRECT3DTEXTURE9 pTexture)
{
auto& vtxBatch = g_particleVertexBatch[pTexture];
const auto& particleMesh = pInstance->GetParticleMeshPointer();
pInstance->Transform(pmat,D3DXToRadian(-30.0f));
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex));
vtxBatch.insert(vtxBatch.end(), particleMesh.begin(), particleMesh.end());
pInstance->Transform(pmat,D3DXToRadian(+30.0f));
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex));
vtxBatch.insert(vtxBatch.end(), particleMesh.begin(), particleMesh.end());
}
};
@@ -366,23 +371,31 @@ namespace NParticleRenderer
{
}
inline void operator () (CParticleInstance * pInstance)
inline void operator () (CParticleInstance* pInstance, LPDIRECT3DTEXTURE9 pTexture)
{
auto& vtxBatch = g_particleVertexBatch[pTexture];
const auto& particleMesh = pInstance->GetParticleMeshPointer();
pInstance->Transform(pmat);
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex));
vtxBatch.insert(vtxBatch.end(), particleMesh.begin(), particleMesh.end());
pInstance->Transform(pmat,D3DXToRadian(-60.0f));
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex));
vtxBatch.insert(vtxBatch.end(), particleMesh.begin(), particleMesh.end());
pInstance->Transform(pmat,D3DXToRadian(+60.0f));
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex));
vtxBatch.insert(vtxBatch.end(), particleMesh.begin(), particleMesh.end());
}
};
struct NormalRenderer
{
inline void operator () (CParticleInstance * pInstance)
inline void operator () (CParticleInstance* pInstance, LPDIRECT3DTEXTURE9 pTexture)
{
auto& vtxBatch = g_particleVertexBatch[pTexture];
const auto& particleMesh = pInstance->GetParticleMeshPointer();
pInstance->Transform();
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex));
vtxBatch.insert(vtxBatch.end(), particleMesh.begin(), particleMesh.end());
}
};
struct AttachRenderer
@@ -393,15 +406,80 @@ namespace NParticleRenderer
{
}
inline void operator () (CParticleInstance * pInstance)
inline void operator () (CParticleInstance* pInstance, LPDIRECT3DTEXTURE9 pTexture)
{
auto& vtxBatch = g_particleVertexBatch[pTexture];
const auto& particleMesh = pInstance->GetParticleMeshPointer();
pInstance->Transform(pmat);
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex));
vtxBatch.insert(vtxBatch.end(), particleMesh.begin(), particleMesh.end());
}
};
}
void CParticleSystemInstance::OnRender()
{
g_particleVertexBatch.clear();
CScreen::Identity();
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, m_pParticleProperty->m_bySrcBlendType);
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, m_pParticleProperty->m_byDestBlendType);
STATEMANAGER.SetTextureStageState(0,D3DTSS_COLOROP,m_pParticleProperty->m_byColorOperationType);
if (m_pParticleProperty->m_byBillboardType < BILLBOARD_TYPE_2FACE)
{
if (!m_pParticleProperty->m_bAttachFlag)
{
auto obj = NParticleRenderer::NormalRenderer();
ForEachParticleRendering(obj);
}
else
{
auto obj = NParticleRenderer::AttachRenderer(mc_pmatLocal);
ForEachParticleRendering(obj);
}
}
else if (m_pParticleProperty->m_byBillboardType == BILLBOARD_TYPE_2FACE)
{
if (!m_pParticleProperty->m_bAttachFlag)
{
auto obj = NParticleRenderer::TwoSideRenderer();
ForEachParticleRendering(obj);
}
else
{
auto obj = NParticleRenderer::TwoSideRenderer(mc_pmatLocal);
ForEachParticleRendering(obj);
}
}
else if (m_pParticleProperty->m_byBillboardType == BILLBOARD_TYPE_3FACE)
{
if (!m_pParticleProperty->m_bAttachFlag)
{
auto obj = NParticleRenderer::ThreeSideRenderer();
ForEachParticleRendering(obj);
}
else
{
auto obj = NParticleRenderer::ThreeSideRenderer(mc_pmatLocal);
ForEachParticleRendering(obj);
}
}
for (auto& [pTexture, vtxBatch] : g_particleVertexBatch) {
if (vtxBatch.empty())
continue;
STATEMANAGER.SetTexture(0, pTexture);
STATEMANAGER.DrawPrimitiveUP(
D3DPT_TRIANGLELIST,
vtxBatch.size() / 3,
vtxBatch.data(),
sizeof(TPDTVertex));
}
}
void CParticleSystemInstance::BatchParticles()
{
CScreen::Identity();
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, m_pParticleProperty->m_bySrcBlendType);

View File

@@ -1,12 +1,12 @@
#pragma once
#include "UserInterface/Locale_inc.h"
#include "EffectElementBaseInstance.h"
#include "ParticleInstance.h"
#include "ParticleProperty.h"
#include "../eterlib/GrpScreen.h"
#include "../eterlib/StateManager.h"
#include "../eterLib/GrpImageInstance.h"
#include "Eterlib/GrpScreen.h"
#include "Eterlib/StateManager.h"
#include "EterLib/GrpImageInstance.h"
#include "EmitterProperty.h"
class CParticleSystemInstance : public CEffectElementBaseInstance
@@ -26,13 +26,12 @@ class CParticleSystemInstance : public CEffectElementBaseInstance
DWORD dwFrameIndex;
for(dwFrameIndex=0; dwFrameIndex<m_kVct_pkImgInst.size(); dwFrameIndex++)
{
STATEMANAGER.SetTexture(0, m_kVct_pkImgInst[dwFrameIndex]->GetTextureReference().GetD3DTexture());
TParticleInstanceList::iterator itor = m_ParticleInstanceListVector[dwFrameIndex].begin();
for (; itor != m_ParticleInstanceListVector[dwFrameIndex].end(); ++itor)
{
if (!InFrustum(*itor))
return;
FunObj(*itor);
FunObj(*itor, m_kVct_pkImgInst[dwFrameIndex]->GetTextureReference().GetD3DTexture());
}
}
}
@@ -58,6 +57,8 @@ class CParticleSystemInstance : public CEffectElementBaseInstance
DWORD GetEmissionCount();
void BatchParticles();
protected:
void OnInitialize();
void OnDestroy();

View File

@@ -190,7 +190,7 @@ typedef CTimeEvent<short> TTimeEventTypeShort;
typedef CTimeEvent<float> TTimeEventTypeFloat;
typedef CTimeEvent<WORD> TTimeEventTypeWord;
typedef CTimeEvent<DWORD> TTimeEventTypeDoubleWord;
typedef CTimeEvent<DWORDCOLOR> TTimeEventTypeColor;
typedef CTimeEvent<D3DXCOLOR> TTimeEventTypeColor;
typedef CTimeEvent<D3DXVECTOR2> TTimeEventTypeVector2;
typedef CTimeEvent<D3DXVECTOR3> TTimeEventTypeVector3;

View File

@@ -4,3 +4,4 @@
#define ENABLE_DRAGON_SOUL_SYSTEM
#define ENABLE_NEW_EQUIPMENT_SYSTEM
//#define ENABLE_DISCORD_RPC
#define ENABLE_BATCHED_PARTICLE_RENDERING

View File

@@ -532,7 +532,7 @@ bool CPythonNetworkStream::CheckPacket(TPacketHeader * pRetHeader)
if (!s_packetHeaderMap.Get(header, &PacketType))
{
TraceError("Unknown packet header: %d, last: %d %d", header, g_iLastPacket[0], g_iLastPacket[1]);
LogBoxf("Unknown packet header: %d, last: %d %d", header, g_iLastPacket[0], g_iLastPacket[1]);
ClearRecvBuffer();
PostQuitMessage(0);
@@ -559,10 +559,10 @@ bool CPythonNetworkStream::CheckPacket(TPacketHeader * pRetHeader)
{
if (!Peek(PacketType.iPacketSize))
{
//Tracef("Not enough packet size: header %d packet size: %d, recv buffer size: %d",
// header,
// PacketType.iPacketSize,
// GetRecvBufferSize());
Tracef("Not enough packet size: header %d packet size: %d, recv buffer size: %d",
header,
PacketType.iPacketSize,
GetRecvBufferSize());
return false;
}
}