LightTextureManager OK

This commit is contained in:
robojumper
2025-03-27 17:52:09 +01:00
parent e8d9aae33e
commit 64528b423f
8 changed files with 198 additions and 28 deletions
+157 -8
View File
@@ -1,18 +1,26 @@
#include "egg/gfx/eggLightTextureMgr.h"
#include "common.h"
#include "egg/gfx/eggDrawGX.h"
#include "egg/gfx/eggG3DUtility.h"
#include "egg/gfx/eggLightObject.h"
#include "egg/gfx/eggLightTexture.h"
#include "egg/gfx/eggStateGX.h"
#include "egg/gfx/eggTextureBuffer.h"
#include "nw4r/g3d/res/g3d_resmat.h"
#include "nw4r/math/math_types.h"
#include "nw4r/ut/ut_Color.h"
#include "rvl/GX/GXTexture.h"
#include "rvl/GX/GXTypes.h"
#include "rvl/MTX/mtx.h"
#include "rvl/MTX/mtx44.h"
#include <cstring>
namespace EGG {
LightTextureManager::LightTextureManager(const LightManager *lightMgr) {
field_0x04 = 0x78;
mFlags = 0x78;
mTextureCount = 0;
mpTextures = nullptr;
mpLightMgr = lightMgr;
@@ -25,14 +33,14 @@ LightTextureManager::LightTextureManager(const LightManager *lightMgr) {
mpTextures[i] = nullptr;
}
mpObjects = new LightObject *[mMaxNumTextures];
mpObjects = new const LightObject *[mMaxNumTextures];
for (int i = 0; i < mMaxNumTextures; i++) {
mpObjects[i] = nullptr;
}
if ((StateGX::s_flag & 0x40) != 0) {
field_0x04 |= 0x80;
field_0x04 &= ~0x40;
mFlags |= 0x80;
mFlags &= ~0x40;
field_0x16 = 3;
}
}
@@ -106,18 +114,37 @@ int LightTextureManager::replaceModelTextures(nw4r::g3d::ResMdl mdl) const {
return count;
}
int LightTextureManager::replaceModelTexture(u16 tex, nw4r::g3d::ResMdl mdl) const {
int LightTextureManager::replaceModelTexture(int tex, nw4r::g3d::ResMdl mdl) const {
if (mpTextures[tex] == nullptr) {
return 0;
}
G3DUtility::SetTextureResult buf[256];
GXTexObj obj;
mpTextures[tex]->getTexObj(&obj);
int count = 0;
for (u32 i = 0; i < mdl.GetResMatNumEntries(); i++) {
for (int i = 0; i < mdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ResMat mat = mdl.GetResMat(i);
// TODO
// count += G3DUtility::SetTexture(mat, nullptr, mpLightMgr[tex]->getName(), obj, false, void *param_6, int param_7, int param_8)
int res = G3DUtility::SetTexture(mat, nullptr, mpTextures[tex]->getName(), &obj, false, buf, 0xFF, 2);
for (int j = 0; j < (u16)res; j++) {
if (buf[j].texCoordId != -1) {
fn_804AE340(mat, static_cast<GXTexCoordID>(buf[j].texCoordId));
}
}
count += res;
}
return count;
}
int LightTextureManager::getTextureIndex(const char *name) const {
for (int i = 0; i < mTextureCount; i++) {
if (!strcmp(name, mpTextures[i]->getName())) {
return i;
}
}
return -1;
}
bool LightTextureManager::setBinaryToTexture(const void *data) {
@@ -131,6 +158,114 @@ bool LightTextureManager::setBinaryToTexture(const void *data) {
return false;
}
void LightTextureManager::correctLightObject() {
int j = 0;
for (int i = 0; i < mpLightMgr->GetNumLightData(); i++) {
const LightObject *o = mpLightMgr->GetLightObject(i);
if (o->CheckFlag1() && o->CheckFlag0x20()) {
mpObjects[j] = o;
j++;
if (j >= mMaxNumTextures) {
break;
}
}
}
for (int i = j; i < mMaxNumTextures; i++) {
mpObjects[i] = nullptr;
}
}
void LightTextureManager::frameReset() {
correctLightObject();
field_0x10 = 0;
}
void LightTextureManager::drawAndCaptureTexture(f32 ox, f32 oy, f32 sx, f32 sy) {
bool b1 = getSomeTfRelatedBool();
u32 mask1 = 1 << (mpLightMgr->GetField0x1D());
if ((mFlags & 0x10) == 0 || (field_0x10 & mask1) != 0 || mTextureCount == 0) {
return;
}
StateGX::resetGXCache();
if ((mFlags & 0x40) != 0) {
ox = 0.0f;
oy = StateGX::s_heightEfb;
sx = StateGX::s_widthEfb;
sy = 528 - StateGX::s_heightEfb;
}
field_0x10 |= mask1;
StateGX::ScopedColor colorGuard(true);
StateGX::ScopedAlpha alphaGuard(false);
LightTexture::initDrawSetting(ox + ((u16)ox & 1), oy + ((u16)oy & 1), sx, sy);
u16 x1, y1, x2, y2;
TextureBuffer *buf = nullptr;
LightTexture::getTexDimensions(&x1, &y1, &x2, &y2, mTextureCount);
x2 += x2 & 3;
y2 += y2 & 3;
if ((mFlags & 0x40) == 0 && (mFlags & 4) != 0) {
buf = TextureBuffer::alloc(x2, y2, GX_TF_RGBA8);
buf->capture(x1, y1, false, -1);
}
if (b1) {
StateGX::GXSetPixelFmt_(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
}
nw4r::ut::Color c(StateGX::s_clearEfb);
if (b1 && StateGX::s_pixFormat == GX_PF_RGBA6_Z24) {
// convert GX_PF_RGBA6_Z24 -> GX_PF_RGB8_Z24
u8 tmp = c.a >> 2;
c = ((c.r >> 2) << 26) | (c.g & 0x3FFC) << 18 | (c.b & 0xFC) << 12 | (tmp & 0x3F) << 8;
}
bool b2 = b1 && (mFlags & 8) != 0;
for (int i = 0; i < mTextureCount; i++) {
mpTextures[i]->fn_804AC0E0(i, c, b2);
}
for (int i = 0; i < mTextureCount; i++) {
mpTextures[i]->draw(i);
}
if (b1) {
StateGX::GXSetPixelFmt_(StateGX::s_pixFormat, StateGX::s_zFmt16);
}
if ((mFlags & 0x40) == 0 && buf != nullptr) {
StateGX::ScopedColor colorGuard(true);
StateGX::ScopedAlpha alphaGuard(true);
nw4r::math::MTX44 orthMtx;
C_MTXOrtho(orthMtx, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
StateGX::GXSetProjection_(orthMtx, GX_ORTHOGRAPHIC);
StateGX::GXSetViewport_(x1, y1, x2, y2, 0.0f, 1.0f);
StateGX::GXSetScissor_(x1, y1, x2, y2);
StateGX::GXSetScissorBoxOffset_(0, 0);
nw4r::math::MTX34 identity;
PSMTXIdentity(identity);
DrawGX::BeginDrawScreen(1, 1, 0);
DrawGX::SetBlendMode(DrawGX::BLEND_14);
GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
buf->load(GX_TEXMAP0);
DrawGX::DrawDL(DrawGX::DL_16, identity, DrawGX::WHITE);
buf->free();
}
StateGX::invalidateTexAllGX();
if ((mFlags & 0x80) != 0) {
LightTexture::beginDebugDraw();
for (int i = 0; i < mTextureCount; i++) {
mpTextures[i]->debugDraw(i);
}
}
}
void LightTextureManager::SetBinaryInner(const Bin &bin) {
if (bin.mHeader.mVersion != 0) {
return;
@@ -172,6 +307,20 @@ const void *LightTextureManager::getLtexFromLmap(const void *lmap, u16 index) {
return buf;
}
void LightTextureManager::fn_804AE340(nw4r::g3d::ResMat mat, GXTexCoordID id) {
nw4r::g3d::ResTexSrt dat = mat.GetResTexSrt();
dat.SetMapMode(id, 1, -1, -1);
nw4r::g3d::ResMatTexCoordGen coordGen = mat.GetResMatTexCoordGen();
GXTexGenType type;
GXTexGenSrc src;
GXBool normalize;
u32 postMtx;
coordGen.GXGetTexCoordGen2(id, &type, &src, &normalize, &postMtx);
coordGen.GXSetTexCoordGen2(id, GX_TG_MTX3x4, GX_TG_NRM, true, postMtx);
coordGen.DCStore(false);
}
size_t LightTextureManager::GetBinarySize() const {
// Contrary to the other dynamically-sized Bins, this only
// returns the fixed size. GetBinaryInner will add the dynamic