3DS: Give real 3D support a try

This commit is contained in:
UnknownShadow200 2024-04-06 14:27:59 +11:00
parent 01c872f333
commit add2537ecf
4 changed files with 81 additions and 26 deletions

View File

@ -538,7 +538,7 @@ static void Render3D_Anaglyph(double delta, float t) {
Matrix_Translate(&view_left, -0.10f, 0, 0); Matrix_Translate(&view_left, -0.10f, 0, 0);
Matrix_Mul(&Gfx.View, &view, &view_left); Matrix_Mul(&Gfx.View, &view, &view_left);
Gfx_SetColorWrite(false, true, true, false); Gfx_Set3DLeft();
Render3DFrame(delta, t); Render3DFrame(delta, t);
Matrix_Translate(&proj_right, -0.07f, 0, 0); Matrix_Translate(&proj_right, -0.07f, 0, 0);
@ -546,12 +546,11 @@ static void Render3D_Anaglyph(double delta, float t) {
Matrix_Translate(&view_right, 0.10f, 0, 0); Matrix_Translate(&view_right, 0.10f, 0, 0);
Matrix_Mul(&Gfx.View, &view, &view_right); Matrix_Mul(&Gfx.View, &view, &view_right);
Gfx_ClearBuffers(GFX_BUFFER_DEPTH); Gfx_Set3DRight();
Gfx_SetColorWrite(true, false, false, false);
Render3DFrame(delta, t); Render3DFrame(delta, t);
Gfx.Projection = proj; Gfx.Projection = proj;
Gfx_SetColorWrite(true, true, true, true); Gfx_End3D();
} }
static void PerformScheduledTasks(double time) { static void PerformScheduledTasks(double time) {

View File

@ -155,6 +155,11 @@ CC_API void Gfx_SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a);
/* NOTE: Implicitly calls Gfx_SetColorWrite */ /* NOTE: Implicitly calls Gfx_SetColorWrite */
CC_API void Gfx_DepthOnlyRendering(cc_bool depthOnly); CC_API void Gfx_DepthOnlyRendering(cc_bool depthOnly);
/* Anaglyph 3D rendering support */
void Gfx_Set3DLeft(void);
void Gfx_Set3DRight(void);
void Gfx_End3D(void);
/* Callback function to initialise/fill out the contents of an index buffer */ /* Callback function to initialise/fill out the contents of an index buffer */
typedef void (*Gfx_FillIBFunc)(cc_uint16* indices, int count, void* obj); typedef void (*Gfx_FillIBFunc)(cc_uint16* indices, int count, void* obj);
/* Creates a new index buffer and fills out its contents */ /* Creates a new index buffer and fills out its contents */
@ -298,4 +303,4 @@ void Gfx_RestoreAlphaState(cc_uint8 draw);
void Texture_Render(const struct Texture* tex); void Texture_Render(const struct Texture* tex);
/* Binds then renders the given texture */ /* Binds then renders the given texture */
void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor); void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor);
#endif #endif

View File

@ -25,6 +25,8 @@ extern const u32 offset_shbin_size;
static void GPUBuffers_DeleteUnreferenced(void); static void GPUBuffers_DeleteUnreferenced(void);
static void GPUTextures_DeleteUnreferenced(void); static void GPUTextures_DeleteUnreferenced(void);
static cc_uint32 frameCounter; static cc_uint32 frameCounter;
static PackedCol clear_color;
static cc_bool rendering3D;
/*########################################################################################################################* /*########################################################################################################################*
@ -106,7 +108,8 @@ static void SwitchProgram(void) {
/*########################################################################################################################* /*########################################################################################################################*
*---------------------------------------------------------General---------------------------------------------------------* *---------------------------------------------------------General---------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static C3D_RenderTarget* topTarget; static C3D_RenderTarget* topTargetLeft;
static C3D_RenderTarget* topTargetRight;
static C3D_RenderTarget* bottomTarget; static C3D_RenderTarget* bottomTarget;
static void AllocShaders(void) { static void AllocShaders(void) {
@ -131,8 +134,8 @@ static void SetDefaultState(void) {
static void InitCitro3D(void) { static void InitCitro3D(void) {
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 4); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 4);
topTarget = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); topTargetLeft = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetOutput(topTarget, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); C3D_RenderTargetSetOutput(topTargetLeft, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
// Even though the bottom screen is 320 pixels wide, we use 400 here so that the same ortho matrix // Even though the bottom screen is 320 pixels wide, we use 400 here so that the same ortho matrix
// can be used for both screens. The output is clipped to the actual screen width, anyway. // can be used for both screens. The output is clipped to the actual screen width, anyway.
@ -186,9 +189,31 @@ void Gfx_FreeState(void) {
} }
void Gfx_3DS_SetRenderScreen(enum Screen3DS screen) { void Gfx_3DS_SetRenderScreen(enum Screen3DS screen) {
C3D_FrameDrawOn(screen == TOP_SCREEN ? topTarget : bottomTarget); C3D_FrameDrawOn(screen == TOP_SCREEN ? topTargetLeft : bottomTarget);
} }
/*########################################################################################################################*
*----------------------------------------------------Stereoscopic support-------------------------------------------------*
*#########################################################################################################################*/
void Gfx_Set3DLeft(void) {
rendering3D = true;
}
void Gfx_Set3DRight(void) {
if (!topTargetRight) {
topTargetRight = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetOutput(topTargetRight, GFX_TOP, GFX_RIGHT, DISPLAY_TRANSFER_FLAGS);
}
C3D_RenderTargetClear(topTargetRight, C3D_CLEAR_ALL, clear_color, 0);
C3D_FrameDrawOn(topTargetRight);
}
void Gfx_End3D(void) {
}
/*########################################################################################################################* /*########################################################################################################################*
*--------------------------------------------------------GPU Textures-----------------------------------------------------* *--------------------------------------------------------GPU Textures-----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
@ -368,7 +393,6 @@ void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
enabled & gfx_colorMask[2], enabled & gfx_colorMask[3]); enabled & gfx_colorMask[2], enabled & gfx_colorMask[3]);
} }
static PackedCol clear_color;
void Gfx_ClearColor(PackedCol color) { void Gfx_ClearColor(PackedCol color) {
// TODO find better way? // TODO find better way?
clear_color = (PackedCol_R(color) << 24) | (PackedCol_G(color) << 16) | (PackedCol_B(color) << 8) | 0xFF; clear_color = (PackedCol_R(color) << 24) | (PackedCol_G(color) << 16) | (PackedCol_B(color) << 8) | 0xFF;
@ -451,9 +475,10 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) {
} }
void Gfx_BeginFrame(void) { void Gfx_BeginFrame(void) {
int flags = gfx_vsync ? C3D_FRAME_SYNCDRAW : 0; rendering3D = false;
int flags = gfx_vsync ? C3D_FRAME_SYNCDRAW : 0;
C3D_FrameBegin(flags); C3D_FrameBegin(flags);
C3D_FrameDrawOn(topTarget); C3D_FrameDrawOn(topTargetLeft);
} }
void Gfx_ClearBuffers(GfxBuffers buffers) { void Gfx_ClearBuffers(GfxBuffers buffers) {
@ -461,11 +486,12 @@ void Gfx_ClearBuffers(GfxBuffers buffers) {
if (buffers & GFX_BUFFER_COLOR) targets |= C3D_CLEAR_COLOR; if (buffers & GFX_BUFFER_COLOR) targets |= C3D_CLEAR_COLOR;
if (buffers & GFX_BUFFER_DEPTH) targets |= C3D_CLEAR_DEPTH; if (buffers & GFX_BUFFER_DEPTH) targets |= C3D_CLEAR_DEPTH;
C3D_RenderTargetClear(topTarget, targets, clear_color, 0); C3D_RenderTargetClear(topTargetLeft, targets, clear_color, 0);
C3D_RenderTargetClear(bottomTarget, targets, 0, 0); C3D_RenderTargetClear(bottomTarget, targets, 0, 0);
} }
void Gfx_EndFrame(void) { void Gfx_EndFrame(void) {
gfxSet3D(rendering3D);
C3D_FrameEnd(0); C3D_FrameEnd(0);
//gfxFlushBuffers(); //gfxFlushBuffers();
//gfxSwapBuffers(); //gfxSwapBuffers();

View File

@ -48,6 +48,21 @@ void Gfx_SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
void Gfx_SetTexturing(cc_bool enabled) { } /* useless */ void Gfx_SetTexturing(cc_bool enabled) { } /* useless */
#ifndef CC_BUILD_3DS
void Gfx_Set3DLeft(void) {
Gfx_SetColorWrite(false, true, true, false);
}
void Gfx_Set3DRight(void) {
Gfx_ClearBuffers(GFX_BUFFER_DEPTH);
Gfx_SetColorWrite(true, false, false, false);
}
void Gfx_End3D(void) {
Gfx_SetColorWrite(true, true, true, true);
}
#endif
/*########################################################################################################################* /*########################################################################################################################*
*------------------------------------------------------Generic/Common-----------------------------------------------------* *------------------------------------------------------Generic/Common-----------------------------------------------------*
@ -87,6 +102,10 @@ static void FreeDefaultResources(void) {
Gfx_DeleteIb(&Gfx_defaultIb); Gfx_DeleteIb(&Gfx_defaultIb);
} }
/*########################################################################################################################*
*------------------------------------------------------FPS and context----------------------------------------------------*
*#########################################################################################################################*/
#ifdef CC_BUILD_WEB #ifdef CC_BUILD_WEB
static void LimitFPS(void) { static void LimitFPS(void) {
/* Can't use Thread_Sleep on the web. (spinwaits instead of sleeping) */ /* Can't use Thread_Sleep on the web. (spinwaits instead of sleeping) */
@ -152,17 +171,9 @@ static CC_INLINE void EndReducedPerformance(void) {
} }
void Gfx_RecreateTexture(GfxResourceID* tex, struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) { /*########################################################################################################################*
Gfx_DeleteTexture(tex); *--------------------------------------------------------2D drawing-------------------------------------------------------*
*tex = Gfx_CreateTexture(bmp, flags, mipmaps); *#########################################################################################################################*/
}
void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count) {
Gfx_DeleteVb(vb);
*vb = Gfx_CreateVb(fmt, count);
return Gfx_LockVb(*vb, fmt, count);
}
#ifndef CC_BUILD_3DS #ifndef CC_BUILD_3DS
void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol color) { void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol color) {
struct VertexColoured* v; struct VertexColoured* v;
@ -246,6 +257,10 @@ void Gfx_End2D(void) {
if (gfx_hadFog) Gfx_SetFog(true); if (gfx_hadFog) Gfx_SetFog(true);
} }
/*########################################################################################################################*
*--------------------------------------------------------Misc/Utils-------------------------------------------------------*
*#########################################################################################################################*/
void Gfx_SetupAlphaState(cc_uint8 draw) { void Gfx_SetupAlphaState(cc_uint8 draw) {
if (draw == DRAW_TRANSLUCENT) Gfx_SetAlphaBlending(true); if (draw == DRAW_TRANSLUCENT) Gfx_SetAlphaBlending(true);
if (draw == DRAW_TRANSPARENT) Gfx_SetAlphaTest(true); if (draw == DRAW_TRANSPARENT) Gfx_SetAlphaTest(true);
@ -260,7 +275,6 @@ void Gfx_RestoreAlphaState(cc_uint8 draw) {
if (draw == DRAW_SPRITE) Gfx_SetAlphaTest(false); if (draw == DRAW_SPRITE) Gfx_SetAlphaTest(false);
} }
static CC_INLINE float Reversed_CalcZNear(float fov, int depthbufferBits) { static CC_INLINE float Reversed_CalcZNear(float fov, int depthbufferBits) {
/* With reversed z depth, near Z plane can be much closer (with sufficient depth buffer precision) */ /* With reversed z depth, near Z plane can be much closer (with sufficient depth buffer precision) */
/* This reduces clipping with high FOV without sacrificing depth precision for faraway objects */ /* This reduces clipping with high FOV without sacrificing depth precision for faraway objects */
@ -286,6 +300,11 @@ static void PrintMaxTextureInfo(cc_string* info) {
/*########################################################################################################################* /*########################################################################################################################*
*---------------------------------------------------------Textures--------------------------------------------------------* *---------------------------------------------------------Textures--------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
void Gfx_RecreateTexture(GfxResourceID* tex, struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
Gfx_DeleteTexture(tex);
*tex = Gfx_CreateTexture(bmp, flags, mipmaps);
}
static void CopyTextureData(void* dst, int dstStride, const struct Bitmap* src, int srcStride) { static void CopyTextureData(void* dst, int dstStride, const struct Bitmap* src, int srcStride) {
/* We need to copy scanline by scanline, as generally srcStride != dstStride */ /* We need to copy scanline by scanline, as generally srcStride != dstStride */
cc_uint8* src_ = (cc_uint8*)src->scan0; cc_uint8* src_ = (cc_uint8*)src->scan0;
@ -415,6 +434,12 @@ void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor) {
/*########################################################################################################################* /*########################################################################################################################*
*------------------------------------------------------Vertex buffers-----------------------------------------------------* *------------------------------------------------------Vertex buffers-----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count) {
Gfx_DeleteVb(vb);
*vb = Gfx_CreateVb(fmt, count);
return Gfx_LockVb(*vb, fmt, count);
}
static GfxResourceID Gfx_AllocStaticVb( VertexFormat fmt, int count); static GfxResourceID Gfx_AllocStaticVb( VertexFormat fmt, int count);
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices); static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices);