diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 31de14d4d..c832e3604 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -843,7 +843,7 @@ static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt) { //if(!nds.isIn3dVblank()) // PROGINFO("Changing texture or texture palette mappings outside of 3d vblank\n"); - gpu3D->NDS_3D_VramReconfigureSignal(); + CurrentRenderer->VramReconfigureSignal(); } //------------------------------- diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 1b367a0cc..54f824c9b 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -2510,7 +2510,6 @@ void NDS_Reset() Screen_Reset(); gfx3d_reset(); - gpu3D->NDS_3D_Reset(); WIFI_Reset(); memcpy(FW_Mac, (MMU.fw.data + 0x36), 6); diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 050cde127..681197876 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -37,7 +37,6 @@ typedef struct } OGLVersion; static OGLVersion _OGLDriverVersion = {0, 0, 0}; -static OpenGLRenderer *_OGLRenderer = NULL; // Lookup Tables static CACHE_ALIGN GLfloat material_8bit_to_float[256] = {0}; @@ -56,14 +55,14 @@ const GLubyte PostprocessElementBuffer[6] = {0, 1, 2, 2, 3, 0}; const GLenum RenderDrawList[4] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT}; -static bool BEGINGL() +bool BEGINGL() { if(oglrender_beginOpenGL) return oglrender_beginOpenGL(); else return true; } -static void ENDGL() +void ENDGL() { if(oglrender_endOpenGL) oglrender_endOpenGL(); @@ -572,13 +571,14 @@ static void OGLGetDriverVersion(const char *oglVersionString, } } -void texDeleteCallback(TexCacheItem *item) +void texDeleteCallback(TexCacheItem *texItem, void *param1, void *param2) { - _OGLRenderer->DeleteTexture(item); + OpenGLRenderer *oglRenderer = (OpenGLRenderer *)param1; + oglRenderer->DeleteTexture(texItem); } template -static Render3D* OGLInit() +static Render3D* OpenGLRendererCreate() { OpenGLRenderer *newRenderer = NULL; Render3DError error = OGLERROR_NOERR; @@ -599,11 +599,6 @@ static Render3D* OGLInit() return NULL; } - // Force the creation of a new rendering object since we don't know what OpenGL version - // the user might be requesting. - delete _OGLRenderer; - _OGLRenderer = NULL; - // Get OpenGL info const char *oglVersionString = (const char *)glGetString(GL_VERSION); const char *oglVendorString = (const char *)glGetString(GL_VENDOR); @@ -615,7 +610,7 @@ static Render3D* OGLInit() if(!strcmp(oglVendorString,"Intel") && strstr(oglRendererString,"965")) { INFO("OpenGL: Incompatible graphic card detected. Disabling OpenGL support.\n"); - return _OGLRenderer; + return newRenderer; } // Check the driver's OpenGL version @@ -627,7 +622,7 @@ static Render3D* OGLInit() OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MAJOR, OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MINOR, OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION, oglVersionString, oglVendorString, oglRendererString); - return _OGLRenderer; + return newRenderer; } // Create new OpenGL rendering object @@ -642,7 +637,7 @@ static Render3D* OGLInit() else { if(require_profile) - return _OGLRenderer; + return newRenderer; } } @@ -688,7 +683,7 @@ static Render3D* OGLInit() { INFO("OpenGL: Renderer did not initialize. Disabling 3D renderer.\n[ Driver Info -\n Version: %s\n Vendor: %s\n Renderer: %s ]\n", oglVersionString, oglVendorString, oglRendererString); - return _OGLRenderer; + return newRenderer; } // Initialize OpenGL extensions @@ -702,21 +697,25 @@ static Render3D* OGLInit() { INFO("OpenGL: Shaders are not working, even though they should be. Disabling 3D renderer.\n"); delete newRenderer; - return _OGLRenderer; + newRenderer = NULL; + + return newRenderer; } else if (IsVersionSupported(3, 0, 0) && error == OGLERROR_FBO_CREATE_ERROR && OGLLoadEntryPoints_3_2_Func != NULL) { INFO("OpenGL: FBOs are not working, even though they should be. Disabling 3D renderer.\n"); delete newRenderer; - return _OGLRenderer; + newRenderer = NULL; + + return newRenderer; } } + ENDGL(); + // Initialization finished -- reset the renderer newRenderer->Reset(); - ENDGL(); - unsigned int major = 0; unsigned int minor = 0; unsigned int revision = 0; @@ -725,97 +724,42 @@ static Render3D* OGLInit() INFO("OpenGL: Renderer initialized successfully (v%u.%u.%u).\n[ Driver Info -\n Version: %s\n Vendor: %s\n Renderer: %s ]\n", major, minor, revision, oglVersionString, oglVendorString, oglRendererString); - _OGLRenderer = newRenderer; - return _OGLRenderer; + return newRenderer; } -static void OGLClose() +static void OpenGLRendererDestroy() { if(!BEGINGL()) return; - if (CurrentRenderer == _OGLRenderer) + if (CurrentRenderer != BaseRenderer) { - CurrentRenderer = NULL; + delete (OpenGLRenderer *)CurrentRenderer; + CurrentRenderer = BaseRenderer; } - delete _OGLRenderer; - _OGLRenderer = NULL; - - ENDGL(); -} - -static void OGLReset() -{ - if(!BEGINGL()) - return; - - _OGLRenderer->Reset(); - - ENDGL(); -} - -static void OGLRender() -{ - if(!BEGINGL()) - return; - - _OGLRenderer->Render(gfx3d); - - ENDGL(); -} - -static void OGLVramReconfigureSignal() -{ - if(!BEGINGL()) - return; - - _OGLRenderer->VramReconfigureSignal(); - - ENDGL(); -} - -static void OGLRenderFinish() -{ - if(!BEGINGL()) - return; - - _OGLRenderer->RenderFinish(); - ENDGL(); } //automatically select 3.2 or old profile depending on whether 3.2 is available GPU3DInterface gpu3Dgl = { "OpenGL", - OGLInit, - OGLClose, - OGLReset, - OGLRender, - OGLRenderFinish, - OGLVramReconfigureSignal + OpenGLRendererCreate, + OpenGLRendererDestroy }; //forcibly use old profile GPU3DInterface gpu3DglOld = { "OpenGL Old", - OGLInit, - OGLClose, - OGLReset, - OGLRender, - OGLRenderFinish, - OGLVramReconfigureSignal + OpenGLRendererCreate, + OpenGLRendererDestroy }; //forcibly use new profile GPU3DInterface gpu3Dgl_3_2 = { "OpenGL 3.2", - OGLInit, - OGLClose, - OGLReset, - OGLRender, - OGLRenderFinish, - OGLVramReconfigureSignal + OpenGLRendererCreate, + OpenGLRendererDestroy }; OpenGLRenderer::OpenGLRenderer() @@ -826,6 +770,28 @@ OpenGLRenderer::OpenGLRenderer() versionMajor = 0; versionMinor = 0; versionRevision = 0; + + isVBOSupported = false; + isPBOSupported = false; + isFBOSupported = false; + isMultisampledFBOSupported = false; + isShaderSupported = false; + isVAOSupported = false; + + // Init OpenGL rendering states + ref = new OGLRenderRef; + ref->fboRenderID = 0; + ref->fboMSIntermediateRenderID = 0; + ref->fboPostprocessID = 0; + ref->selectedRenderingFBO = 0; + + memset(GPU_screen3D, 0, sizeof(GPU_screen3D)); + + currTexture = NULL; + gpuScreen3DHasNewData[0] = false; + gpuScreen3DHasNewData[1] = false; + doubleBufferIndex = 0; + _currentPolyIndex = 0; } bool OpenGLRenderer::IsExtensionPresent(const std::set *oglExtensionSet, const std::string extensionName) const @@ -931,23 +897,6 @@ void OpenGLRenderer::ConvertFramebuffer(const u32 *__restrict srcBuffer, u32 *ds } } -OpenGLRenderer_1_2::OpenGLRenderer_1_2() -{ - isVBOSupported = false; - isPBOSupported = false; - isFBOSupported = false; - isMultisampledFBOSupported = false; - isShaderSupported = false; - isVAOSupported = false; - - // Init OpenGL rendering states - ref = new OGLRenderRef; - ref->fboRenderID = 0; - ref->fboMSIntermediateRenderID = 0; - ref->fboPostprocessID = 0; - ref->selectedRenderingFBO = 0; -} - OpenGLRenderer_1_2::~OpenGLRenderer_1_2() { if (ref == NULL) @@ -1959,6 +1908,11 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) OGLRenderRef &OGLRef = *this->ref; this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01; + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } + if (this->isShaderSupported) { glUseProgram(OGLRef.programGeometryID); @@ -2203,6 +2157,8 @@ Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount) this->ReadBackPixels(); + ENDGL(); + return OGLERROR_NOERR; } @@ -2450,9 +2406,9 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT { this->currTexture = newTexture; //has the ogl renderer initialized the texture? - if(!this->currTexture->deleteCallback) + if(this->currTexture->GetDeleteCallback() == NULL) { - this->currTexture->deleteCallback = &texDeleteCallback; + this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); if(OGLRef.freeTextureIDs.empty()) { @@ -2507,16 +2463,13 @@ Render3DError OpenGLRenderer_1_2::Reset() { OGLRenderRef &OGLRef = *this->ref; - this->gpuScreen3DHasNewData[0] = false; - this->gpuScreen3DHasNewData[1] = false; + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } glFinish(); - for (size_t i = 0; i < 2; i++) - { - memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i])); - } - if (!this->isShaderSupported) { glEnable(GL_NORMALIZE); @@ -2527,6 +2480,16 @@ Render3DError OpenGLRenderer_1_2::Reset() glEnable(GL_BLEND); } + ENDGL(); + + this->gpuScreen3DHasNewData[0] = false; + this->gpuScreen3DHasNewData[1] = false; + + for (size_t i = 0; i < 2; i++) + { + memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i])); + } + if (OGLRef.color4fBuffer != NULL) { memset(OGLRef.color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat)); @@ -2549,7 +2512,6 @@ Render3DError OpenGLRenderer_1_2::Reset() memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer)); memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer)); memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer)); - memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); TexCache_Reset(); @@ -2567,6 +2529,11 @@ Render3DError OpenGLRenderer_1_2::RenderFinish() OGLRenderRef &OGLRef = *this->ref; + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } + if (this->isPBOSupported) { glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID[i]); @@ -2587,6 +2554,8 @@ Render3DError OpenGLRenderer_1_2::RenderFinish() this->ConvertFramebuffer(workingBuffer, (u32 *)gfx3d_convertedScreen); } + ENDGL(); + this->gpuScreen3DHasNewData[i] = false; return OGLERROR_NOERR; @@ -2878,6 +2847,11 @@ Render3DError OpenGLRenderer_1_5::BeginRender(const GFX3D &engine) OGLRenderRef &OGLRef = *this->ref; this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01; + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } + if (this->isShaderSupported) { glUseProgram(OGLRef.programGeometryID); @@ -2970,6 +2944,11 @@ Render3DError OpenGLRenderer_1_5::RenderFinish() OGLRenderRef &OGLRef = *this->ref; + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } + if (this->isPBOSupported) { glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID[i]); @@ -2990,6 +2969,8 @@ Render3DError OpenGLRenderer_1_5::RenderFinish() this->ConvertFramebuffer(workingBuffer, (u32 *)gfx3d_convertedScreen); } + ENDGL(); + this->gpuScreen3DHasNewData[i] = false; return OGLERROR_NOERR; @@ -3403,6 +3384,11 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine) OGLRenderRef &OGLRef = *this->ref; this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01; + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } + // Setup render states glUseProgram(OGLRef.programGeometryID); glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading); @@ -3704,9 +3690,9 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT { this->currTexture = newTexture; //has the ogl renderer initialized the texture? - if(!this->currTexture->deleteCallback) + if(this->currTexture->GetDeleteCallback() == NULL) { - this->currTexture->deleteCallback = &texDeleteCallback; + this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); if(OGLRef.freeTextureIDs.empty()) { @@ -3761,6 +3747,11 @@ Render3DError OpenGLRenderer_2_1::RenderFinish() return OGLERROR_NOERR; } + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } + glBindBuffer(GL_PIXEL_PACK_BUFFER, this->ref->pboRenderDataID[i]); const u32 *__restrict mappedBufferPtr = (u32 *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); @@ -3772,6 +3763,8 @@ Render3DError OpenGLRenderer_2_1::RenderFinish() glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + ENDGL(); + this->gpuScreen3DHasNewData[i] = false; return OGLERROR_NOERR; diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index f5a18f8fa..d9fde371c 100644 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -309,6 +309,8 @@ enum OGLErrorCode { OGLERROR_NOERR = RENDER3DERROR_NOERR, + OGLERROR_BEGINGL_FAILED, + OGLERROR_FEATURE_UNSUPPORTED, OGLERROR_VBO_UNSUPPORTED, OGLERROR_PBO_UNSUPPORTED, @@ -504,7 +506,7 @@ extern CACHE_ALIGN const GLfloat divide5bitBy31_LUT[32]; extern const GLfloat PostprocessVtxBuffer[16]; extern const GLubyte PostprocessElementBuffer[6]; -extern void texDeleteCallback(TexCacheItem *item); +extern void texDeleteCallback(TexCacheItem *texItem, void *param1, void *param2); //This is called by OGLRender whenever it initializes. //Platforms, please be sure to set this up. @@ -518,6 +520,11 @@ extern bool (*oglrender_beginOpenGL)(); //This is called by OGLRender after it is done using opengl. extern void (*oglrender_endOpenGL)(); +// Helper functions for calling the above function pointers at the +// beginning and ending of OpenGL commands. +bool BEGINGL(); +void ENDGL(); + // These functions need to be assigned by ports that support using an // OpenGL 3.2 Core Profile context. The OGLRender_3_2.cpp file includes // the corresponding functions to assign to each function pointer. @@ -668,7 +675,6 @@ protected: virtual Render3DError SetupViewport(const u32 viewportValue); public: - OpenGLRenderer_1_2(); ~OpenGLRenderer_1_2(); virtual Render3DError InitExtensions(); diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 4369c520b..5541b6436 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -1045,6 +1045,11 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) OGLRenderRef &OGLRef = *this->ref; this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01; + if(!BEGINGL()) + { + return OGLERROR_BEGINGL_FAILED; + } + // Since glReadPixels() is called at the end of every render, we know that rendering // must be synchronized at that time. Therefore, GL_MAP_UNSYNCHRONIZED_BIT should be // safe to use. @@ -1384,9 +1389,9 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT { this->currTexture = newTexture; //has the ogl renderer initialized the texture? - if(!this->currTexture->deleteCallback) + if(this->currTexture->GetDeleteCallback() == NULL) { - this->currTexture->deleteCallback = &texDeleteCallback; + this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); if(OGLRef.freeTextureIDs.empty()) { diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index be89dc99f..3e16a0d62 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -546,7 +546,7 @@ void gfx3d_init() void gfx3d_reset() { - gpu3D->NDS_3D_RenderFinish(); + CurrentRenderer->RenderFinish(); #ifdef _SHOW_VTX_COUNTERS max_polys = max_verts = 0; @@ -625,6 +625,8 @@ void gfx3d_reset() GFX_PIPEclear(); GFX_FIFOclear(); + + CurrentRenderer->Reset(); } @@ -2284,7 +2286,7 @@ void gfx3d_VBlankEndSignal(bool skipFrame) return; } - gpu3D->NDS_3D_Render(); + CurrentRenderer->Render(gfx3d); } //#define _3D_LOG @@ -2395,7 +2397,7 @@ void gfx3d_glGetLightColor(unsigned int index, unsigned int* dest) void gfx3d_GetLineData(int line, u8** dst) { - gpu3D->NDS_3D_RenderFinish(); + CurrentRenderer->RenderFinish(); *dst = gfx3d_convertedScreen+((line)<<(8+2)); } @@ -2511,7 +2513,7 @@ SFORMAT SF_GFX3D[]={ //-------------savestate void gfx3d_savestate(EMUFILE* os) { - gpu3D->NDS_3D_RenderFinish(); + CurrentRenderer->RenderFinish(); //version write32le(4,os); diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index d137ca744..1ddc8ed18 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -1116,19 +1116,15 @@ void _HACK_Viewer_ExecUnit() _HACK_viewer_rasterizerUnit.mainLoop(); } -static Render3D* SoftRastInit() +static Render3D* SoftRasterizerRendererCreate() { return new SoftRasterizerRenderer; } GPU3DInterface gpu3DRasterize = { "SoftRasterizer", - SoftRastInit, - Default3D_Close, - Default3D_Reset, - Default3D_Render, - Default3D_RenderFinish, - Default3D_VramReconfigureSignal + SoftRasterizerRendererCreate, + Render3DBaseDestroy }; SoftRasterizerRenderer::SoftRasterizerRenderer() @@ -1779,7 +1775,6 @@ Render3DError SoftRasterizerRenderer::Reset() memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer)); memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer)); memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer)); - memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); TexCache_Reset(); diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index 7a6588f63..6a0b6c682 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -30,38 +30,34 @@ int cur3DCore = GPU3D_NULL; GPU3DInterface gpu3DNull = { "None", - Default3D_Init, - Default3D_Close, - Default3D_Reset, - Default3D_Render, - Default3D_RenderFinish, - Default3D_VramReconfigureSignal + Render3DBaseCreate, + Render3DBaseDestroy }; GPU3DInterface *gpu3D = &gpu3DNull; -static Render3D *_baseRenderer = NULL; +Render3D *BaseRenderer = NULL; Render3D *CurrentRenderer = NULL; void Render3D_Init() { - if (_baseRenderer == NULL) + if (BaseRenderer == NULL) { - _baseRenderer = new Render3D; + BaseRenderer = new Render3D; } if (CurrentRenderer == NULL) { gpu3D = &gpu3DNull; cur3DCore = GPU3D_NULL; - CurrentRenderer = _baseRenderer; + CurrentRenderer = BaseRenderer; } } void Render3D_DeInit() { gpu3D->NDS_3D_Close(); - delete _baseRenderer; - _baseRenderer = NULL; + delete BaseRenderer; + BaseRenderer = NULL; } bool NDS_3D_ChangeCore(int newCore) @@ -87,7 +83,7 @@ bool NDS_3D_ChangeCore(int newCore) gpu3D->NDS_3D_Close(); gpu3D = &gpu3DNull; cur3DCore = GPU3D_NULL; - CurrentRenderer = _baseRenderer; + CurrentRenderer = BaseRenderer; Render3D *newRenderer = newRenderInterface->NDS_3D_Init(); if (newRenderer == NULL) @@ -103,41 +99,21 @@ bool NDS_3D_ChangeCore(int newCore) return result; } -Render3D* Default3D_Init() +Render3D* Render3DBaseCreate() { - _baseRenderer->Reset(); - return _baseRenderer; + BaseRenderer->Reset(); + return BaseRenderer; } -void Default3D_Close() +void Render3DBaseDestroy() { - if (CurrentRenderer != _baseRenderer) + if (CurrentRenderer != BaseRenderer) { delete CurrentRenderer; - CurrentRenderer = NULL; + CurrentRenderer = BaseRenderer; } } -void Default3D_Reset() -{ - CurrentRenderer->Reset(); -} - -void Default3D_Render() -{ - CurrentRenderer->Render(gfx3d); -} - -void Default3D_RenderFinish() -{ - CurrentRenderer->RenderFinish(); -} - -void Default3D_VramReconfigureSignal() -{ - CurrentRenderer->VramReconfigureSignal(); -} - Render3D::Render3D() { _renderID = RENDERID_NULL; @@ -160,7 +136,6 @@ Render3D::Render3D() Render3D::~Render3D() { - memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); TexCache_Reset(); } @@ -309,7 +284,6 @@ Render3DError Render3D::Reset() memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer)); memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer)); memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer)); - memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); TexCache_Reset(); diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index a08c9489a..4869a7391 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -28,28 +28,9 @@ class Render3D; typedef struct Render3DInterface { - // The name of the plugin, this name will appear in the plugins list - const char *name; - - //called once when the plugin starts up - Render3D* (*NDS_3D_Init)(); - - //called when the plugin shuts down - void (*NDS_3D_Close)(); - - //called when the emulator resets - void (*NDS_3D_Reset)(); - - //called when the renderer should do its job and render the current display lists - void (*NDS_3D_Render)(); - - // Called whenever 3D rendering needs to finish. This function should block the calling thread - // and only release the block when 3D rendering is finished. (Before reading the 3D layer, be - // sure to always call this function.) - void (*NDS_3D_RenderFinish)(); - - //called when the emulator reconfigures its vram. you may need to invalidate your texture cache. - void (*NDS_3D_VramReconfigureSignal)(); + const char *name; // The name of the renderer. + Render3D* (*NDS_3D_Init)(); // Called when the renderer is created. + void (*NDS_3D_Close)(); // Called when the renderer is destroyed. } GPU3DInterface; @@ -63,15 +44,12 @@ extern GPU3DInterface *core3DList[]; extern GPU3DInterface gpu3DNull; // Extern pointer +extern Render3D *BaseRenderer; extern Render3D *CurrentRenderer; extern GPU3DInterface *gpu3D; -Render3D* Default3D_Init(); -void Default3D_Close(); -void Default3D_Reset(); -void Default3D_Render(); -void Default3D_RenderFinish(); -void Default3D_VramReconfigureSignal(); +Render3D* Render3DBaseCreate(); +void Render3DBaseDestroy(); void Render3D_Init(); void Render3D_DeInit(); @@ -153,10 +131,15 @@ public: virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer); virtual Render3DError ClearFramebuffer(const GFX3D_State &renderState); - virtual Render3DError Reset(); - virtual Render3DError Render(const GFX3D &engine); - virtual Render3DError RenderFinish(); - virtual Render3DError VramReconfigureSignal(); + virtual Render3DError Reset(); // Called when the emulator resets. + + virtual Render3DError Render(const GFX3D &engine); // Called when the renderer should do its job and render the current display lists. + + virtual Render3DError RenderFinish(); // Called whenever 3D rendering needs to finish. This function should block the calling thread + // and only release the block when 3D rendering is finished. (Before reading the 3D layer, be + // sure to always call this function.) + + virtual Render3DError VramReconfigureSignal(); // Called when the emulator reconfigures its VRAM. Ypu may need to invalidate your texture cache. }; #endif diff --git a/desmume/src/texcache.h b/desmume/src/texcache.h index ab1e524ac..b84f45bf1 100644 --- a/desmume/src/texcache.h +++ b/desmume/src/texcache.h @@ -34,21 +34,31 @@ enum TexCache_TexFormat class TexCacheItem; typedef std::multimap TTexCacheItemMultimap; +typedef void (*TexCacheItemDeleteCallback)(TexCacheItem *texItem, void *param1, void *param2); class TexCacheItem { +private: + TexCacheItemDeleteCallback _deleteCallback; + void *_deleteCallbackParam1; + void *_deleteCallbackParam2; + public: TexCacheItem() : decode_len(0) , decoded(NULL) , suspectedInvalid(false) , assumedInvalid(false) - , deleteCallback(NULL) + , _deleteCallback(NULL) + , _deleteCallbackParam1(NULL) + , _deleteCallbackParam2(NULL) , cacheFormat(TexFormat_None) {} - ~TexCacheItem() { + + ~TexCacheItem() + { delete[] decoded; - if(deleteCallback) deleteCallback(this); + if(_deleteCallback != NULL) _deleteCallback(this, this->_deleteCallbackParam1, this->_deleteCallbackParam2); } u32 decode_len; u32 mode; @@ -64,8 +74,6 @@ public: float invSizeX, invSizeY; u64 texid; //used by ogl renderer for the texid - void (*deleteCallback)(TexCacheItem*); - TexCache_TexFormat cacheFormat; struct Dump { @@ -77,6 +85,18 @@ public: u8* texture; u8 palette[256*2]; } dump; + + TexCacheItemDeleteCallback GetDeleteCallback() + { + return this->_deleteCallback; + } + + void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2) + { + this->_deleteCallback = callbackFunc; + this->_deleteCallbackParam1 = inParam1; + this->_deleteCallbackParam2 = inParam2; + } }; void TexCache_Invalidate();