3DS: Fix UI being affected by fog

This commit is contained in:
UnknownShadow200 2025-10-01 19:45:18 +10:00
parent dc76a18275
commit 29d34e7e86
3 changed files with 61 additions and 128 deletions

View File

@ -9,6 +9,7 @@
#include "gsp_gpu.h"
#include "pica_gpu.h"
// See the .v.pica shader files in misc/3ds
#define CONST_MVP 0 // c0-c3
#define CONST_TEX 4 // c4
@ -23,23 +24,23 @@ extern const u32 textured_shbin_size;
extern const u8 offset_shbin[];
extern const u32 offset_shbin_size;
static void GPUBuffers_DeleteUnreferenced(void);
static void GPUTextures_DeleteUnreferenced(void);
static cc_uint32 frameCounter1;
static PackedCol clear_color;
static cc_bool rendering3D;
#define DISPLAY_TRANSFER_FLAGS \
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
static void GPUBuffers_DeleteUnreferenced(void);
static void GPUTextures_DeleteUnreferenced(void);
static cc_uint32 frameCounter1;
static PackedCol clear_color;
static cc_bool rendering3D;
/*########################################################################################################################*
*------------------------------------------------------Vertex shaders-----------------------------------------------------*
*#########################################################################################################################*/
#define UNI_MVP_MATRIX (1 << 0)
static C3D_Mtx _mvp;
static int texOffset, dirty_mvp;
@ -56,22 +57,6 @@ static void Shader_Alloc(struct CCShader* shader, const u8* binData, int binSize
shaderProgramSetVsh(&shader->program, &shader->dvlb->DVLE[0]);
}
static void Shader_Free(struct CCShader* shader) {
shaderProgramFree(&shader->program);
DVLB_Free(shader->dvlb);
}
static void UpdateMVP(void) {
struct CCShader* s = gfx_activeShader;
dirty_mvp = true;
if (!s) return; // NULL if context is lost
if (dirty_mvp) {
pica_upload_mat4_constant(CONST_MVP, &_mvp);
dirty_mvp = false;
}
}
// Switches program to one that can render current vertex format and state
// Loads program and reloads uniforms if needed
static void SwitchProgram(void) {
@ -86,7 +71,6 @@ static void SwitchProgram(void) {
gfx_activeShader = shader;
C3D_BindProgram(&shader->program);
}
UpdateMVP();
}
@ -105,13 +89,6 @@ static void AllocShaders(void) {
Shader_Alloc(&shaders[2], offset_shbin, offset_shbin_size);
}
static void FreeShaders(void) {
for (int i = 0; i < Array_Elems(shaders); i++)
{
Shader_Free(&shaders[i]);
}
}
static void SetDefaultState(void) {
Gfx_SetFaceCulling(false);
Gfx_SetAlphaTest(false);
@ -196,7 +173,6 @@ void Gfx_Free(void) {
C3Di_RenderQueueExit();
gfxSet3D(false);
// FreeShaders()
// C3D_Fini()
// aptUnhook(&hookCookie);
}
@ -735,14 +711,13 @@ void Gfx_DeleteDynamicVb(GfxResourceID* vb) { Gfx_DeleteVb(vb); }
*-----------------------------------------------------State management----------------------------------------------------*
*#########################################################################################################################*/
static u32 fogColor;
static C3D_FogLut fog_lut;
static int fogMode = FOG_LINEAR;
static float fogDensity = 1.0f;
static float fogEnd = 32.0f;
void Gfx_SetFog(cc_bool enabled) {
C3D_FogGasMode(enabled ? GPU_FOG : GPU_NO_FOG, GPU_PLAIN_DENSITY, false);
// TODO doesn't work quite right
pica_update_fog_mode(enabled, false);
gfx_fogEnabled = enabled;
}
void Gfx_SetFogCol(PackedCol color) {
@ -751,21 +726,7 @@ void Gfx_SetFogCol(PackedCol color) {
if (c == fogColor) return;
fogColor = c;
C3D_FogColor(c);
}
static void ApplyFog(float* values) {
float data[256];
for (int i = 0; i <= 128; i ++)
{
float val = values[i];
if (i < 128) data[i] = val;
if (i > 0) data[i + 127] = val - data[i-1];
}
FogLut_FromArray(&fog_lut, data);
C3D_FogLutBind(&fog_lut);
pica_set_fog_color(c);
}
static float GetFogValue(float c) {
@ -786,10 +747,13 @@ static void UpdateFog(void) {
// TODO: Exp calculation isn't right for lava ???
for (int i = 0; i <= 128; i ++)
{
float c = FogLut_CalcZ(i / 128.0f, near, far);
float c = FogLut_CalcZ(i / 128.0f, near, far);
values[i] = GetFogValue(c);
}
ApplyFog(values);
C3D_FogLut fog_lut;
FogLut_FromArray(&fog_lut, values);
pica_set_fog_table(fog_lut.data);
}
void Gfx_SetFogDensity(float value) {
@ -862,7 +826,7 @@ void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) {
}
Mtx_Multiply(&_mvp, &_proj, &_view);
UpdateMVP();
pica_upload_mat4_constant(CONST_MVP, &_mvp);
}

View File

@ -1,7 +1,37 @@
/*########################################################################################################################*
*--------------------------------------------------Vertex attribute config------------------------------------------------*
*#########################################################################################################################*/
// Vertex data pipeline:
// - 12 vertex arrays, which each consist of 12 components
// which are mapped to
// - 12 vertex attributes
// which are mapped to
// - 12 shader inputs
//
// Note that ClassiCube only uses 1 vertex array at present
/*########################################################################################################################*
*---------------------------------------------------------Fog config------------------------------------------------------*
*#########################################################################################################################*/
static CC_INLINE void pica_set_fog_color(u32 color) {
GPUCMD_AddWrite(GPUREG_FOG_COLOR, color);
}
static CC_INLINE void pica_set_fog_table(const u32 table[128]) {
GPUCMD_AddWrite(GPUREG_FOG_LUT_INDEX, 0);
GPUCMD_AddWrites(GPUREG_FOG_LUT_DATA0, table, 128);
}
static CC_INLINE void pica_update_fog_mode(bool fogEnabled, bool flipZ) {
GPU_FOGMODE fog = fogEnabled ? GPU_FOG : GPU_NO_FOG;
GPU_GASMODE gas = GPU_PLAIN_DENSITY;
u32 buf = fog | (gas << 3) | (flipZ ? (1 << 16) : 0);
GPUCMD_AddMaskedWrite(GPUREG_TEXENV_UPDATE_BUFFER, 0x5, buf);
}
/*########################################################################################################################*
*----------------------------------------------------Vertex arrays config-------------------------------------------------*
*#########################################################################################################################*/
// https://3dbrew.org/wiki/GPU/Internal_Registers#GPUREG_ATTRIBBUFFERi_CONFIG1
// Sets how to map first 8 vertex array components to vertex attributes (or padding)
static CC_INLINE void pica_set_attrib_array0_mapping(u32 mapping) {

83
third_party/citro3d.c vendored
View File

@ -151,13 +151,9 @@ static inline float FogLut_CalcZ(float depth, float near, float far)
return far*near/(depth*(far-near)+near);
}
static void FogLut_FromArray(C3D_FogLut* lut, const float data[256]);
static void FogLut_FromArray(C3D_FogLut* lut, const float data[129]);
static void C3D_FogGasMode(GPU_FOGMODE fogMode, GPU_GASMODE gasMode, bool zFlip);
static void C3D_FogColor(u32 color);
static void C3D_FogLutBind(C3D_FogLut* lut);
@ -297,8 +293,6 @@ typedef struct
C3D_Tex* tex[3];
u32 texEnvBuf, texEnvBufClr;
u32 fogClr;
C3D_FogLut* fogLut;
C3D_FrameBuf fb;
u32 viewport[5];
@ -319,7 +313,6 @@ enum
C3DiF_VshCode = BIT(11),
C3DiF_GshCode = BIT(12),
C3DiF_TexStatus = BIT(14),
C3DiF_FogLut = BIT(17),
C3DiF_Gas = BIT(18),
C3DiF_Reset = BIT(19),
@ -559,18 +552,20 @@ static void C3Di_EffectBind(C3D_Effect* e)
static void FogLut_FromArray(C3D_FogLut* lut, const float data[256])
static void FogLut_FromArray(C3D_FogLut* lut, const float data[129])
{
int i;
for (i = 0; i < 128; i ++)
{
float in = data[i], diff = data[i+128];
float cur = data[i + 0];
float next = data[i + 1];
float diff = next - cur;
u32 val = 0;
if (in > 0.0f)
if (cur > 0.0f)
{
in *= 0x800;
val = (in < 0x800) ? (u32)in : 0x7FF;
cur *= 0x800;
val = (cur < 0x800) ? (u32)cur : 0x7FF;
}
u32 val2 = 0;
@ -598,32 +593,6 @@ static void C3D_FogGasMode(GPU_FOGMODE fogMode, GPU_GASMODE gasMode, bool zFlip)
ctx->texEnvBuf |= (fogMode&7) | ((gasMode&1)<<3) | (zFlip ? BIT(16) : 0);
}
static void C3D_FogColor(u32 color)
{
C3D_Context* ctx = C3Di_GetContext();
if (!(ctx->flags & C3DiF_Active))
return;
ctx->flags |= C3DiF_TexEnvBuf;
ctx->fogClr = color;
}
static void C3D_FogLutBind(C3D_FogLut* lut)
{
C3D_Context* ctx = C3Di_GetContext();
if (!(ctx->flags & C3DiF_Active))
return;
if (lut)
{
ctx->flags |= C3DiF_FogLut;
ctx->fogLut = lut;
} else
ctx->flags &= ~C3DiF_FogLut;
}
@ -1002,9 +971,6 @@ static void C3Di_OnRestore(void)
ctx->flags |= C3DiF_AttrInfo | C3DiF_Effect | C3DiF_FrameBuf
| C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_Gas | C3DiF_Reset;
if (ctx->fogLut)
ctx->flags |= C3DiF_FogLut;
}
#define GXQUEUE_MAX_ENTRIES 32
@ -1041,8 +1007,6 @@ static bool C3D_Init(size_t cmdBufSize)
ctx->texConfig = BIT(12);
ctx->texEnvBuf = 0;
ctx->texEnvBufClr = 0xFFFFFFFF;
ctx->fogClr = 0;
ctx->fogLut = NULL;
for (i = 0; i < 3; i ++)
ctx->tex[i] = NULL;
@ -1191,17 +1155,6 @@ static void C3Di_UpdateContext(void)
ctx->flags &= ~C3DiF_TexEnvBuf;
GPUCMD_AddMaskedWrite(GPUREG_TEXENV_UPDATE_BUFFER, 0x7, ctx->texEnvBuf);
GPUCMD_AddWrite(GPUREG_TEXENV_BUFFER_COLOR, ctx->texEnvBufClr);
GPUCMD_AddWrite(GPUREG_FOG_COLOR, ctx->fogClr);
}
if ((ctx->flags & C3DiF_FogLut) && (ctx->texEnvBuf&7) != GPU_NO_FOG)
{
ctx->flags &= ~C3DiF_FogLut;
if (ctx->fogLut)
{
GPUCMD_AddWrite(GPUREG_FOG_LUT_INDEX, 0);
GPUCMD_AddWrites(GPUREG_FOG_LUT_DATA0, ctx->fogLut->data, 128);
}
}
}
@ -1240,21 +1193,7 @@ static void C3D_BindProgram(shaderProgram_s* program)
{
C3D_Context* ctx = C3Di_GetContext();
shaderProgram_s* oldProg = ctx->program;
if (oldProg != program)
{
ctx->program = program;
ctx->flags |= C3DiF_Program | C3DiF_AttrInfo;
if (!oldProg)
ctx->flags |= C3DiF_VshCode | C3DiF_GshCode;
else
{
DVLP_s* oldProgV = oldProg->vertexShader->dvle->dvlp;
DVLP_s* newProgV = program->vertexShader->dvle->dvlp;
if (oldProgV != newProgV)
ctx->flags |= C3DiF_VshCode | C3DiF_GshCode;
}
}
ctx->program = program;
ctx->flags |= C3DiF_Program | C3DiF_AttrInfo;
ctx->flags |= C3DiF_VshCode | C3DiF_GshCode;
}