mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-04 02:16:03 -04:00
bloom cleanup start
start working on a better bloom
This commit is contained in:
+196
-17
@@ -1232,12 +1232,12 @@ void mDoGph_drawFilterQuad(s8 param_0, s8 param_1) {
|
||||
void mDoGph_gInf_c::bloom_c::create() {
|
||||
if (m_buffer == NULL) {
|
||||
#ifdef TARGET_PC
|
||||
u32 size = 0x20; // No need to allocate memory for texture
|
||||
m_buffer = (void*)1;
|
||||
#else
|
||||
u32 size = GXGetTexBufferSize(FB_WIDTH / 2, FB_HEIGHT / 2, GX_TF_RGBA8, GX_FALSE, 0);
|
||||
#endif
|
||||
m_buffer = mDoExt_getArchiveHeap()->alloc(size, -32);
|
||||
JUT_ASSERT(1621, m_buffer != NULL);
|
||||
#endif
|
||||
|
||||
mEnable = false;
|
||||
mMode = 0;
|
||||
@@ -1249,20 +1249,202 @@ void mDoGph_gInf_c::bloom_c::create() {
|
||||
}
|
||||
|
||||
void mDoGph_gInf_c::bloom_c::remove() {
|
||||
#if !TARGET_PC
|
||||
if (m_buffer != NULL) {
|
||||
mDoExt_getArchiveHeap()->free(m_buffer);
|
||||
m_buffer = NULL;
|
||||
}
|
||||
#endif
|
||||
mMonoColor.a = 0;
|
||||
}
|
||||
|
||||
void mDoGph_gInf_c::bloom_c::draw() {
|
||||
|
||||
#if TARGET_PC
|
||||
static void CopyToTexObj(GXTexObj* pDst, uintptr_t texID, int dstWidth, int dstHeight, GXTexFmt dstFmt = GX_TF_RGBA8) {
|
||||
GXSetTexCopyDst(dstWidth, dstHeight, dstFmt, FALSE);
|
||||
GXCopyTex((void*)texID, false);
|
||||
GXInitTexObj(pDst, (void*)texID, dstWidth, dstHeight, dstFmt, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObjLOD(pDst, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
|
||||
}
|
||||
|
||||
void mDoGph_gInf_c::bloom_c::draw() {
|
||||
ZoneScoped;
|
||||
if (!dusk::getSettings().game.enableBloom) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool enabled = mEnable;
|
||||
if (mMonoColor.a == 0 && !enabled)
|
||||
return;
|
||||
|
||||
f32 width = mDoGph_gInf_c::getWidth();
|
||||
f32 height = mDoGph_gInf_c::getHeight();
|
||||
GXSetViewport(0.0f, 0.0f, width, height, 0.0f, 1.0f);
|
||||
GXSetScissor(0, 0, width, height);
|
||||
|
||||
GXLoadTexObj(getFrameBufferTexObj(), GX_TEXMAP0);
|
||||
GXSetNumChans(0);
|
||||
GXSetNumTexGens(1);
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c);
|
||||
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_GREEN);
|
||||
GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
|
||||
GXSetZCompLoc(1);
|
||||
GXSetZMode(0, GX_ALWAYS, 0);
|
||||
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0);
|
||||
GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor);
|
||||
GXSetFogRangeAdj(0, 0, 0);
|
||||
GXSetCullMode(GX_CULL_NONE);
|
||||
GXSetDither(1);
|
||||
Mtx44 ortho;
|
||||
C_MTXOrtho(ortho, 0.0f, height, 0.0f, width, 0.0f, 10.0f);
|
||||
GXLoadPosMtxImm(cMtx_getIdentity(), 0);
|
||||
GXSetProjection(ortho, GX_ORTHOGRAPHIC);
|
||||
GXSetCurrentMtx(0);
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S8, 0);
|
||||
|
||||
auto filterQuad = [&](int div) {
|
||||
f32 x = width / div, y = height / div;
|
||||
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
|
||||
GXPosition3f32(0, 0, -5);
|
||||
GXTexCoord2s8(0, 0);
|
||||
GXPosition3f32(x, 0, -5);
|
||||
GXTexCoord2s8(1, 0);
|
||||
GXPosition3f32(x, y, -5);
|
||||
GXTexCoord2s8(1, 1);
|
||||
GXPosition3f32(0, y, -5);
|
||||
GXTexCoord2s8(0, 1);
|
||||
GXEnd();
|
||||
};
|
||||
|
||||
if (mMonoColor.a != 0) {
|
||||
GXSetNumTevStages(1);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C2, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A2);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP1, GX_TEV_SWAP1);
|
||||
GXSetTevColor(GX_TEVREG2, mMonoColor);
|
||||
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR);
|
||||
filterQuad(1);
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
enum PassID { Pass0, Pass1, Pass2 };
|
||||
|
||||
GXCreateFrameBuffer(width, height);
|
||||
|
||||
GXSetNumTevStages(3);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_TEXC, GX_CC_TEXA, GX_CC_HALF, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP1, GX_TEV_SWAP1);
|
||||
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_TEXC, GX_CC_CPREV, GX_CC_HALF, GX_CC_C0);
|
||||
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP3, GX_TEV_SWAP3);
|
||||
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_OR);
|
||||
GXColorS10 tevColor0 = {(s16)-mPoint, (s16)-mPoint, (s16)-mPoint, 0x40};
|
||||
GXSetTevColorS10(GX_TEVREG0, tevColor0);
|
||||
GXColor tevColor1 = {mBlureRatio, mBlureRatio, mBlureRatio, mBlureRatio};
|
||||
GXSetTevColor(GX_TEVREG1, tevColor1);
|
||||
GXPixModeSync();
|
||||
filterQuad(2);
|
||||
|
||||
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
||||
|
||||
// Downsample and filter from 1/2 EFB into 1/4.
|
||||
TGXTexObj tmpTex[3];
|
||||
GXSetTexCopySrc(0, 0, width / 2, height / 2);
|
||||
CopyToTexObj(&tmpTex[0], Pass0, width / 4, height / 4);
|
||||
GXLoadTexObj(&tmpTex[0], GX_TEXMAP0);
|
||||
|
||||
GXSetNumTexGens(8);
|
||||
u32 texMtxID = GX_TEXMTX0;
|
||||
int angle = 0;
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
for (int texCoord = (int)GX_TEXCOORD1; texCoord < (int)GX_MAX_TEXCOORD; texCoord++) {
|
||||
GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, texMtxID);
|
||||
|
||||
f32 dVar15 = mBlureSize * ((448.0f / getHeight()) / 6400.0f);
|
||||
|
||||
mDoMtx_stack_c::transS((dVar15 * cM_scos(angle)) * getInvScale(),
|
||||
dVar15 * cM_ssin(angle), 0.0f);
|
||||
GXLoadTexMtxImm(mDoMtx_stack_c::get(), texMtxID, GX_MTX2x4);
|
||||
|
||||
texMtxID += 3;
|
||||
angle += 0x2492;
|
||||
}
|
||||
|
||||
GXSetNumTevStages(8);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_A1, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
for (int tevStage = (int)GX_TEVSTAGE1; tevStage < 8; tevStage++) {
|
||||
GXSetTevOrder((GXTevStageID)tevStage, (GXTexCoordID)tevStage, GX_TEXMAP0,
|
||||
GX_COLOR_NULL);
|
||||
GXSetTevColorIn((GXTevStageID)tevStage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_A1, GX_CC_CPREV);
|
||||
GXSetTevColorOp((GXTevStageID)tevStage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
|
||||
GX_TEVPREV);
|
||||
GXSetTevAlphaIn((GXTevStageID)tevStage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0);
|
||||
GXSetTevAlphaOp((GXTevStageID)tevStage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
|
||||
GX_TEVPREV);
|
||||
}
|
||||
GXPixModeSync();
|
||||
|
||||
// Blur filter from tmp_tex1 1/4 to EFB 1/4.
|
||||
filterQuad(4);
|
||||
|
||||
GXSetTexCopySrc(0, 0, width / 4, height / 4);
|
||||
CopyToTexObj(&tmpTex[1], Pass1, width / 8, height / 8);
|
||||
GXLoadTexObj(&tmpTex[1], GX_TEXMAP0);
|
||||
|
||||
// Upsample 1/8 buffer back up to 1/4 buffer.
|
||||
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR);
|
||||
GXPixModeSync();
|
||||
GXInvalidateTexAll();
|
||||
filterQuad(4);
|
||||
|
||||
// Now that we've upsampled and filtered our final bloom, copy 1/4 buffer.
|
||||
GXSetTexCopySrc(0, 0, width / 4, height / 4);
|
||||
CopyToTexObj(&tmpTex[2], Pass2, width / 4, height / 4);
|
||||
GXLoadTexObj(&tmpTex[2], GX_TEXMAP0);
|
||||
|
||||
GXRestoreFrameBuffer();
|
||||
|
||||
// Now blend our bloom into the real FB.
|
||||
GXSetTevColor(GX_TEVREG0, mBlendColor);
|
||||
GXSetNumTevStages(1);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetBlendMode(GX_BM_BLEND, mMode == 1 ? GX_BL_INVDSTCLR : GX_BL_ONE, GX_BL_SRCALPHA, GX_LO_OR);
|
||||
GXPixModeSync();
|
||||
GXInvalidateTexAll();
|
||||
filterQuad(1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void mDoGph_gInf_c::bloom_c::draw() {
|
||||
bool enabled = mEnable && m_buffer != NULL;
|
||||
if (mMonoColor.a != 0 || enabled) {
|
||||
#if TARGET_PC
|
||||
@@ -1376,24 +1558,20 @@ void mDoGph_gInf_c::bloom_c::draw() {
|
||||
GXLoadTexObj(&tmp_tex1, GX_TEXMAP0);
|
||||
|
||||
GXSetNumTexGens(8);
|
||||
u32 iVar11 = 0x1e;
|
||||
int sVar10 = 0;
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c);
|
||||
u32 texMtxID = GX_TEXMTX0;
|
||||
int angle = 0;
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
for (int texCoord = (int)GX_TEXCOORD1; texCoord < (int)GX_MAX_TEXCOORD; texCoord++) {
|
||||
GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, iVar11);
|
||||
GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, texMtxID);
|
||||
|
||||
#if TARGET_PC
|
||||
f32 dVar15 = mBlureSize * ((448.0f / getHeight()) / 6400.0f);
|
||||
#else
|
||||
f32 dVar15 = mBlureSize * (1.0f / 6400.0f);
|
||||
#endif
|
||||
|
||||
mDoMtx_stack_c::transS((dVar15 * cM_scos(sVar10)) * getInvScale(),
|
||||
dVar15 * cM_ssin(sVar10), 0.0f);
|
||||
GXLoadTexMtxImm(mDoMtx_stack_c::get(), iVar11, GX_MTX2x4);
|
||||
mDoMtx_stack_c::transS((dVar15 * cM_scos(angle)) * getInvScale(),
|
||||
dVar15 * cM_ssin(angle), 0.0f);
|
||||
GXLoadTexMtxImm(mDoMtx_stack_c::get(), texMtxID, GX_MTX2x4);
|
||||
|
||||
iVar11 += 3;
|
||||
sVar10 += 0x2492;
|
||||
texMtxID += 3;
|
||||
angle += 0x2492;
|
||||
}
|
||||
GXSetNumTevStages(8);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
@@ -1495,6 +1673,7 @@ void mDoGph_gInf_c::bloom_c::draw() {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void retry_captue_frame(view_class* param_0, view_port_class* param_1, int param_2) {
|
||||
UNUSED(param_0);
|
||||
|
||||
Reference in New Issue
Block a user