mirror of https://github.com/AxioDL/metaforce.git
More particle implementation
This commit is contained in:
parent
43a818d1a3
commit
0f1f0e1211
|
@ -7,6 +7,7 @@ namespace Retro
|
||||||
u32 CGraphics::g_NumLightsActive = 0;
|
u32 CGraphics::g_NumLightsActive = 0;
|
||||||
ERglLight CGraphics::g_LightActive = ERglLight::None;
|
ERglLight CGraphics::g_LightActive = ERglLight::None;
|
||||||
ERglLight CGraphics::g_LightsWereOn = ERglLight::None;
|
ERglLight CGraphics::g_LightsWereOn = ERglLight::None;
|
||||||
|
Zeus::CTransform CGraphics::g_ViewMatrix;
|
||||||
|
|
||||||
void CGraphics::DisableAllLights()
|
void CGraphics::DisableAllLights()
|
||||||
{
|
{
|
||||||
|
@ -33,4 +34,25 @@ void CGraphics::SetLightState(ERglLight lightState)
|
||||||
g_NumLightsActive = Zeus::Math::PopCount(lightState);
|
g_NumLightsActive = Zeus::Math::PopCount(lightState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGraphics::SetDepthWriteMode(bool, ERglEnum, bool)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGraphics::SetBlendMode(ERglBlendMode, ERglBlendFactor, ERglBlendFactor, ERglLogicOp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGraphics::SetCullMode(ERglCullMode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGraphics::SetModelMatrix(const Zeus::CTransform& xf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __RETRO_CGRAPHICS_HPP__
|
#define __RETRO_CGRAPHICS_HPP__
|
||||||
|
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
|
#include "CTransform.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
|
@ -20,15 +21,101 @@ enum class ERglLight : u8
|
||||||
};
|
};
|
||||||
ENABLE_BITWISE_ENUM(ERglLight)
|
ENABLE_BITWISE_ENUM(ERglLight)
|
||||||
|
|
||||||
|
enum class ERglEnum
|
||||||
|
{
|
||||||
|
Never = 0,
|
||||||
|
Less = 1,
|
||||||
|
Equal = 2,
|
||||||
|
LEqual = 3,
|
||||||
|
Greater = 4,
|
||||||
|
NEqual = 5,
|
||||||
|
GEqual = 6,
|
||||||
|
Always = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ERglBlendMode
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Blend = 1,
|
||||||
|
Logic = 2,
|
||||||
|
Subtract = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ERglBlendFactor
|
||||||
|
{
|
||||||
|
Zero = 0,
|
||||||
|
One = 1,
|
||||||
|
SrcColor = 2,
|
||||||
|
InvSrcColor = 3,
|
||||||
|
SrcAlpha = 4,
|
||||||
|
InvSrcAlpha = 5,
|
||||||
|
DstAlpha = 6,
|
||||||
|
InvDstAlpha = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ERglLogicOp
|
||||||
|
{
|
||||||
|
Clear = 0,
|
||||||
|
And = 1,
|
||||||
|
RevAnd = 2,
|
||||||
|
Copy = 3,
|
||||||
|
InvAnd = 4,
|
||||||
|
NoOp = 5,
|
||||||
|
Xor = 6,
|
||||||
|
Or = 7,
|
||||||
|
Nor = 8,
|
||||||
|
Equiv = 9,
|
||||||
|
Inv = 10,
|
||||||
|
RevOr = 11,
|
||||||
|
InvCopy = 12,
|
||||||
|
InvOr = 13,
|
||||||
|
NAnd = 14,
|
||||||
|
Set = 15
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ERglCullMode
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Front = 1,
|
||||||
|
Back = 2,
|
||||||
|
All = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ERglAlphaFunc
|
||||||
|
{
|
||||||
|
Never = 0,
|
||||||
|
Less = 1,
|
||||||
|
Equal = 2,
|
||||||
|
LEqual = 3,
|
||||||
|
Greater = 4,
|
||||||
|
NEqual = 5,
|
||||||
|
GEqual = 6,
|
||||||
|
Always = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ERglAlphaOp
|
||||||
|
{
|
||||||
|
And = 0,
|
||||||
|
Or = 1,
|
||||||
|
Xor = 2,
|
||||||
|
XNor = 3
|
||||||
|
};
|
||||||
|
|
||||||
class CGraphics
|
class CGraphics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static u32 g_NumLightsActive;
|
static u32 g_NumLightsActive;
|
||||||
static ERglLight g_LightActive;
|
static ERglLight g_LightActive;
|
||||||
static ERglLight g_LightsWereOn;
|
static ERglLight g_LightsWereOn;
|
||||||
|
static Zeus::CTransform g_ViewMatrix;
|
||||||
static void DisableAllLights();
|
static void DisableAllLights();
|
||||||
static void EnableLight(ERglLight light);
|
static void EnableLight(ERglLight light);
|
||||||
static void SetLightState(ERglLight lightState);
|
static void SetLightState(ERglLight lightState);
|
||||||
|
static void SetDepthWriteMode(bool, ERglEnum, bool);
|
||||||
|
static void SetBlendMode(ERglBlendMode, ERglBlendFactor, ERglBlendFactor, ERglLogicOp);
|
||||||
|
static void SetCullMode(ERglCullMode);
|
||||||
|
static void SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1);
|
||||||
|
static void SetModelMatrix(const Zeus::CTransform& xf);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ add_library(RuntimeCommon
|
||||||
CMoviePlayer.hpp CMoviePlayer.cpp
|
CMoviePlayer.hpp CMoviePlayer.cpp
|
||||||
CGameDebug.hpp CGameDebug.cpp
|
CGameDebug.hpp CGameDebug.cpp
|
||||||
CGraphics.hpp CGraphics.cpp
|
CGraphics.hpp CGraphics.cpp
|
||||||
|
CModel.hpp CModelBoo.cpp
|
||||||
rstl.hpp rstl.cpp
|
rstl.hpp rstl.cpp
|
||||||
GameGlobalObjects.hpp
|
GameGlobalObjects.hpp
|
||||||
RetroTypes.hpp
|
RetroTypes.hpp
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef __RETRO_CMODEL_HPP__
|
||||||
|
#define __RETRO_CMODEL_HPP__
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
#include "CColor.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CModelFlags
|
||||||
|
{
|
||||||
|
u8 f1;
|
||||||
|
u8 f2;
|
||||||
|
u16 f3;
|
||||||
|
Zeus::CColor color;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Draw(const CModelFlags& flags) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __RETRO_CMODEL_HPP__
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "CModel.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
|
||||||
|
void CModel::Draw(const CModelFlags& flags) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "CTexture.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
|
||||||
|
void CTexture::Load(int slot, EClampMode clamp)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,8 +11,14 @@ class CTexture
|
||||||
u16 x4_w;
|
u16 x4_w;
|
||||||
u16 x6_h;
|
u16 x6_h;
|
||||||
public:
|
public:
|
||||||
|
enum class EClampMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
One
|
||||||
|
};
|
||||||
u16 GetWidth() const {return x4_w;}
|
u16 GetWidth() const {return x4_w;}
|
||||||
u16 GetHeight() const {return x6_h;}
|
u16 GetHeight() const {return x6_h;}
|
||||||
|
void Load(int slot, EClampMode clamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "CParticleGlobals.hpp"
|
#include "CParticleGlobals.hpp"
|
||||||
#include "CParticleSwoosh.hpp"
|
#include "CParticleSwoosh.hpp"
|
||||||
#include "CParticleElectric.hpp"
|
#include "CParticleElectric.hpp"
|
||||||
|
#include "CModel.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ int CElementGen::g_ParticleAliveCount;
|
||||||
int CElementGen::g_ParticleSystemAliveCount;
|
int CElementGen::g_ParticleSystemAliveCount;
|
||||||
s32 CElementGen::g_FreeIndex;
|
s32 CElementGen::g_FreeIndex;
|
||||||
bool CElementGen::g_StaticListInitialized = false;
|
bool CElementGen::g_StaticListInitialized = false;
|
||||||
|
bool CElementGen::g_MoveRedToAlphaBuffer = false;
|
||||||
static rstl::reserved_vector<CElementGen::CParticle, 2560> g_StaticParticleList;
|
static rstl::reserved_vector<CElementGen::CParticle, 2560> g_StaticParticleList;
|
||||||
static rstl::reserved_vector<u16, 2560> g_StaticFreeList;
|
static rstl::reserved_vector<u16, 2560> g_StaticFreeList;
|
||||||
void CElementGen::Initialize()
|
void CElementGen::Initialize()
|
||||||
|
@ -958,7 +960,192 @@ void CElementGen::Render()
|
||||||
|
|
||||||
void CElementGen::RenderModels()
|
void CElementGen::RenderModels()
|
||||||
{
|
{
|
||||||
|
CGenDescription* desc = x1c_genDesc.CastObj<CGenDescription>();
|
||||||
|
|
||||||
|
if (x225_29_modelsUseLights)
|
||||||
|
CGraphics::SetLightState(x22c_backupLightActive);
|
||||||
|
CGlobalRandom gr(x230_randState);
|
||||||
|
|
||||||
|
SUVElementSet uvs = {0.f, 0.f, 1.f, 1.f};
|
||||||
|
CUVElement* texr = desc->x54_TEXR.get();
|
||||||
|
CTexture* cachedTex = nullptr;
|
||||||
|
bool texConst = true;
|
||||||
|
bool moveRedToAlphaBuffer = false;
|
||||||
|
|
||||||
|
if (desc->x45_24_PMUS)
|
||||||
|
{
|
||||||
|
if (g_MoveRedToAlphaBuffer && desc->x44_31_PMAB && desc->x54_TEXR)
|
||||||
|
moveRedToAlphaBuffer = true;
|
||||||
|
|
||||||
|
if (desc->x44_31_PMAB)
|
||||||
|
{
|
||||||
|
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, false);
|
||||||
|
if (moveRedToAlphaBuffer)
|
||||||
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||||
|
else
|
||||||
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true);
|
||||||
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
CGraphics::SetCullMode(ERglCullMode::None);
|
||||||
|
|
||||||
|
if (texr)
|
||||||
|
{
|
||||||
|
CParticle& target = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
||||||
|
int partFrame = x50_curFrame - target.x28_startFrame;
|
||||||
|
cachedTex = texr->GetValueTexture(partFrame).GetObj();
|
||||||
|
cachedTex->Load(0, CTexture::EClampMode::One);
|
||||||
|
/* Shade as TEXC * RASC and TEXA * RASA */
|
||||||
|
if (moveRedToAlphaBuffer)
|
||||||
|
{
|
||||||
|
/* Color = Prev.rgb * Prev.a */
|
||||||
|
/* Alpha = Tex.r * Prev.a */
|
||||||
|
}
|
||||||
|
texConst = texr->HasConstantTexture();
|
||||||
|
texr->GetValueUV(partFrame, uvs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Zeus::CTransform orient = Zeus::CTransform::Identity();
|
||||||
|
if (desc->x45_25_PMOO)
|
||||||
|
orient = x178_orientation;
|
||||||
|
orient = orient * x1d8_globalOrientation;
|
||||||
|
|
||||||
|
CVectorElement* pmrt = desc->x70_PMRT.get();
|
||||||
|
bool pmrtConst = false;
|
||||||
|
if (pmrt)
|
||||||
|
pmrtConst = pmrt->IsFastConstant();
|
||||||
|
|
||||||
|
Zeus::CVector3f trans = (xdc * x148) * x88_globalTranslation;
|
||||||
|
|
||||||
|
Zeus::CTransform rot = Zeus::CTransform::Identity();
|
||||||
|
if (pmrtConst)
|
||||||
|
{
|
||||||
|
Zeus::CVector3f pmrtVal;
|
||||||
|
pmrt->GetValue(x50_curFrame, pmrtVal);
|
||||||
|
rot = Zeus::CTransform::RotateZ(pmrtVal[2] * M_PI / 180.f);
|
||||||
|
rot.rotateLocalY(pmrtVal[1] * M_PI / 180.f);
|
||||||
|
rot.rotateLocalX(pmrtVal[0] * M_PI / 180.f);
|
||||||
|
}
|
||||||
|
rot = orient * rot;
|
||||||
|
|
||||||
|
CParticleGlobals::SetEmitterTime(x50_curFrame);
|
||||||
|
Zeus::CColor col = {1.f, 1.f, 1.f, 1.f};
|
||||||
|
|
||||||
|
Zeus::CVector3f pmopVec;
|
||||||
|
auto matrixIt = x3c_parentMatrices.begin();
|
||||||
|
for (CParticleListItem& item : x2c_particleLists)
|
||||||
|
{
|
||||||
|
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||||
|
if (particle.x0_endFrame == -1)
|
||||||
|
{
|
||||||
|
++matrixIt;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
|
||||||
|
int partFrame = x50_curFrame - particle.x28_startFrame - 1;
|
||||||
|
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
|
||||||
|
CVectorElement* pmop = desc->x6c_PMOP.get();
|
||||||
|
if (pmop)
|
||||||
|
pmop->GetValue(partFrame, pmopVec);
|
||||||
|
|
||||||
|
Zeus::CTransform partTrans = Zeus::CTransform::Translate(particle.x4_pos + trans);
|
||||||
|
if (x28_orientType == EModelOrientationType::One)
|
||||||
|
{
|
||||||
|
Zeus::CTransform partRot(*matrixIt);
|
||||||
|
Zeus::CVector3f pmopRotateOffset = (orient * partRot) * pmopVec;
|
||||||
|
partTrans = partTrans * partRot;
|
||||||
|
partTrans += pmopRotateOffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
partTrans += orient * pmopVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pmrtConst)
|
||||||
|
{
|
||||||
|
partTrans = partTrans * rot;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pmrt)
|
||||||
|
{
|
||||||
|
Zeus::CVector3f pmrtVal;
|
||||||
|
pmrt->GetValue(partFrame, pmrtVal);
|
||||||
|
rot = Zeus::CTransform::RotateZ(pmrtVal[2] * M_PI / 180.f);
|
||||||
|
rot.rotateLocalY(pmrtVal[1] * M_PI / 180.f);
|
||||||
|
rot.rotateLocalX(pmrtVal[0] * M_PI / 180.f);
|
||||||
|
partTrans = partTrans * (orient * rot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
partTrans = partTrans * rot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CVectorElement* pmsc = desc->x74_PMSC.get();
|
||||||
|
if (pmsc)
|
||||||
|
{
|
||||||
|
Zeus::CVector3f pmscVal;
|
||||||
|
pmsc->GetValue(partFrame, pmscVal);
|
||||||
|
partTrans = partTrans * Zeus::CTransform::Scale(pmscVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
CColorElement* pmcl = desc->x78_PMCL.get();
|
||||||
|
if (pmcl)
|
||||||
|
pmcl->GetValue(partFrame, col);
|
||||||
|
|
||||||
|
CGraphics::SetModelMatrix((xac * partTrans) * x118);
|
||||||
|
|
||||||
|
if (desc->x45_24_PMUS)
|
||||||
|
{
|
||||||
|
if (!texConst)
|
||||||
|
{
|
||||||
|
CTexture* tex = texr->GetValueTexture(x50_curFrame - particle.x28_startFrame).GetObj();
|
||||||
|
if (tex != cachedTex)
|
||||||
|
{
|
||||||
|
tex->Load(0, CTexture::EClampMode::One);
|
||||||
|
cachedTex = tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw: */
|
||||||
|
/* Pos: {0.5, 0.0, 0.5} Color: <col-variable> UV0: {uv[2], uv[3]} */
|
||||||
|
/* Pos: {-0.5, 0.0, 0.5} Color: <col-variable> UV0: {uv[0], uv[3]} */
|
||||||
|
/* Pos: {-0.5, 0.0, -0.5} Color: <col-variable> UV0: {uv[0], uv[1]} */
|
||||||
|
/* Pos: {0.5, 0.0, -0.5} Color: <col-variable> UV0: {uv[2], uv[1]} */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CModel* model = desc->x5c_PMDL.m_model.GetObj();
|
||||||
|
if (desc->x44_31_PMAB)
|
||||||
|
{
|
||||||
|
model->Draw({3, 0, 1, col});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (1.f == col.a)
|
||||||
|
model->Draw({0, 0, 3, Zeus::CColor::skWhite});
|
||||||
|
else
|
||||||
|
model->Draw({4, 0, 1, col});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++matrixIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x225_29_modelsUseLights)
|
||||||
|
CGraphics::DisableAllLights();
|
||||||
|
|
||||||
|
CGraphics::SetCullMode(ERglCullMode::Front);
|
||||||
|
if (moveRedToAlphaBuffer)
|
||||||
|
{
|
||||||
|
/* Restore passthrough */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CElementGen::RenderLines()
|
void CElementGen::RenderLines()
|
||||||
|
@ -966,6 +1153,291 @@ void CElementGen::RenderLines()
|
||||||
}
|
}
|
||||||
|
|
||||||
void CElementGen::RenderParticles()
|
void CElementGen::RenderParticles()
|
||||||
|
{
|
||||||
|
CGenDescription* desc = x1c_genDesc.CastObj<CGenDescription>();
|
||||||
|
CGlobalRandom gr(x230_randState);
|
||||||
|
|
||||||
|
CUVElement* texr = desc->x54_TEXR.get();
|
||||||
|
CUVElement* tind = desc->x58_TIND.get();
|
||||||
|
if (texr && tind)
|
||||||
|
{
|
||||||
|
RenderParticlesIndirectTexture();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRealElement* size = desc->x4c_SIZE.get();
|
||||||
|
if (size && size->IsConstant())
|
||||||
|
{
|
||||||
|
float sizeVal;
|
||||||
|
size->GetValue(0, sizeVal);
|
||||||
|
if (sizeVal == 0.f)
|
||||||
|
{
|
||||||
|
size->GetValue(1, sizeVal);
|
||||||
|
if (sizeVal == 0.f)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Zeus::CTransform xf(CGraphics::g_ViewMatrix);
|
||||||
|
Zeus::CTransform xf2 = xf.inverse() * x1d8_globalOrientation;
|
||||||
|
|
||||||
|
xf = ((Zeus::CTransform::Translate(x88_globalTranslation) * xac) * xf) * x118;
|
||||||
|
CGraphics::SetModelMatrix(xf);
|
||||||
|
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
|
||||||
|
|
||||||
|
SUVElementSet uvs = {0.f, 0.f, 1.f, 1.f};
|
||||||
|
bool constTexr = true;
|
||||||
|
bool constUVs = true;
|
||||||
|
CTexture* cachedTex = nullptr;
|
||||||
|
|
||||||
|
if (texr)
|
||||||
|
{
|
||||||
|
CParticle& target = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
||||||
|
int partFrame = x50_curFrame - target.x28_startFrame;
|
||||||
|
cachedTex = texr->GetValueTexture(partFrame).GetObj();
|
||||||
|
cachedTex->Load(0, CTexture::EClampMode::One);
|
||||||
|
|
||||||
|
if (x30c_moduColor != Zeus::CColor::skBlack)
|
||||||
|
{
|
||||||
|
/* Add RASC * PREVC pass for MODU color loaded into channel mat-color */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Pass-thru */
|
||||||
|
}
|
||||||
|
|
||||||
|
constTexr = texr->HasConstantTexture();
|
||||||
|
texr->GetValueUV(partFrame, uvs);
|
||||||
|
constUVs = texr->HasConstantUV();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Pass-thru */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc->x44_28_SORT)
|
||||||
|
{
|
||||||
|
for (CParticleListItem& item : x2c_particleLists)
|
||||||
|
{
|
||||||
|
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||||
|
item.x4_viewPoint = xf2 * ((particle.x4_pos - particle.x10_prevPos) * x60 + particle.x10_prevPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(x2c_particleLists.begin(), x2c_particleLists.end(),
|
||||||
|
[](const CParticleListItem& a, const CParticleListItem& b) -> bool
|
||||||
|
{return a.x4_viewPoint[1] >= b.x4_viewPoint[1];});
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
bool done = false;
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
for (int i=0 ; i<x2c_particleLists.size()-1 ; ++i)
|
||||||
|
{
|
||||||
|
CParticleListItem& p1 = x2c_particleLists[i];
|
||||||
|
CParticleListItem& p2 = x2c_particleLists[i+1];
|
||||||
|
if (p1.x4_viewPoint[1] < p2.x4_viewPoint[1])
|
||||||
|
{
|
||||||
|
CParticleListItem tmp = p2;
|
||||||
|
p2 = p1;
|
||||||
|
p1 = tmp;
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x30c_moduColor != Zeus::CColor::skBlack)
|
||||||
|
{
|
||||||
|
/* Load mat-color here */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Pass-thru */
|
||||||
|
}
|
||||||
|
|
||||||
|
bool moveRedToAlphaBuffer = false;
|
||||||
|
if (g_MoveRedToAlphaBuffer && x224_26_AAPH)
|
||||||
|
moveRedToAlphaBuffer = true;
|
||||||
|
|
||||||
|
if (moveRedToAlphaBuffer)
|
||||||
|
{
|
||||||
|
CGraphics::SetDepthWriteMode(x224_28_zTest, ERglEnum::LEqual, false);
|
||||||
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||||
|
/* Color = Prev.rgb * Prev.a */
|
||||||
|
/* Alpha = Tex.r * Prev.a */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x224_26_AAPH)
|
||||||
|
{
|
||||||
|
CGraphics::SetDepthWriteMode(x224_28_zTest, ERglEnum::LEqual, false);
|
||||||
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CGraphics::SetDepthWriteMode(x224_28_zTest, ERglEnum::LEqual, x224_27_ZBUF);
|
||||||
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbspVal = std::max(1, x228_MBSP);
|
||||||
|
if (!x224_29_MBLR)
|
||||||
|
{
|
||||||
|
/* Begin quad draw of x2c_particleLists.size() * 4 verts */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Begin quad draw of x2c_particleLists.size() * 4 * mbspVal verts */
|
||||||
|
}
|
||||||
|
|
||||||
|
CParticleGlobals::SetEmitterTime(x50_curFrame);
|
||||||
|
if (!x224_29_MBLR)
|
||||||
|
{
|
||||||
|
for (CParticleListItem& item : x2c_particleLists)
|
||||||
|
{
|
||||||
|
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||||
|
int partFrame = x50_curFrame - particle.x28_startFrame - 1;
|
||||||
|
Zeus::CVector3f viewPoint;
|
||||||
|
if (desc->x44_28_SORT)
|
||||||
|
viewPoint = item.x4_viewPoint;
|
||||||
|
else
|
||||||
|
viewPoint = xf2 * ((particle.x4_pos - particle.x10_prevPos) * x60 + particle.x10_prevPos);
|
||||||
|
|
||||||
|
if (!constTexr)
|
||||||
|
{
|
||||||
|
CTexture* tex = texr->GetValueTexture(partFrame).GetObj();
|
||||||
|
if (tex != cachedTex)
|
||||||
|
{
|
||||||
|
tex->Load(0, CTexture::EClampMode::One);
|
||||||
|
cachedTex = tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!constUVs)
|
||||||
|
{
|
||||||
|
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
|
||||||
|
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
|
||||||
|
texr->GetValueUV(partFrame, uvs);
|
||||||
|
}
|
||||||
|
|
||||||
|
float size = 0.5f * particle.x2c_lineLengthOrSize;
|
||||||
|
if (0.f == particle.x30_lineWidthOrRota)
|
||||||
|
{
|
||||||
|
/* Draw: */
|
||||||
|
/* Pos: {viewPoint.x + size, 0.0, viewPoint.z + size} Color: particle.color UV0: {uv[2], uv[3]} */
|
||||||
|
/* Pos: {viewPoint.x - size, 0.0, viewPoint.z + size} Color: particle.color UV0: {uv[0], uv[3]} */
|
||||||
|
/* Pos: {viewPoint.x - size, 0.0, viewPoint.z - size} Color: particle.color UV0: {uv[0], uv[1]} */
|
||||||
|
/* Pos: {viewPoint.x + size, 0.0, viewPoint.z - size} Color: particle.color UV0: {uv[2], uv[1]} */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float theta = particle.x30_lineWidthOrRota * M_PI / 180.f;
|
||||||
|
float sinT = sinf(theta) * size;
|
||||||
|
float cosT = sinf(theta) * size;
|
||||||
|
|
||||||
|
/* Draw:
|
||||||
|
viewPoint.x + sinT + cosT;
|
||||||
|
0.f;
|
||||||
|
viewPoint.z + cosT - sinT;
|
||||||
|
|
||||||
|
viewPoint.x + sinT - cosT;
|
||||||
|
0.f;
|
||||||
|
viewPoint.z + sinT + cosT;
|
||||||
|
|
||||||
|
viewPoint.x - (sinT + cosT);
|
||||||
|
0.f;
|
||||||
|
viewPoint.z - (cosT - sinT);
|
||||||
|
|
||||||
|
viewPoint.x + (cosT - sinT);
|
||||||
|
0.f;
|
||||||
|
viewPoint.z + (-cosT - sinT);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float mbspFac = 1.f / float(mbspVal);
|
||||||
|
for (CParticleListItem& item : x2c_particleLists)
|
||||||
|
{
|
||||||
|
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||||
|
int partFrame = x50_curFrame - particle.x28_startFrame - 1;
|
||||||
|
|
||||||
|
if (!constTexr)
|
||||||
|
{
|
||||||
|
CTexture* tex = texr->GetValueTexture(partFrame).GetObj();
|
||||||
|
if (tex != cachedTex)
|
||||||
|
{
|
||||||
|
tex->Load(0, CTexture::EClampMode::One);
|
||||||
|
cachedTex = tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!constUVs)
|
||||||
|
{
|
||||||
|
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
|
||||||
|
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
|
||||||
|
texr->GetValueUV(partFrame, uvs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Zeus::CVector3f dVec = particle.x4_pos - particle.x10_prevPos;
|
||||||
|
Zeus::CVector3f vec = dVec * x60 + particle.x10_prevPos;
|
||||||
|
Zeus::CVector3f mbspVec = dVec * mbspFac;
|
||||||
|
float size = 0.5f * particle.x2c_lineLengthOrSize;
|
||||||
|
if (0.f == particle.x30_lineWidthOrRota)
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<mbspVal ; ++i)
|
||||||
|
{
|
||||||
|
vec += mbspVec;
|
||||||
|
Zeus::CVector3f vec2 = xf2 * vec;
|
||||||
|
/* Draw: */
|
||||||
|
/* Pos: {vec2.x + size, vec2.y, vec2.z + size} Color: particle.color UV0: {uv[2], uv[3]} */
|
||||||
|
/* Pos: {vec2.x - size, vec2.y, vec2.z + size} Color: particle.color UV0: {uv[0], uv[3]} */
|
||||||
|
/* Pos: {vec2.x - size, vec2.y, vec2.z - size} Color: particle.color UV0: {uv[0], uv[1]} */
|
||||||
|
/* Pos: {vec2.x + size, vec2.y, vec2.z - size} Color: particle.color UV0: {uv[2], uv[1]} */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float theta = particle.x30_lineWidthOrRota * M_PI / 180.f;
|
||||||
|
float sinT = sinf(theta) * size;
|
||||||
|
float cosT = sinf(theta) * size;
|
||||||
|
|
||||||
|
for (int i=0 ; i<mbspVal ; ++i)
|
||||||
|
{
|
||||||
|
vec += mbspVec;
|
||||||
|
Zeus::CVector3f vec2 = xf2 * vec;
|
||||||
|
/* Draw:
|
||||||
|
vec2.x + sinT + cosT;
|
||||||
|
vec2.y;
|
||||||
|
vec2.z + cosT - sinT;
|
||||||
|
|
||||||
|
vec2.x + sinT - cosT;
|
||||||
|
vec2.y;
|
||||||
|
vec2.z + sinT + cosT;
|
||||||
|
|
||||||
|
vec2.x - (sinT + cosT);
|
||||||
|
vec2.y;
|
||||||
|
vec2.z - (cosT - sinT);
|
||||||
|
|
||||||
|
vec2.x + (cosT - sinT);
|
||||||
|
vec2.y;
|
||||||
|
vec2.z + (-cosT - sinT);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moveRedToAlphaBuffer)
|
||||||
|
{
|
||||||
|
/* Restore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CElementGen::RenderParticlesIndirectTexture()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
{
|
{
|
||||||
friend class CElementGen;
|
friend class CElementGen;
|
||||||
s16 x0_partIdx;
|
s16 x0_partIdx;
|
||||||
Zeus::CVector3f x4_vec;
|
Zeus::CVector3f x4_viewPoint;
|
||||||
public:
|
public:
|
||||||
CParticleListItem(s16 idx)
|
CParticleListItem(s16 idx)
|
||||||
: x0_partIdx(idx)
|
: x0_partIdx(idx)
|
||||||
|
@ -99,7 +99,7 @@ protected:
|
||||||
bool x224_25_LIT_;
|
bool x224_25_LIT_;
|
||||||
bool x224_26_AAPH;
|
bool x224_26_AAPH;
|
||||||
bool x224_27_ZBUF;
|
bool x224_27_ZBUF;
|
||||||
bool x224_28 = true;
|
bool x224_28_zTest = true;
|
||||||
bool x224_29_MBLR;
|
bool x224_29_MBLR;
|
||||||
bool x224_30_VMD1;
|
bool x224_30_VMD1;
|
||||||
bool x224_31_VMD2;
|
bool x224_31_VMD2;
|
||||||
|
@ -108,7 +108,7 @@ protected:
|
||||||
bool x225_26_LINE;
|
bool x225_26_LINE;
|
||||||
bool x225_27_FXLL;
|
bool x225_27_FXLL;
|
||||||
bool x225_28_warmedUp = false;
|
bool x225_28_warmedUp = false;
|
||||||
bool x225_29 = false;
|
bool x225_29_modelsUseLights = false;
|
||||||
bool x226;
|
bool x226;
|
||||||
int x228_MBSP;
|
int x228_MBSP;
|
||||||
ERglLight x22c_backupLightActive = ERglLight::None;
|
ERglLight x22c_backupLightActive = ERglLight::None;
|
||||||
|
@ -171,6 +171,7 @@ public:
|
||||||
static bool g_StaticListInitialized;
|
static bool g_StaticListInitialized;
|
||||||
static int g_ParticleAliveCount;
|
static int g_ParticleAliveCount;
|
||||||
static int g_ParticleSystemAliveCount;
|
static int g_ParticleSystemAliveCount;
|
||||||
|
static bool g_MoveRedToAlphaBuffer;
|
||||||
static void Initialize();
|
static void Initialize();
|
||||||
|
|
||||||
void UpdateExistingParticles();
|
void UpdateExistingParticles();
|
||||||
|
@ -187,6 +188,7 @@ public:
|
||||||
void RenderModels();
|
void RenderModels();
|
||||||
void RenderLines();
|
void RenderLines();
|
||||||
void RenderParticles();
|
void RenderParticles();
|
||||||
|
void RenderParticlesIndirectTexture();
|
||||||
|
|
||||||
virtual void Update(double);
|
virtual void Update(double);
|
||||||
bool InternalUpdate(double);
|
bool InternalUpdate(double);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit d6f77c2afe63259dfd23ff80574ebacfc13cca4d
|
Subproject commit a8d0a73f5fff9d6d49d921507451bf55ba368a2a
|
Loading…
Reference in New Issue