diff --git a/src/dusk/display/display.c b/src/dusk/display/display.c index bd1cf547..3c29fdac 100644 --- a/src/dusk/display/display.c +++ b/src/dusk/display/display.c @@ -33,6 +33,7 @@ errorret_t displayInit(void) { #ifdef displayPlatformInit errorChain(displayPlatformInit()); #endif + errorChain(displaySetState((displaystate_t){ .flags = 0 })); errorChain(textureInit( &TEXTURE_WHITE, 4, 4, TEXTURE_FORMAT_RGBA, (texturedata_t){ .rgbaColors = TEXTURE_WHITE_PIXELS } @@ -110,6 +111,13 @@ errorret_t displayUpdate(void) { errorOk(); } +errorret_t displaySetState(displaystate_t state) { + #ifdef displayPlatformSetState + errorChain(displayPlatformSetState(state)); + #endif + errorOk(); +} + errorret_t displayDispose(void) { errorChain(shaderDispose(&SHADER_UNLIT)); errorChain(spriteBatchDispose()); diff --git a/src/dusk/display/display.h b/src/dusk/display/display.h index 23a319b5..cc134e4e 100644 --- a/src/dusk/display/display.h +++ b/src/dusk/display/display.h @@ -40,15 +40,26 @@ extern display_t DISPLAY; /** * Initializes the display system. + * @return An errorret_t indicating success or failure. */ errorret_t displayInit(void); /** * Tells the display system to actually draw the frame. + * @return An errorret_t indicating success or failure. */ errorret_t displayUpdate(void); +/** + * Sets the display state. + * + * @param state The state to set. + * @return An errorret_t indicating success or failure. + */ +errorret_t displaySetState(displaystate_t state); + /** * Disposes of the display system. + * @return An errorret_t indicating success or failure. */ errorret_t displayDispose(void); \ No newline at end of file diff --git a/src/dusk/display/displaystate.h b/src/dusk/display/displaystate.h new file mode 100644 index 00000000..ee27028a --- /dev/null +++ b/src/dusk/display/displaystate.h @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +#define DISPLAY_STATE_FLAG_CULL (1 << 0) +#define DISPLAY_STATE_FLAG_DEPTH_TEST (1 << 1) +#define DISPLAY_STATE_FLAG_BLEND (1 << 2) + +typedef struct { + uint8_t flags; +} displaystate_t; \ No newline at end of file diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index c410475b..ffa39938 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -55,6 +55,10 @@ errorret_t sceneRender(void) { shader_t *shaderCurrent = NULL; mat4 view, proj, model; + + errorChain(displaySetState((displaystate_t){ + .flags = DISPLAY_STATE_FLAG_CULL | DISPLAY_STATE_FLAG_DEPTH_TEST + })); // For each camera for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) { @@ -148,6 +152,9 @@ errorret_t sceneRender(void) { errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)); errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); + errorChain(displaySetState((displaystate_t){ + .flags = DISPLAY_STATE_FLAG_BLEND + })); errorChain(uiRender()); diff --git a/src/duskdolphin/display/displaydolphin.c b/src/duskdolphin/display/displaydolphin.c index f4b4cdf6..e6aabd1a 100644 --- a/src/duskdolphin/display/displaydolphin.c +++ b/src/duskdolphin/display/displaydolphin.c @@ -75,10 +75,6 @@ errorret_t displayInitDolphin(void) { ) ); - // Setup cull modes - GX_SetCullMode(GX_CULL_NONE); - GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); - GX_SetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE); GX_SetDispCopyGamma(GX_GM_1_0); GX_SetColorUpdate(GX_TRUE); @@ -103,12 +99,36 @@ errorret_t displayUpdateDolphin(void) { errorOk(); } +errorret_t displaySetStateDolphin(displaystate_t state) { + if(state.flags & DISPLAY_STATE_FLAG_CULL) { + GX_SetCullMode(GX_CULL_BACK); + } else { + GX_SetCullMode(GX_CULL_NONE); + } + + if(state.flags & DISPLAY_STATE_FLAG_DEPTH_TEST) { + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + } else { + GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); + } + + if(state.flags & DISPLAY_STATE_FLAG_BLEND) { + GX_SetBlendMode( + GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR + ); + } else { + GX_SetBlendMode( + GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR + ); + } + + errorOk(); +} + errorret_t displaySwapDolphin(void) { GX_DrawDone(); DISPLAY.whichFrameBuffer ^= 1; - // GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); - // GX_SetColorUpdate(GX_TRUE); GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE); VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]); VIDEO_Flush(); diff --git a/src/duskdolphin/display/displaydolphin.h b/src/duskdolphin/display/displaydolphin.h index ab7ab6d3..d3932526 100644 --- a/src/duskdolphin/display/displaydolphin.h +++ b/src/duskdolphin/display/displaydolphin.h @@ -7,6 +7,7 @@ #pragma once #include "error/error.h" +#include "display/displaystate.h" #define DISPLAY_DOLPHIN_FIFO_SIZE (256*1024) @@ -30,4 +31,9 @@ errorret_t displayUpdateDolphin(void); /** * Swaps the display buffers on Dolphin. */ -errorret_t displaySwapDolphin(void); \ No newline at end of file +errorret_t displaySwapDolphin(void); + +/** + * Sets the display state on Dolphin. + */ +errorret_t displaySetStateDolphin(displaystate_t state); \ No newline at end of file diff --git a/src/duskdolphin/display/displayplatform.h b/src/duskdolphin/display/displayplatform.h index ab718d04..ed9b61a9 100644 --- a/src/duskdolphin/display/displayplatform.h +++ b/src/duskdolphin/display/displayplatform.h @@ -11,5 +11,6 @@ #define displayPlatformInit displayInitDolphin #define displayPlatformUpdate displayUpdateDolphin #define displayPlatformSwap displaySwapDolphin +#define displayPlatformSetState displaySetStateDolphin typedef displaydolphin_t displayplatform_t; \ No newline at end of file diff --git a/src/duskgl/display/displaygl.c b/src/duskgl/display/displaygl.c index d716a8cb..c25904ae 100644 --- a/src/duskgl/display/displaygl.c +++ b/src/duskgl/display/displaygl.c @@ -8,20 +8,6 @@ #include "displaygl.h" errorret_t displayOpenGLInit(void) { - glDisable(GL_CULL_FACE); - errorChain(errorGLCheck()); - - glEnable(GL_DEPTH_TEST); - errorChain(errorGLCheck()); - glDepthFunc(GL_LEQUAL); - errorChain(errorGLCheck()); - glClearDepth(1.0f); - errorChain(errorGLCheck()); - - glEnable(GL_BLEND); - errorChain(errorGLCheck()); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - errorChain(errorGLCheck()); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); errorChain(errorGLCheck()); diff --git a/src/dusklinux/display/displayplatform.h b/src/dusklinux/display/displayplatform.h index b1936672..fa23c6d8 100644 --- a/src/dusklinux/display/displayplatform.h +++ b/src/dusklinux/display/displayplatform.h @@ -13,4 +13,5 @@ typedef displaysdl2_t displayplatform_t; #define displayPlatformInit displaySDL2Init #define displayPlatformUpdate displaySDL2Update #define displayPlatformSwap displaySDL2Swap +#define displayPlatformSetState displaySDL2SetState #define displayPlatformDispose displaySDL2Dispose \ No newline at end of file diff --git a/src/dusksdl2/display/displaysdl2.c b/src/dusksdl2/display/displaysdl2.c index 5eccdf42..74125db9 100644 --- a/src/dusksdl2/display/displaysdl2.c +++ b/src/dusksdl2/display/displaysdl2.c @@ -102,6 +102,42 @@ errorret_t displaySDL2Swap(void) { errorOk(); } +errorret_t displaySDL2SetState(displaystate_t state) { + if(state.flags & DISPLAY_STATE_FLAG_CULL) { + glEnable(GL_CULL_FACE); + errorChain(errorGLCheck()); + glCullFace(GL_BACK); + errorChain(errorGLCheck()); + } else { + glDisable(GL_CULL_FACE); + errorChain(errorGLCheck()); + } + + if(state.flags & DISPLAY_STATE_FLAG_DEPTH_TEST) { + glEnable(GL_DEPTH_TEST); + errorChain(errorGLCheck()); + glDepthFunc(GL_LEQUAL); + errorChain(errorGLCheck()); + glClearDepth(1.0f); + errorChain(errorGLCheck()); + } else { + glDisable(GL_DEPTH_TEST); + errorChain(errorGLCheck()); + } + + if(state.flags & DISPLAY_STATE_FLAG_BLEND) { + glEnable(GL_BLEND); + errorChain(errorGLCheck()); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + errorChain(errorGLCheck()); + } else { + glDisable(GL_BLEND); + errorChain(errorGLCheck()); + } + + errorOk(); +} + void displaySDL2Dispose(void) { if(DISPLAY.glContext) { SDL_GL_DeleteContext(DISPLAY.glContext); diff --git a/src/dusksdl2/display/displaysdl2.h b/src/dusksdl2/display/displaysdl2.h index ebee170b..bb02d478 100644 --- a/src/dusksdl2/display/displaysdl2.h +++ b/src/dusksdl2/display/displaysdl2.h @@ -7,6 +7,7 @@ #pragma once #include "error/error.h" +#include "display/displaystate.h" typedef struct { SDL_Window *window; @@ -29,6 +30,11 @@ errorret_t displaySDL2Update(void); */ errorret_t displaySDL2Swap(void); +/** + * Sets the SDL2 display state. + */ +errorret_t displaySDL2SetState(displaystate_t state); + /** * Disposes/Cleans up the SDL2 Render system. */