mirror of https://github.com/PrimeDecomp/prime.git
DolphinCGraphics & CDecal 99%
This commit is contained in:
parent
02ca9b7893
commit
5195d31e22
|
@ -0,0 +1,4 @@
|
|||
[flake8]
|
||||
# E203: whitespace before ':'
|
||||
# E501: line too long
|
||||
extend-ignore = E203,E501
|
|
@ -14,6 +14,7 @@ tools/mwcc_compiler
|
|||
versions/
|
||||
build.ninja
|
||||
.ninja_deps
|
||||
.ninja_lock
|
||||
.ninja_log
|
||||
objdiff.json
|
||||
orig/*/*
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue