DolphinCGraphics & CDecal 99%

This commit is contained in:
Luke Street 2024-09-18 23:13:27 -06:00
parent 02ca9b7893
commit 5195d31e22
12 changed files with 135 additions and 54 deletions

4
.flake8 Normal file
View File

@ -0,0 +1,4 @@
[flake8]
# E203: whitespace before ':'
# E501: line too long
extend-ignore = E203,E501

1
.gitignore vendored
View File

@ -14,6 +14,7 @@ tools/mwcc_compiler
versions/ versions/
build.ninja build.ninja
.ninja_deps .ninja_deps
.ninja_lock
.ninja_log .ninja_log
objdiff.json objdiff.json
orig/*/* orig/*/*

View File

@ -25,6 +25,7 @@ public:
mB = b; mB = b;
mA = a; mA = a;
} }
CColor(const CColor& other) : mRgba(other.mRgba) {}
void Set(const float r, const float g, const float b, const float a); void Set(const float r, const float g, const float b, const float a);
void Set(uchar r, uchar g, uchar b, uchar a = 255) { void Set(uchar r, uchar g, uchar b, uchar a = 255) {

View File

@ -9,8 +9,8 @@ class CModelFlags {
public: public:
enum ETrans { enum ETrans {
kT_Opaque = 0, kT_Opaque = 0,
kT_One = 1, // ? kT_One = 1, // ?
kT_Two = 2, // ? kT_Two = 2, // ?
kT_Four = 4, // ? kT_Four = 4, // ?
kT_Blend = 5, kT_Blend = 5,
kT_Additive = 7, kT_Additive = 7,
@ -30,7 +30,7 @@ public:
, x1_matSetIdx(0) , x1_matSetIdx(0)
, x2_flags(kF_DepthCompare | kF_DepthUpdate) , x2_flags(kF_DepthCompare | kF_DepthUpdate)
, x4_color(1.f, 1.f, 1.f, rgba) {} , x4_color(1.f, 1.f, 1.f, rgba) {}
CModelFlags(ETrans trans, CColor color) CModelFlags(ETrans trans, const CColor& color)
: x0_blendMode(trans) : x0_blendMode(trans)
, x1_matSetIdx(0) , x1_matSetIdx(0)
, x2_flags(kF_DepthCompare | kF_DepthUpdate) , x2_flags(kF_DepthCompare | kF_DepthUpdate)
@ -104,7 +104,9 @@ public:
static CModelFlags AlphaBlended(float alpha) { return CModelFlags(kT_Blend, alpha); } static CModelFlags AlphaBlended(float alpha) { return CModelFlags(kT_Blend, alpha); }
static CModelFlags AlphaBlended(const CColor& color) { return CModelFlags(kT_Blend, color); } static CModelFlags AlphaBlended(const CColor& color) { return CModelFlags(kT_Blend, color); }
static CModelFlags Additive(float f) { return CModelFlags(CModelFlags::kT_Additive, f); } static CModelFlags Additive(float f) { return CModelFlags(CModelFlags::kT_Additive, f); }
static CModelFlags Additive(const CColor& color) { return CModelFlags(CModelFlags::kT_Additive, color); } static CModelFlags Additive(const CColor& color) {
return CModelFlags(CModelFlags::kT_Additive, color);
}
static CModelFlags AdditiveRGB(const CColor& color); static CModelFlags AdditiveRGB(const CColor& color);
static CModelFlags ColorModulate(const CColor& color); static CModelFlags ColorModulate(const CColor& color);

View File

@ -90,7 +90,10 @@ public:
} }
void AddTranslationZ(float z) { posZ += z; } void AddTranslationZ(float z) { posZ += z; }
CTransform4f& operator*=(const CTransform4f& other); CTransform4f& operator*=(const CTransform4f& other) {
*this = *this * other;
return *this;
}
CTransform4f operator*(const CTransform4f& vec) const; CTransform4f operator*(const CTransform4f& vec) const;
CVector3f operator*(const CVector3f& vec) const; CVector3f operator*(const CVector3f& vec) const;

View File

@ -5,7 +5,7 @@
class CVector2i { class CVector2i {
public: public:
CVector2i(int, int); CVector2i(int x, int y);
int GetX() const { return mX; } int GetX() const { return mX; }
int GetY() const { return mY; } int GetY() const { return mY; }

View File

@ -16,10 +16,10 @@ class CSpawnSystemKeyframeData;
class CGenDescription { class CGenDescription {
public: public:
typedef rstl::optional_object< TCachedToken< CModel > > TParticleModel; typedef rstl::optional_object< TLockedToken< CModel > > TParticleModel;
typedef rstl::optional_object< TCachedToken< CGenDescription > > TChildGeneratorDesc; typedef rstl::optional_object< TLockedToken< CGenDescription > > TChildGeneratorDesc;
typedef rstl::optional_object< TCachedToken< CSwooshDescription > > TSwooshGeneratorDesc; typedef rstl::optional_object< TLockedToken< CSwooshDescription > > TSwooshGeneratorDesc;
typedef TCachedToken< CElectricDescription > TElectricGeneratorDesc; typedef TLockedToken< CElectricDescription > TElectricGeneratorDesc;
CGenDescription(); CGenDescription();
~CGenDescription(); ~CGenDescription();

View File

@ -64,8 +64,8 @@ struct SUVElementSet {
class CUVElement : public IElement { class CUVElement : public IElement {
public: public:
virtual TLockedToken< CTexture > GetValueTexture(int frame) const = 0;
virtual void GetValueUV(int frame, SUVElementSet& valOut) const = 0; virtual void GetValueUV(int frame, SUVElementSet& valOut) const = 0;
virtual TLockedToken< CTexture > GetValueTexture(int frame) const = 0;
virtual bool HasConstantTexture() const = 0; virtual bool HasConstantTexture() const = 0;
virtual bool HasConstantUV() const = 0; virtual bool HasConstantUV() const = 0;
}; };

View File

@ -54,7 +54,7 @@ private:
int x54_modelLifetime; int x54_modelLifetime;
int x58_frameIdx; int x58_frameIdx;
int x5c_flags; int x5c_flags;
CVector3f x60_rotation; mutable CVector3f x60_rotation;
void InitQuad(CQuadDecal& quad, const CDecalDescription::SQuadDescr& desc, int flag) { void InitQuad(CQuadDecal& quad, const CDecalDescription::SQuadDescr& desc, int flag) {
if (!desc.x14_TEX.null()) { if (!desc.x14_TEX.null()) {

View File

@ -1,5 +1,6 @@
#include "Kyoto/CRandom16.hpp" #include "Kyoto/CRandom16.hpp"
#include "Kyoto/Alloc/CMemory.hpp" #include "Kyoto/Alloc/CMemory.hpp"
#include "Kyoto/Basics/CCast.hpp"
CRandom16* CRandom16::gRandomNumber = nullptr; CRandom16* CRandom16::gRandomNumber = nullptr;
CGlobalRandom* CGlobalRandom::gCurrentGlobalRandom = nullptr; CGlobalRandom* CGlobalRandom::gCurrentGlobalRandom = nullptr;
@ -43,6 +44,6 @@ int CRandom16::Next() {
} }
float CRandom16::Float() { float CRandom16::Float() {
int next = Next(); float next = CCast::ToReal32(Next());
return 1.52590222E-5f * next; return 1.52590222E-5f * next;
} }

View File

@ -1382,33 +1382,32 @@ CGraphics::ClipScreenRectFromVS(const CVector3f& p1, const CVector3f& p2, ETexel
int maxX = abs(p1p.GetX() - p2p.GetX()); int maxX = abs(p1p.GetX() - p2p.GetX());
int maxY = abs(p1p.GetY() - p2p.GetY()); int maxY = abs(p1p.GetY() - p2p.GetY());
int left = minX & 0xfffffffe; int left = minX & ~1;
if (left >= mViewport.mLeft + mViewport.mWidth) { if (left >= mViewport.mLeft + mViewport.mWidth) {
return CClippedScreenRect(); return CClippedScreenRect();
} }
int right = minX + maxX + 2 & 0xfffffffe; int right = minX + maxX + 2 & ~1;
if (right <= mViewport.mLeft) { if (right <= mViewport.mLeft) {
return CClippedScreenRect(); return CClippedScreenRect();
} }
left = rstl::max_val(left, mViewport.mLeft) & 0xfffffffe; left = rstl::max_val(left, mViewport.mLeft) & ~1;
right = rstl::min_val(right, mViewport.mLeft + mViewport.mWidth) + 1 & 0xfffffffe; right = rstl::min_val(right, mViewport.mLeft + mViewport.mWidth) + 1 & ~1;
int top = minY & 0xfffffffe; int top = minY & ~1;
if (top >= mViewport.mTop + mViewport.mHeight) { if (top >= mViewport.mTop + mViewport.mHeight) {
return CClippedScreenRect(); return CClippedScreenRect();
} }
int bottom = minY + maxY + 2 & 0xfffffffe; int bottom = minY + maxY + 2 & ~1;
if (bottom <= mViewport.mTop) { if (bottom <= mViewport.mTop) {
return CClippedScreenRect(); return CClippedScreenRect();
} }
top = rstl::max_val(top, mViewport.mTop) & 0xfffffffe; top = rstl::max_val(top, mViewport.mTop) & ~1;
bottom = rstl::min_val(bottom, mViewport.mTop + mViewport.mHeight) + 1 & 0xfffffffe; bottom = rstl::min_val(bottom, mViewport.mTop + mViewport.mHeight) + 1 & ~1;
// int height = bottom - top; float minV = CCast::LtoF(minY - top) / CCast::LtoF(bottom - top);
float minV = static_cast< float >(minY - top) / static_cast< float >(bottom - top); float maxV = CCast::LtoF(maxY + (minY - top) + 1) / CCast::LtoF(bottom - top);
float maxV = static_cast< float >(maxY + (minY - top) + 1) / static_cast< float >(bottom - top);
int texAlign = 4; int texAlign = 4;
switch (fmt) { switch (fmt) {
@ -1424,11 +1423,10 @@ CGraphics::ClipScreenRectFromVS(const CVector3f& p1, const CVector3f& p2, ETexel
texAlign = 2; texAlign = 2;
break; break;
} }
// int width = right - left;
int texWidth = texAlign + (right - left) - 1 & ~(texAlign - 1);
float minU = static_cast< float >(minX - left) / static_cast< float >(texWidth); int texWidth = texAlign + (right - left) - 1 & ~(texAlign - 1);
float maxU = static_cast< float >(maxX + (minX - left) + 1) / static_cast< float >(texWidth); float minU = CCast::LtoF(minX - left) / CCast::LtoF(texWidth);
float maxU = CCast::LtoF(maxX + (minX - left) + 1) / CCast::LtoF(texWidth);
return CClippedScreenRect(left, top, right - left, bottom - top, texWidth, minU, maxU, minV, return CClippedScreenRect(left, top, right - left, bottom - top, texWidth, minU, maxU, minV,
maxV); maxV);
} }

View File

@ -1,6 +1,8 @@
#include "Weapons/CDecal.hpp" #include "Weapons/CDecal.hpp"
#include "Kyoto/Graphics/CGX.hpp" #include "Kyoto/Graphics/CGX.hpp"
#include "Kyoto/Graphics/CGraphics.hpp" #include "Kyoto/Graphics/CGraphics.hpp"
#include "Kyoto/Graphics/CModel.hpp"
#include "Kyoto/Graphics/CModelFlags.hpp"
#include "Kyoto/Graphics/CTexture.hpp" #include "Kyoto/Graphics/CTexture.hpp"
#include "Kyoto/Math/CRelAngle.hpp" #include "Kyoto/Math/CRelAngle.hpp"
#include "Kyoto/Particles/CParticleGlobals.hpp" #include "Kyoto/Particles/CParticleGlobals.hpp"
@ -57,7 +59,7 @@ void CDecal::RenderQuad(CQuadDecal& decal, const CDecalDescription::SQuadDescr&
} }
CTransform4f modXf = xc_transform; CTransform4f modXf = xc_transform;
modXf.SetTranslation(modXf.GetTranslation() + offset); modXf.AddTranslation(offset);
CGraphics::SetModelMatrix(modXf); CGraphics::SetModelMatrix(modXf);
CGraphics::SetAlphaCompare(kAF_Always, 0, kAO_And, kAF_Always, 0); CGraphics::SetAlphaCompare(kAF_Always, 0, kAO_And, kAF_Always, 0);
@ -80,8 +82,12 @@ void CDecal::RenderQuad(CQuadDecal& decal, const CDecalDescription::SQuadDescr&
uvSet.yMin = 0.f; uvSet.yMin = 0.f;
uvSet.yMax = 1.f; uvSet.yMax = 1.f;
if (!desc.x14_TEX.null()) { if (!desc.x14_TEX.null()) {
TLockedToken< CTexture > tex = desc.x14_TEX->GetValueTexture(x58_frameIdx); TToken< CTexture > tex = desc.x14_TEX->GetValueTexture(x58_frameIdx);
if (!tex.IsLoaded()) {
return;
}
tex->Load(GX_TEXMAP0, CTexture::kCM_Repeat); tex->Load(GX_TEXMAP0, CTexture::kCM_Repeat);
tex.GetObj(); // ?
CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvModulate); CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvModulate);
desc.x14_TEX->GetValueUV(x58_frameIdx, uvSet); desc.x14_TEX->GetValueUV(x58_frameIdx, uvSet);
if (redToAlpha) { if (redToAlpha) {
@ -116,44 +122,43 @@ void CDecal::RenderQuad(CQuadDecal& decal, const CDecalDescription::SQuadDescr&
CGX::SetVtxDescv(vtxDesc); CGX::SetVtxDescv(vtxDesc);
CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
float y = 0.001f;
if (decal.x8_rotation == 0.f) { if (decal.x8_rotation == 0.f) {
// Vertex 0 // Vertex 0
GXPosition3f32(-size, y, size); GXPosition3f32(-size, 0.001f, size);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMin);
// Vertex 1
GXPosition3f32(size, y, size);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMax, uvSet.yMin);
// Vertex 2
GXPosition3f32(-size, y, -size);
GXColor1u32(color.GetColor_u32()); GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMax); GXTexCoord2f32(uvSet.xMin, uvSet.yMax);
// Vertex 3 // Vertex 1
GXPosition3f32(size, y, -size); GXPosition3f32(size, 0.001f, size);
GXColor1u32(color.GetColor_u32()); GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMax, uvSet.yMax); GXTexCoord2f32(uvSet.xMax, uvSet.yMax);
// Vertex 2
GXPosition3f32(-size, 0.001f, -size);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMin);
// Vertex 3
GXPosition3f32(size, 0.001f, -size);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMax, uvSet.yMin);
} else { } else {
CRelAngle ang = CRelAngle::FromDegrees(decal.x8_rotation); CRelAngle ang = CRelAngle::FromDegrees(decal.x8_rotation);
float sinSize = sine(ang) * size; float sinSize = sine(ang) * size;
float cosSize = cosine(ang) * size; float cosSize = cosine(ang) * size;
// Vertex 0 // Vertex 0
GXPosition3f32(sinSize - cosSize, y, cosSize + sinSize); GXPosition3f32(sinSize - cosSize, 0.001f, cosSize + sinSize);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMin);
// Vertex 1
GXPosition3f32(cosSize + sinSize, y, cosSize - sinSize);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMax, uvSet.yMin);
// Vertex 2
GXPosition3f32(-(cosSize + sinSize), y, -(cosSize - sinSize));
GXColor1u32(color.GetColor_u32()); GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMax); GXTexCoord2f32(uvSet.xMin, uvSet.yMax);
// Vertex 3 // Vertex 1
GXPosition3f32(-sinSize + cosSize, y, -cosSize - sinSize); GXPosition3f32(cosSize + sinSize, 0.001f, cosSize - sinSize);
GXColor1u32(color.GetColor_u32()); GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMax, uvSet.yMax); GXTexCoord2f32(uvSet.xMax, uvSet.yMax);
// Vertex 2
GXPosition3f32(-(cosSize + sinSize), 0.001f, -(cosSize - sinSize));
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMin);
// Vertex 3
GXPosition3f32(-sinSize + cosSize, 0.001f, -cosSize - sinSize);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMax, uvSet.yMin);
} }
CGX::End(); CGX::End();
@ -163,7 +168,73 @@ void CDecal::RenderQuad(CQuadDecal& decal, const CDecalDescription::SQuadDescr&
} }
} }
void CDecal::RenderMdl() const {} void CDecal::RenderMdl() const {
CColor color = CColor::White();
CVector3f offset = CVector3f::Zero();
CTransform4f rotXf = CTransform4f::Identity();
if (!x0_description->x5c_25_DMOO) {
rotXf = xc_transform.GetRotation();
}
bool dmrtIsConst = false;
if (CVectorElement* off = x0_description->x50_DMRT.get()) {
if (off->IsFastConstant()) {
dmrtIsConst = true;
}
}
CTransform4f dmrtXf = CTransform4f::Identity();
if (dmrtIsConst) {
x0_description->x50_DMRT->GetValue(x58_frameIdx, x60_rotation);
dmrtXf = CTransform4f::RotateZ(CRelAngle::FromDegrees(x60_rotation.GetZ()));
dmrtXf.RotateLocalY(CRelAngle::FromDegrees(x60_rotation.GetY()));
dmrtXf.RotateLocalX(CRelAngle::FromDegrees(x60_rotation.GetX()));
}
dmrtXf = rotXf * dmrtXf;
if (CVectorElement* off = x0_description->x4c_DMOP.get()) {
off->GetValue(x58_frameIdx, offset);
}
CTransform4f worldXf = CTransform4f::Translate(xc_transform.GetTranslation() + rotXf * offset);
if (dmrtIsConst) {
worldXf *= dmrtXf;
} else if (CVectorElement* dmrt = x0_description->x50_DMRT.get()) {
CVector3f rotation(0.f, 0.f, 0.f);
dmrt->GetValue(x58_frameIdx, rotation);
dmrtXf = CTransform4f::RotateZ(CRelAngle::FromDegrees(rotation.GetZ()));
dmrtXf.RotateLocalY(CRelAngle::FromDegrees(rotation.GetY()));
dmrtXf.RotateLocalX(CRelAngle::FromDegrees(rotation.GetX()));
worldXf *= rotXf * dmrtXf;
} else {
worldXf *= dmrtXf;
}
if (CVectorElement* dmsc = x0_description->x54_DMSC.get()) {
CVector3f scale(0.f, 0.f, 0.f);
dmsc->GetValue(x58_frameIdx, scale);
worldXf *= CTransform4f::Scale(scale.GetX(), scale.GetY(), scale.GetZ());
}
if (CColorElement* dmcl = x0_description->x58_DMCL.get()) {
dmcl->GetValue(x58_frameIdx, color);
}
CGraphics::SetModelMatrix(worldXf);
if (x0_description->x5c_24_DMAB) {
const CModelFlags flags = CModelFlags::Additive(color).DepthCompareUpdate(true, false);
(*x0_description->x38_DMDL)->Draw(flags);
} else if (color.GetAlpha() == 1.f) {
(*x0_description->x38_DMDL)->Draw(CModelFlags::Normal());
} else {
const CModelFlags flags = CModelFlags::AlphaBlended(color).DepthCompareUpdate(true, false);
(*x0_description->x38_DMDL)->Draw(flags);
}
CGraphics::SetCullMode(kCM_Front);
CTevCombiners::ResetStates();
}
void CDecal::Render() const { void CDecal::Render() const {
CGlobalRandom gr(sDecalRandom); CGlobalRandom gr(sDecalRandom);