From 2bff2f4d6b67e7717f553124373f5a2a9a59fc21 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 30 Nov 2022 01:43:17 -0500 Subject: [PATCH] More DolphinCGraphics Former-commit-id: d9f71836b51dc78af6ba27be9ac65cd769204467 --- include/Kyoto/Graphics/CGraphics.hpp | 2 + include/dolphin/mtx.h | 76 ++++++++++++++++- src/Kyoto/Graphics/DolphinCGraphics.cpp | 108 ++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 3 deletions(-) diff --git a/include/Kyoto/Graphics/CGraphics.hpp b/include/Kyoto/Graphics/CGraphics.hpp index 99df089b..59388438 100644 --- a/include/Kyoto/Graphics/CGraphics.hpp +++ b/include/Kyoto/Graphics/CGraphics.hpp @@ -210,6 +210,8 @@ public: static void ConfigureFrameBuffer(const COsContext& osContext); static void EnableLight(ERglLight light); static void LoadLight(ERglLight light, const CLight& info); + static void SetLightState(uchar lights); + static void SetViewMatrix(); static void SetIdentityViewPointMatrix(); static void SetIdentityModelMatrix(); diff --git a/include/dolphin/mtx.h b/include/dolphin/mtx.h index f1eec99d..f57beeaf 100644 --- a/include/dolphin/mtx.h +++ b/include/dolphin/mtx.h @@ -9,13 +9,23 @@ extern "C" { typedef f32 Mtx[3][4]; typedef f32 (*MtxPtr)[4]; +typedef f32 ROMtx[4][3]; +typedef f32 (*ROMtxPtr)[3]; +typedef f32 Mtx44[4][4]; +typedef f32 (*Mtx44Ptr)[4]; typedef struct { - f32 x; - f32 y; - f32 z; + f32 x, y, z; } Vec, *VecPtr; +typedef struct { + s16 x, y, z; +} S16Vec, *S16VecPtr; + +typedef struct { + f32 x, y, z, w; +} Quaternion, *QuaternionPtr; + void C_MTXIdentity(Mtx m); void C_MTXCopy(const Mtx src, Mtx dst); void C_MTXConcat(const Mtx a, const Mtx b, Mtx ab); @@ -27,6 +37,27 @@ void C_MTXMultVec(const Mtx m, const Vec* src, Vec* dst); void C_MTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); void C_MTXMultVecSR(const Mtx m, const Vec* src, Vec* dst); void C_MTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); +void C_MTXQuat(Mtx m, const Quaternion* q); +void C_MTXReflect(Mtx m, const Vec* p, const Vec* n); +void C_MTXTrans(Mtx m, f32 xT, f32 yT, f32 zT); +void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT); +void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS); +void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS); +void C_MTXRotRad(Mtx m, char axis, f32 rad); +void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA); +void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); +void C_MTXLookAt(Mtx m, const Vec* camPos, const Vec* camUp, const Vec* target); +void C_MTXFrustum(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f); +void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f); +void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f); +void C_MTXLightFrustum(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 scaleS, f32 scaleT, f32 transS, + f32 transT); + +void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, + f32 transT); + +void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, + f32 transT); #ifdef __MWERKS__ void PSMTXIdentity(Mtx m); @@ -40,6 +71,15 @@ void PSMTXMultVec(const Mtx m, const Vec* src, Vec* dst); void PSMTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); void PSMTXMultVecSR(const Mtx m, const Vec* src, Vec* dst); void PSMTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); +void PSMTXQuat(Mtx m, const Quaternion* q); +void PSMTXReflect(Mtx m, const Vec* p, const Vec* n); +void PSMTXTrans(Mtx m, f32 xT, f32 yT, f32 zT); +void PSMTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT); +void PSMTXScale(Mtx m, f32 xS, f32 yS, f32 zS); +void PSMTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS); +void PSMTXRotRad(Mtx m, char axis, f32 rad); +void PSMTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA); +void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); #endif #ifdef __MWERKS__ @@ -54,6 +94,17 @@ void PSMTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 coun #define MTXMultVecArray PSMTXMultVecArray #define MTXMultVecSR PSMTXMultVecSR #define MTXMultVecArraySR PSMTXMultVecArraySR +#define MTXQuat PSMTXQuat +#define MTXReflect PSMTXReflect +#define MTXTrans PSMTXTrans +#define MTXTransApply PSMTXTransApply +#define MTXScale PSMTXScale +#define MTXScaleApply PSMTXScaleApply +#define MTXRotRad PSMTXRotRad +#define MTXRotTrig PSMTXRotTrig +#define MTXRotAxisRad PSMTXRotAxisRad +#define MTXRotDeg(m, axis, deg) PSMTXRotRad(m, axis, MTXDegToRad(deg)) +#define MTXRotAxisDeg(m, axis, deg) PSMTXRotAxisRad(m, axis, MTXDegToRad(deg)) #else #define MTXIdentity C_MTXIdentity #define MTXCopy C_MTXCopy @@ -66,8 +117,27 @@ void PSMTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 coun #define MTXMultVecArray C_MTXMultVecArray #define MTXMultVecSR C_MTXMultVecSR #define MTXMultVecArraySR C_MTXMultVecArraySR +#define MTXQuat C_MTXQuat +#define MTXReflect C_MTXReflect +#define MTXTrans C_MTXTrans +#define MTXTransApply C_MTXTransApply +#define MTXScale C_MTXScale +#define MTXScaleApply C_MTXScaleApply +#define MTXRotRad C_MTXRotRad +#define MTXRotTrig C_MTXRotTrig +#define MTXRotAxisRad C_MTXRotAxisRad +#define MTXRotDeg(m, axis, deg) C_MTXRotRad(m, axis, MTXDegToRad(deg)) +#define MTXRotAxisDeg(m, axis, deg) C_MTXRotAxisRad(m, axis, MTXDegToRad(deg)) #endif +#define MTXLookAt C_MTXLookAt +#define MTXFrustum C_MTXFrustum +#define MTXPerspective C_MTXPerspective +#define MTXOrtho C_MTXOrtho +#define MTXLightFrustum C_MTXLightFrustum +#define MTXLightPerspective C_MTXLightPerspective +#define MTXLightOrtho C_MTXLightOrtho + #ifdef __cplusplus } #endif diff --git a/src/Kyoto/Graphics/DolphinCGraphics.cpp b/src/Kyoto/Graphics/DolphinCGraphics.cpp index 50f419ff..311f27a7 100644 --- a/src/Kyoto/Graphics/DolphinCGraphics.cpp +++ b/src/Kyoto/Graphics/DolphinCGraphics.cpp @@ -383,6 +383,9 @@ void CGraphics::EnableLight(ERglLight light) { } static inline GXLightID get_hw_light_index(ERglLight light) { +#if NONMATCHING + return static_cast< GXLightID >((light << 1) & (GX_MAX_LIGHT - 1)); +#else if (light == kLight0) { return GX_LIGHT0; } else if (light == kLight1) { @@ -400,6 +403,7 @@ static inline GXLightID get_hw_light_index(ERglLight light) { } // wtf? return static_cast< GXLightID >(light == kLight7 ? GX_LIGHT7 : 0); +#endif } void CGraphics::LoadLight(ERglLight light, const CLight& info) { @@ -462,3 +466,107 @@ void CGraphics::DisableAllLights() { CGX::SetChanCtrl(CGX::Channel0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); } + +// https://en.wikipedia.org/wiki/Hamming_weight +static inline uint popcount8(uint b) { + b = (b & 0x55) + ((b & 0xAA) >> 1); + b = (b & 0x33) + ((b & 0xCC) >> 2); + return (static_cast< uchar >(b) & 0xF) + (static_cast< uchar >(b) >> 4); +} + +void CGraphics::SetLightState(uchar lights) { + GXAttnFn attnFn = GX_AF_NONE; + if (lights != 0) { + attnFn = GX_AF_SPOT; + } + GXDiffuseFn diffFn = GX_DF_NONE; + if (lights != 0) { + diffFn = GX_DF_CLAMP; + } + CGX::SetChanCtrl(CGX::Channel0, lights != 0 ? GX_TRUE : GX_FALSE, GX_SRC_REG, + (vtxDescr.streamFlags & 2) != 0 ? GX_SRC_VTX : GX_SRC_REG, + static_cast< GXLightID >(lights), diffFn, attnFn); + mLightActive = lights; + mNumLightsActive = popcount8(lights); +} + +void CGraphics::SetViewMatrix() { + Mtx mtx; + MTXTrans(mtx, -mViewPoint.GetX(), -mViewPoint.GetY(), -mViewPoint.GetZ()); + MTXConcat(mGXViewPointMatrix, mtx, mCameraMtx); + if (mIsGXModelMatrixIdentity) { + MTXCopy(mCameraMtx, mGxModelView); + } else { + MTXConcat(mCameraMtx, mGXModelMatrix, mGxModelView); + } + GXLoadPosMtxImm(mGxModelView, GX_PNMTX0); + + Mtx nrmMtx; + MTXInvXpose(mGxModelView, nrmMtx); + GXLoadNrmMtxImm(nrmMtx, GX_PNMTX0); +} + +void CGraphics::SetViewPointMatrix(const CTransform4f& xf) { + mViewMatrix = xf; + mGXViewPointMatrix[0][0] = xf.Get00(); + mGXViewPointMatrix[0][1] = xf.Get10(); + mGXViewPointMatrix[0][2] = xf.Get20(); + mGXViewPointMatrix[0][3] = 0.f; + mGXViewPointMatrix[1][0] = xf.Get02(); + mGXViewPointMatrix[1][1] = xf.Get12(); + mGXViewPointMatrix[1][2] = xf.Get22(); + mGXViewPointMatrix[1][3] = 0.f; + mGXViewPointMatrix[2][0] = -xf.Get01(); + mGXViewPointMatrix[2][1] = -xf.Get11(); + mGXViewPointMatrix[2][2] = -xf.Get21(); + mGXViewPointMatrix[2][3] = 0.f; + mViewPoint = xf.GetTranslation(); + SetViewMatrix(); +} + +void CGraphics::SetIdentityViewPointMatrix() { + mViewMatrix = CTransform4f::Identity(); + MTXIdentity(mGXViewPointMatrix); + mGXViewPointMatrix[2][2] = 0.0; + mGXViewPointMatrix[1][1] = 0.0; + mGXViewPointMatrix[1][2] = 1.0; + mGXViewPointMatrix[2][1] = -1.0; + mViewPoint = CVector3f::Zero(); + SetViewMatrix(); +} + +// TODO: non-matching +void CGraphics::SetModelMatrix(const CTransform4f& xf) { + if (&xf == &CTransform4f::Identity()) { + if (!mIsGXModelMatrixIdentity) { + mModelMatrix = CTransform4f::Identity(); + mIsGXModelMatrixIdentity = true; + SetViewMatrix(); + } + return; + } + + mModelMatrix = xf; + mIsGXModelMatrixIdentity = false; + mGXModelMatrix[0][0] = xf.Get00(); + mGXModelMatrix[0][1] = xf.Get01(); + mGXModelMatrix[0][2] = xf.Get02(); + mGXModelMatrix[0][3] = xf.Get03(); + mGXModelMatrix[1][0] = xf.Get10(); + mGXModelMatrix[1][1] = xf.Get11(); + mGXModelMatrix[1][2] = xf.Get12(); + mGXModelMatrix[1][3] = xf.Get13(); + mGXModelMatrix[2][0] = xf.Get20(); + mGXModelMatrix[2][1] = xf.Get21(); + mGXModelMatrix[2][2] = xf.Get22(); + mGXModelMatrix[2][3] = xf.Get23(); + SetViewMatrix(); +} + +void CGraphics::SetIdentityModelMatrix() { + if (!mIsGXModelMatrixIdentity) { + mModelMatrix = CTransform4f::Identity(); + mIsGXModelMatrixIdentity = true; + SetViewMatrix(); + } +}