mirror of https://github.com/PrimeDecomp/prime.git
parent
7c6839fee7
commit
16987ab59b
|
@ -184,12 +184,18 @@ public:
|
|||
public:
|
||||
CRenderState();
|
||||
|
||||
void Flush();
|
||||
void ResetFlushAll();
|
||||
void SetVtxState(const float*, const float*, const unsigned int*);
|
||||
|
||||
// In map this takes two args, but x4 is unused?
|
||||
void Set(int v0) { x0_ = v0; }
|
||||
|
||||
private:
|
||||
int x0_;
|
||||
int x4_;
|
||||
};
|
||||
|
||||
class CProjectionState {
|
||||
public:
|
||||
CProjectionState(bool persp, float left, float right, float top, float bottom, float near,
|
||||
|
@ -245,6 +251,14 @@ public:
|
|||
static void SetDefaultVtxAttrFmt();
|
||||
static CMatrix4f GetPerspectiveProjectionMatrix();
|
||||
static CMatrix4f CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar);
|
||||
static void ResetGfxStates();
|
||||
static void LoadDolphinSpareTexture(int width, int height, GXTexFmt fmt, void* data,
|
||||
GXTexMapID texId);
|
||||
static void LoadDolphinSpareTexture(int width, int height, GXCITexFmt fmt, GXTlut tlut,
|
||||
void* data, GXTexMapID texId);
|
||||
static void TickRenderTimings();
|
||||
static const CProjectionState& GetProjectionState();
|
||||
static void SetProjectionState(const CProjectionState& proj);
|
||||
|
||||
static float GetDepthNear() { return mDepthNear; }
|
||||
static float GetDepthFar() { return mDepthFar; }
|
||||
|
@ -267,7 +281,8 @@ public:
|
|||
static void StreamNormal(const float* nrm);
|
||||
static void StreamEnd();
|
||||
static void Render2D(const CTexture& tex, int x, int y, int w, int h, const CColor& col);
|
||||
static void DrawPrimitive(ERglPrimitive primitive, const float* pos, const CVector3f& normal, const CColor& col, int numVerts);
|
||||
static void DrawPrimitive(ERglPrimitive primitive, const float* pos, const CVector3f& normal,
|
||||
const CColor& col, int numVerts);
|
||||
|
||||
static void VideoPreCallback(u32 retraceCount);
|
||||
static void VideoPostCallback(u32 retraceCount);
|
||||
|
@ -351,7 +366,7 @@ private:
|
|||
static GXTexRegionCallback mGXDefaultTexRegionCallback;
|
||||
static void* mpFifo;
|
||||
static GXFifoObj* mpFifoObj;
|
||||
static int mRenderTimings;
|
||||
static uint mRenderTimings;
|
||||
static float mSecondsMod900;
|
||||
static CTimeProvider* mpExternalTimeProvider;
|
||||
// lbl_805A9408
|
||||
|
|
|
@ -28,6 +28,7 @@ void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 t
|
|||
void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even,
|
||||
GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd);
|
||||
GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback);
|
||||
void GXInvalidateTexRegion(const GXTexRegion* region);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ int CGraphics::mSpareBufferTexCacheSize;
|
|||
GXTexRegionCallback CGraphics::mGXDefaultTexRegionCallback;
|
||||
void* CGraphics::mpFifo;
|
||||
GXFifoObj* CGraphics::mpFifoObj;
|
||||
int CGraphics::mRenderTimings;
|
||||
uint CGraphics::mRenderTimings;
|
||||
float CGraphics::mSecondsMod900;
|
||||
CTimeProvider* CGraphics::mpExternalTimeProvider;
|
||||
int lbl_805A9408;
|
||||
|
@ -1130,3 +1130,226 @@ void CGraphics::SetTevStates(uchar flags) {
|
|||
(flags & kHasColor) ? GX_SRC_VTX : GX_SRC_REG, static_cast< GXLightID >(light),
|
||||
diffFn, attnFn);
|
||||
}
|
||||
|
||||
void CGraphics::FullRender() {
|
||||
CGX::Begin(static_cast< GXPrimitive >(mCurrentPrimitive), GX_VTXFMT0, mNumPrimitives);
|
||||
switch (vtxDescr.streamFlags) {
|
||||
case 0:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
}
|
||||
break;
|
||||
case kHasNormals:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
const Vec& nrm = nrmBuffer[i];
|
||||
GXNormal3f32(nrm.x, nrm.y, nrm.z);
|
||||
}
|
||||
break;
|
||||
case kHasColor:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
GXColor1u32(clrBuffer[i]);
|
||||
}
|
||||
break;
|
||||
case kHasTexture:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
const Vec2& uv = txtBuffer0[i];
|
||||
GXTexCoord2f32(uv.x, uv.y);
|
||||
}
|
||||
break;
|
||||
case kHasNormals | kHasTexture:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
const Vec& nrm = nrmBuffer[i];
|
||||
GXNormal3f32(nrm.x, nrm.y, nrm.z);
|
||||
const Vec2& uv = txtBuffer0[i];
|
||||
GXTexCoord2f32(uv.x, uv.y);
|
||||
}
|
||||
break;
|
||||
case kHasNormals | kHasColor:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
const Vec& nrm = nrmBuffer[i];
|
||||
GXNormal3f32(nrm.x, nrm.y, nrm.z);
|
||||
GXColor1u32(clrBuffer[i]);
|
||||
}
|
||||
break;
|
||||
case kHasColor | kHasTexture:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
GXColor1u32(clrBuffer[i]);
|
||||
const Vec2& uv = txtBuffer0[i];
|
||||
GXTexCoord2f32(uv.x, uv.y);
|
||||
}
|
||||
break;
|
||||
case kHasNormals | kHasColor | kHasTexture:
|
||||
for (int i = 0; i < mNumPrimitives; i++) {
|
||||
const Vec& vtx = vtxBuffer[i];
|
||||
GXPosition3f32(vtx.x, vtx.y, vtx.z);
|
||||
const Vec& nrm = nrmBuffer[i];
|
||||
GXNormal3f32(nrm.x, nrm.y, nrm.z);
|
||||
GXColor1u32(clrBuffer[i]);
|
||||
const Vec2& uv = txtBuffer0[i];
|
||||
GXTexCoord2f32(uv.x, uv.y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
CGX::End();
|
||||
}
|
||||
|
||||
void CGraphics::SetDepthRange(float near, float far) {
|
||||
mDepthNear = near;
|
||||
mDepthFar = far;
|
||||
GXSetViewport(static_cast< float >(mViewport.mLeft), static_cast< float >(mViewport.mTop),
|
||||
static_cast< float >(mViewport.mWidth), static_cast< float >(mViewport.mHeight),
|
||||
mDepthNear, mDepthFar);
|
||||
}
|
||||
|
||||
static inline GXTevStageID get_texture_unit(ERglTevStage stage) {
|
||||
#if NONMATCHING
|
||||
// one instruction, no branches
|
||||
return static_cast< GXTevStageID >(stage & (GX_MAX_TEVSTAGE - 1));
|
||||
#else
|
||||
if (stage == kTS_Stage0) {
|
||||
return GX_TEVSTAGE0;
|
||||
} else if (stage == kTS_Stage1) {
|
||||
return GX_TEVSTAGE1;
|
||||
} else if (stage == kTS_Stage2) {
|
||||
return GX_TEVSTAGE2;
|
||||
} else if (stage == kTS_Stage3) {
|
||||
return GX_TEVSTAGE3;
|
||||
} else if (stage == kTS_Stage4) {
|
||||
return GX_TEVSTAGE4;
|
||||
} else if (stage == kTS_Stage5) {
|
||||
return GX_TEVSTAGE5;
|
||||
} else if (stage == kTS_Stage6) {
|
||||
return GX_TEVSTAGE6;
|
||||
} else if (stage == kTS_Stage7) {
|
||||
return GX_TEVSTAGE7;
|
||||
} else if (stage == kTS_Stage8) {
|
||||
return GX_TEVSTAGE8;
|
||||
} else if (stage == kTS_Stage9) {
|
||||
return GX_TEVSTAGE9;
|
||||
} else if (stage == kTS_Stage10) {
|
||||
return GX_TEVSTAGE10;
|
||||
} else if (stage == kTS_Stage11) {
|
||||
return GX_TEVSTAGE11;
|
||||
} else if (stage == kTS_Stage12) {
|
||||
return GX_TEVSTAGE12;
|
||||
} else if (stage == kTS_Stage13) {
|
||||
return GX_TEVSTAGE13;
|
||||
} else if (stage == kTS_Stage14) {
|
||||
return GX_TEVSTAGE14;
|
||||
}
|
||||
// wtf?
|
||||
return static_cast< GXTevStageID >(stage == kTS_Stage15 ? GX_TEVSTAGE15 : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGraphics::SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass) {
|
||||
CTevCombiners::SetupPass(get_texture_unit(stage), pass);
|
||||
}
|
||||
|
||||
void CGraphics::SetFog(ERglFogMode mode, float startz, float endz, const CColor& color) {
|
||||
CGX::SetFog(static_cast< GXFogType >(mode), startz, endz, mProj.GetNear(), mProj.GetFar(),
|
||||
color.GetGXColor());
|
||||
}
|
||||
|
||||
void CGraphics::ResetGfxStates() { sRenderState.Set(0); }
|
||||
|
||||
void CGraphics::SetDefaultVtxAttrFmt() {
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 14);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 14);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_TEX0, GX_TEX_ST, GX_U16, 15);
|
||||
for (int i = 1; i <= 7; ++i) {
|
||||
GXAttr attr = static_cast< GXAttr >(GX_VA_TEX0 + i);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, attr, GX_TEX_ST, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, attr, GX_TEX_ST, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT2, attr, GX_TEX_ST, GX_F32, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphics::LoadDolphinSpareTexture(int width, int height, GXTexFmt fmt, void* data,
|
||||
GXTexMapID texId) {
|
||||
GXTexObj texObj;
|
||||
GXInitTexObj(&texObj, data != nullptr ? data : mpSpareBuffer, width, height, fmt, GX_CLAMP,
|
||||
GX_CLAMP, GX_DISABLE);
|
||||
GXInitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.f, 0.f, 0.f, GX_DISABLE, GX_DISABLE, GX_ANISO_1);
|
||||
GXLoadTexObj(&texObj, texId);
|
||||
CTexture::InvalidateTexmap(texId);
|
||||
if (texId == GX_TEXMAP7) {
|
||||
GXInvalidateTexRegion(&mTexRegions[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphics::LoadDolphinSpareTexture(int width, int height, GXCITexFmt fmt, GXTlut tlut,
|
||||
void* data, GXTexMapID texId) {
|
||||
GXTexObj texObj;
|
||||
GXInitTexObjCI(&texObj, data != nullptr ? data : mpSpareBuffer, width, height, fmt, GX_CLAMP,
|
||||
GX_CLAMP, GX_DISABLE, tlut);
|
||||
GXInitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.f, 0.f, 0.f, GX_DISABLE, GX_DISABLE, GX_ANISO_1);
|
||||
GXLoadTexObj(&texObj, texId);
|
||||
CTexture::InvalidateTexmap(texId);
|
||||
if (texId == GX_TEXMAP7) {
|
||||
GXInvalidateTexRegion(&mTexRegions[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphics::TickRenderTimings() {
|
||||
mRenderTimings = (mRenderTimings + 1) % (900 * 60);
|
||||
mSecondsMod900 = static_cast< float >(mRenderTimings) / 60.f;
|
||||
}
|
||||
|
||||
float CGraphics::GetSecondsMod900() {
|
||||
if (mpExternalTimeProvider != nullptr) {
|
||||
return mpExternalTimeProvider->GetSecondsMod900();
|
||||
}
|
||||
return mSecondsMod900;
|
||||
}
|
||||
|
||||
void CGraphics::SetExternalTimeProvider(CTimeProvider* timeProvider) {
|
||||
mpExternalTimeProvider = timeProvider;
|
||||
}
|
||||
|
||||
void CGraphics::FlushProjection() {
|
||||
float right = mProj.GetRight();
|
||||
float left = mProj.GetLeft();
|
||||
float top = mProj.GetTop();
|
||||
float bottom = mProj.GetBottom();
|
||||
float near = mProj.GetNear();
|
||||
float far = mProj.GetFar();
|
||||
if (mProj.IsPerspective()) {
|
||||
Mtx44 mtx;
|
||||
MTXFrustum(mtx, top, bottom, left, right, near, far);
|
||||
GXSetProjection(mtx, GX_PERSPECTIVE);
|
||||
} else {
|
||||
Mtx44 mtx;
|
||||
MTXOrtho(mtx, top, bottom, left, right, near, far);
|
||||
GXSetProjection(mtx, GX_ORTHOGRAPHIC);
|
||||
}
|
||||
}
|
||||
|
||||
const CGraphics::CProjectionState& CGraphics::GetProjectionState() { return mProj; }
|
||||
|
||||
void CGraphics::SetProjectionState(const CProjectionState& proj) {
|
||||
mProj = proj;
|
||||
FlushProjection();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue