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/
build.ninja
.ninja_deps
.ninja_lock
.ninja_log
objdiff.json
orig/*/*

View File

@ -25,6 +25,7 @@ public:
mB = b;
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(uchar r, uchar g, uchar b, uchar a = 255) {

View File

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

View File

@ -90,7 +90,10 @@ public:
}
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;
CVector3f operator*(const CVector3f& vec) const;

View File

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

View File

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

View File

@ -64,8 +64,8 @@ struct SUVElementSet {
class CUVElement : public IElement {
public:
virtual TLockedToken< CTexture > GetValueTexture(int frame) 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 HasConstantUV() const = 0;
};

View File

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

View File

@ -1,5 +1,6 @@
#include "Kyoto/CRandom16.hpp"
#include "Kyoto/Alloc/CMemory.hpp"
#include "Kyoto/Basics/CCast.hpp"
CRandom16* CRandom16::gRandomNumber = nullptr;
CGlobalRandom* CGlobalRandom::gCurrentGlobalRandom = nullptr;
@ -43,6 +44,6 @@ int CRandom16::Next() {
}
float CRandom16::Float() {
int next = Next();
float next = CCast::ToReal32(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 maxY = abs(p1p.GetY() - p2p.GetY());
int left = minX & 0xfffffffe;
int left = minX & ~1;
if (left >= mViewport.mLeft + mViewport.mWidth) {
return CClippedScreenRect();
}
int right = minX + maxX + 2 & 0xfffffffe;
int right = minX + maxX + 2 & ~1;
if (right <= mViewport.mLeft) {
return CClippedScreenRect();
}
left = rstl::max_val(left, mViewport.mLeft) & 0xfffffffe;
right = rstl::min_val(right, mViewport.mLeft + mViewport.mWidth) + 1 & 0xfffffffe;
left = rstl::max_val(left, mViewport.mLeft) & ~1;
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) {
return CClippedScreenRect();
}
int bottom = minY + maxY + 2 & 0xfffffffe;
int bottom = minY + maxY + 2 & ~1;
if (bottom <= mViewport.mTop) {
return CClippedScreenRect();
}
top = rstl::max_val(top, mViewport.mTop) & 0xfffffffe;
bottom = rstl::min_val(bottom, mViewport.mTop + mViewport.mHeight) + 1 & 0xfffffffe;
top = rstl::max_val(top, mViewport.mTop) & ~1;
bottom = rstl::min_val(bottom, mViewport.mTop + mViewport.mHeight) + 1 & ~1;
// int height = bottom - top;
float minV = static_cast< float >(minY - top) / static_cast< float >(bottom - top);
float maxV = static_cast< float >(maxY + (minY - top) + 1) / static_cast< float >(bottom - top);
float minV = CCast::LtoF(minY - top) / CCast::LtoF(bottom - top);
float maxV = CCast::LtoF(maxY + (minY - top) + 1) / CCast::LtoF(bottom - top);
int texAlign = 4;
switch (fmt) {
@ -1424,11 +1423,10 @@ CGraphics::ClipScreenRectFromVS(const CVector3f& p1, const CVector3f& p2, ETexel
texAlign = 2;
break;
}
// int width = right - left;
int texWidth = texAlign + (right - left) - 1 & ~(texAlign - 1);
float minU = static_cast< float >(minX - left) / static_cast< float >(texWidth);
float maxU = static_cast< float >(maxX + (minX - left) + 1) / static_cast< float >(texWidth);
int texWidth = texAlign + (right - left) - 1 & ~(texAlign - 1);
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,
maxV);
}

View File

@ -1,6 +1,8 @@
#include "Weapons/CDecal.hpp"
#include "Kyoto/Graphics/CGX.hpp"
#include "Kyoto/Graphics/CGraphics.hpp"
#include "Kyoto/Graphics/CModel.hpp"
#include "Kyoto/Graphics/CModelFlags.hpp"
#include "Kyoto/Graphics/CTexture.hpp"
#include "Kyoto/Math/CRelAngle.hpp"
#include "Kyoto/Particles/CParticleGlobals.hpp"
@ -57,7 +59,7 @@ void CDecal::RenderQuad(CQuadDecal& decal, const CDecalDescription::SQuadDescr&
}
CTransform4f modXf = xc_transform;
modXf.SetTranslation(modXf.GetTranslation() + offset);
modXf.AddTranslation(offset);
CGraphics::SetModelMatrix(modXf);
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.yMax = 1.f;
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.GetObj(); // ?
CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvModulate);
desc.x14_TEX->GetValueUV(x58_frameIdx, uvSet);
if (redToAlpha) {
@ -116,44 +122,43 @@ void CDecal::RenderQuad(CQuadDecal& decal, const CDecalDescription::SQuadDescr&
CGX::SetVtxDescv(vtxDesc);
CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
float y = 0.001f;
if (decal.x8_rotation == 0.f) {
// Vertex 0
GXPosition3f32(-size, y, 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);
GXPosition3f32(-size, 0.001f, size);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMax);
// Vertex 3
GXPosition3f32(size, y, -size);
// Vertex 1
GXPosition3f32(size, 0.001f, size);
GXColor1u32(color.GetColor_u32());
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 {
CRelAngle ang = CRelAngle::FromDegrees(decal.x8_rotation);
float sinSize = sine(ang) * size;
float cosSize = cosine(ang) * size;
// Vertex 0
GXPosition3f32(sinSize - cosSize, y, 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));
GXPosition3f32(sinSize - cosSize, 0.001f, cosSize + sinSize);
GXColor1u32(color.GetColor_u32());
GXTexCoord2f32(uvSet.xMin, uvSet.yMax);
// Vertex 3
GXPosition3f32(-sinSize + cosSize, y, -cosSize - sinSize);
// Vertex 1
GXPosition3f32(cosSize + sinSize, 0.001f, cosSize - sinSize);
GXColor1u32(color.GetColor_u32());
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();
@ -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 {
CGlobalRandom gr(sDecalRandom);