diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 8da37db21..1b367a0cc 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -160,7 +160,8 @@ int NDS_Init() //why is this done here? shitty engineering. not intended. NDS_RunAdvansceneAutoImport(); } - + + Render3D_Init(); gfx3d_init(); armcpu_new(&NDS_ARM9,0); @@ -190,7 +191,7 @@ void NDS_DeInit(void) SPU_DeInit(); Screen_DeInit(); MMU_DeInit(); - gpu3D->NDS_3D_Close(); + Render3D_DeInit(); WIFI_DeInit(); diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 1335a9206..050cde127 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -578,29 +578,32 @@ void texDeleteCallback(TexCacheItem *item) } template -static char OGLInit(void) +static Render3D* OGLInit() { - char result = 0; + OpenGLRenderer *newRenderer = NULL; Render3DError error = OGLERROR_NOERR; - if(!oglrender_init) - return result; - if(!oglrender_init()) - return result; - - result = Default3D_Init(); - if (result == 0) + if (oglrender_init == NULL) { - return result; + return NULL; } - - if(!BEGINGL()) + + if (!oglrender_init()) + { + return NULL; + } + + if (!BEGINGL()) { INFO("OpenGL<%s,%s>: Could not initialize -- BEGINGL() failed.\n",require_profile?"force":"auto",enable_3_2?"3_2":"old"); - result = 0; - return result; + 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); @@ -611,9 +614,8 @@ static char OGLInit(void) // http://forums.desmume.org/viewtopic.php?id=9286 if(!strcmp(oglVendorString,"Intel") && strstr(oglRendererString,"965")) { - INFO("Incompatible graphic card detected. Disabling OpenGL support.\n"); - result = 0; - return result; + INFO("OpenGL: Incompatible graphic card detected. Disabling OpenGL support.\n"); + return _OGLRenderer; } // Check the driver's OpenGL version @@ -625,74 +627,72 @@ static char OGLInit(void) OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MAJOR, OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MINOR, OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION, oglVersionString, oglVendorString, oglRendererString); - result = 0; - return result; + return _OGLRenderer; } // Create new OpenGL rendering object - if(enable_3_2) + if (enable_3_2) { if (OGLLoadEntryPoints_3_2_Func != NULL && OGLCreateRenderer_3_2_Func != NULL) { OGLLoadEntryPoints_3_2_Func(); OGLLoadEntryPoints_Legacy(); //zero 04-feb-2013 - this seems to be necessary as well - OGLCreateRenderer_3_2_Func(&_OGLRenderer); + OGLCreateRenderer_3_2_Func(&newRenderer); } else { if(require_profile) - return 0; + return _OGLRenderer; } } // If the renderer doesn't initialize with OpenGL v3.2 or higher, fall back // to one of the lower versions. - if (_OGLRenderer == NULL) + if (newRenderer == NULL) { OGLLoadEntryPoints_Legacy(); if (IsVersionSupported(2, 1, 0)) { - _OGLRenderer = new OpenGLRenderer_2_1; - _OGLRenderer->SetVersion(2, 1, 0); + newRenderer = new OpenGLRenderer_2_1; + newRenderer->SetVersion(2, 1, 0); } else if (IsVersionSupported(2, 0, 0)) { - _OGLRenderer = new OpenGLRenderer_2_0; - _OGLRenderer->SetVersion(2, 0, 0); + newRenderer = new OpenGLRenderer_2_0; + newRenderer->SetVersion(2, 0, 0); } else if (IsVersionSupported(1, 5, 0)) { - _OGLRenderer = new OpenGLRenderer_1_5; - _OGLRenderer->SetVersion(1, 5, 0); + newRenderer = new OpenGLRenderer_1_5; + newRenderer->SetVersion(1, 5, 0); } else if (IsVersionSupported(1, 4, 0)) { - _OGLRenderer = new OpenGLRenderer_1_4; - _OGLRenderer->SetVersion(1, 4, 0); + newRenderer = new OpenGLRenderer_1_4; + newRenderer->SetVersion(1, 4, 0); } else if (IsVersionSupported(1, 3, 0)) { - _OGLRenderer = new OpenGLRenderer_1_3; - _OGLRenderer->SetVersion(1, 3, 0); + newRenderer = new OpenGLRenderer_1_3; + newRenderer->SetVersion(1, 3, 0); } else if (IsVersionSupported(1, 2, 0)) { - _OGLRenderer = new OpenGLRenderer_1_2; - _OGLRenderer->SetVersion(1, 2, 0); + newRenderer = new OpenGLRenderer_1_2; + newRenderer->SetVersion(1, 2, 0); } } - if (_OGLRenderer == NULL) + if (newRenderer == NULL) { 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); - result = 0; - return result; + return _OGLRenderer; } // Initialize OpenGL extensions - error = _OGLRenderer->InitExtensions(); + error = newRenderer->InitExtensions(); if (error != OGLERROR_NOERR) { if ( IsVersionSupported(2, 0, 0) && @@ -701,31 +701,48 @@ static char OGLInit(void) error == OGLERROR_FRAGMENT_SHADER_PROGRAM_LOAD_ERROR) ) { INFO("OpenGL: Shaders are not working, even though they should be. Disabling 3D renderer.\n"); - result = 0; - return result; + delete newRenderer; + return _OGLRenderer; } 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"); - result = 0; - return result; + delete newRenderer; + return _OGLRenderer; } } // Initialization finished -- reset the renderer - _OGLRenderer->Reset(); + newRenderer->Reset(); ENDGL(); unsigned int major = 0; unsigned int minor = 0; unsigned int revision = 0; - _OGLRenderer->GetVersion(&major, &minor, &revision); + newRenderer->GetVersion(&major, &minor, &revision); 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); - return result; + _OGLRenderer = newRenderer; + return _OGLRenderer; +} + +static void OGLClose() +{ + if(!BEGINGL()) + return; + + if (CurrentRenderer == _OGLRenderer) + { + CurrentRenderer = NULL; + } + + delete _OGLRenderer; + _OGLRenderer = NULL; + + ENDGL(); } static void OGLReset() @@ -738,19 +755,6 @@ static void OGLReset() ENDGL(); } -static void OGLClose() -{ - if(!BEGINGL()) - return; - - delete _OGLRenderer; - _OGLRenderer = NULL; - - ENDGL(); - - Default3D_Close(); -} - static void OGLRender() { if(!BEGINGL()) @@ -785,8 +789,8 @@ static void OGLRenderFinish() GPU3DInterface gpu3Dgl = { "OpenGL", OGLInit, - OGLReset, OGLClose, + OGLReset, OGLRender, OGLRenderFinish, OGLVramReconfigureSignal @@ -796,8 +800,8 @@ GPU3DInterface gpu3Dgl = { GPU3DInterface gpu3DglOld = { "OpenGL Old", OGLInit, - OGLReset, OGLClose, + OGLReset, OGLRender, OGLRenderFinish, OGLVramReconfigureSignal @@ -807,8 +811,8 @@ GPU3DInterface gpu3DglOld = { GPU3DInterface gpu3Dgl_3_2 = { "OpenGL 3.2", OGLInit, - OGLReset, OGLClose, + OGLReset, OGLRender, OGLRenderFinish, OGLVramReconfigureSignal @@ -816,6 +820,9 @@ GPU3DInterface gpu3Dgl_3_2 = { OpenGLRenderer::OpenGLRenderer() { + _renderID = RENDERID_OPENGL_AUTO; + _renderName = "OpenGL"; + versionMajor = 0; versionMinor = 0; versionRevision = 0; @@ -967,7 +974,7 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2() DestroyFBOs(); DestroyMultisampledFBO(); - //kill the tex cache to free all the texture ids + // Kill the texture cache now before all of our texture IDs disappear. TexCache_Reset(); while(!ref->freeTextureIDs.empty()) @@ -1196,10 +1203,10 @@ Render3DError OpenGLRenderer_1_2::InitGeometryProgramShaderLocations() OGLRenderRef &OGLRef = *this->ref; // Set up shader uniforms - OGLRef.uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID, "texRenderObject"); - OGLRef.uniformTexToonTable = glGetUniformLocation(OGLRef.programGeometryID, "texToonTable"); - glUniform1i(OGLRef.uniformTexRenderObject, 0); - glUniform1i(OGLRef.uniformTexToonTable, OGLTextureUnitID_ToonTable); + const GLint uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID, "texRenderObject"); + const GLint uniformTexToonTable = glGetUniformLocation(OGLRef.programGeometryID, "texToonTable"); + glUniform1i(uniformTexRenderObject, 0); + glUniform1i(uniformTexToonTable, OGLTextureUnitID_ToonTable); OGLRef.uniformStateToonShadingMode = glGetUniformLocation(OGLRef.programGeometryID, "stateToonShadingMode"); OGLRef.uniformStateEnableAlphaTest = glGetUniformLocation(OGLRef.programGeometryID, "stateEnableAlphaTest"); @@ -2071,7 +2078,7 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) +Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList) { OGLRenderRef &OGLRef = *this->ref; const size_t polyCount = polyList->count; @@ -2413,7 +2420,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT const PolygonTexParams params = thePoly.getTexParams(); // Check if we need to use textures - if (thePoly.texParam == 0 || params.texFormat == TEXMODE_NONE || !enableTexturing) + if (params.texFormat == TEXMODE_NONE || !enableTexturing) { if (this->isShaderSupported) { @@ -2538,6 +2545,14 @@ Render3DError OpenGLRenderer_1_2::Reset() OGLRef.vtxPtrTexCoord = (GLvoid *)offsetof(VERT, texcoord); OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)offsetof(VERT, color) : OGLRef.color4fBuffer; + memset(this->clearImageColor16Buffer, 0, sizeof(this->clearImageColor16Buffer)); + 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(); + return OGLERROR_NOERR; } @@ -3116,13 +3131,13 @@ Render3DError OpenGLRenderer_2_0::InitEdgeMarkProgramShaderLocations() { OGLRenderRef &OGLRef = *this->ref; - OGLRef.uniformTexGDepth_EdgeMark = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragDepth"); - OGLRef.uniformTexGPolyID_EdgeMark = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInPolyID"); - glUniform1i(OGLRef.uniformTexGDepth_EdgeMark, OGLTextureUnitID_GDepth); - glUniform1i(OGLRef.uniformTexGPolyID_EdgeMark, OGLTextureUnitID_GPolyID); + const GLint uniformTexGDepth = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragDepth"); + const GLint uniformTexGPolyID = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInPolyID"); + glUniform1i(uniformTexGDepth, OGLTextureUnitID_GDepth); + glUniform1i(uniformTexGPolyID, OGLTextureUnitID_GPolyID); - OGLRef.uniformFramebufferSize = glGetUniformLocation(OGLRef.programEdgeMarkID, "framebufferSize"); - OGLRef.uniformStateEdgeColor = glGetUniformLocation(OGLRef.programEdgeMarkID, "stateEdgeColor"); + OGLRef.uniformFramebufferSize = glGetUniformLocation(OGLRef.programEdgeMarkID, "framebufferSize"); + OGLRef.uniformStateEdgeColor = glGetUniformLocation(OGLRef.programEdgeMarkID, "stateEdgeColor"); return OGLERROR_NOERR; } @@ -3307,12 +3322,12 @@ Render3DError OpenGLRenderer_2_0::InitFogProgramShaderLocations() { OGLRenderRef &OGLRef = *this->ref; - OGLRef.uniformTexGColor_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFragColor"); - OGLRef.uniformTexGDepth_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFragDepth"); - OGLRef.uniformTexGFog_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFogAttributes"); - glUniform1i(OGLRef.uniformTexGColor_Fog, OGLTextureUnitID_GColor); - glUniform1i(OGLRef.uniformTexGDepth_Fog, OGLTextureUnitID_GDepth); - glUniform1i(OGLRef.uniformTexGFog_Fog, OGLTextureUnitID_FogAttr); + const GLint uniformTexGColor = glGetUniformLocation(OGLRef.programFogID, "texInFragColor"); + const GLint uniformTexGDepth = glGetUniformLocation(OGLRef.programFogID, "texInFragDepth"); + const GLint uniformTexGFog = glGetUniformLocation(OGLRef.programFogID, "texInFogAttributes"); + glUniform1i(uniformTexGColor, OGLTextureUnitID_GColor); + glUniform1i(uniformTexGDepth, OGLTextureUnitID_GDepth); + glUniform1i(uniformTexGFog, OGLTextureUnitID_FogAttr); OGLRef.uniformStateEnableFogAlphaOnly = glGetUniformLocation(OGLRef.programFogID, "stateEnableFogAlphaOnly"); OGLRef.uniformStateFogColor = glGetUniformLocation(OGLRef.programFogID, "stateFogColor"); @@ -3675,7 +3690,7 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT const PolygonTexParams params = thePoly.getTexParams(); // Check if we need to use textures - if (thePoly.texParam == 0 || params.texFormat == TEXMODE_NONE || !enableTexturing) + if (params.texFormat == TEXMODE_NONE || !enableTexturing) { glUniform1i(OGLRef.uniformPolyEnableTexture, GL_FALSE); return OGLERROR_NOERR; diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 4cf7c4a33..f5a18f8fa 100644 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -330,6 +330,13 @@ union GLvec2 GLfloat v[2]; }; +union GLvec3 +{ + struct { GLfloat r, g, b; }; + struct { GLfloat x, y, z; }; + GLfloat v[3]; +}; + union GLvec4 { struct { GLfloat r, g, b, a; }; @@ -337,6 +344,13 @@ union GLvec4 GLfloat v[4]; }; +struct OGLVertex +{ + GLvec4 position; + GLvec2 texCoord; + GLvec3 color; +}; + struct OGLRenderStates { GLvec2 framebufferSize; @@ -428,19 +442,6 @@ struct OGLRenderRef GLuint programEdgeMarkID; GLuint programFogID; - GLuint uniformBlockRenderStatesGeometry; - GLuint uniformBlockRenderStatesEdgeMark; - GLuint uniformBlockRenderStatesFog; - GLuint uniformTexBufferPolyStates; - - GLuint uniformTexRenderObject; - GLuint uniformTexToonTable; - GLuint uniformTexGDepth_EdgeMark; - GLuint uniformTexGPolyID_EdgeMark; - GLuint uniformTexGColor_Fog; - GLuint uniformTexGDepth_Fog; - GLuint uniformTexGFog_Fog; - GLint uniformFramebufferSize; GLint uniformStateToonShadingMode; GLint uniformStateEnableAlphaTest; @@ -655,7 +656,7 @@ protected: // Base rendering methods virtual Render3DError BeginRender(const GFX3D &engine); - virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList); + virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList); virtual Render3DError EndRender(const u64 frameCount); virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer); diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 4e26ddb74..4369c520b 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -549,13 +549,13 @@ Render3DError OpenGLRenderer_3_2::InitEdgeMarkProgramShaderLocations() { OGLRenderRef &OGLRef = *this->ref; - OGLRef.uniformBlockRenderStatesEdgeMark = glGetUniformBlockIndex(OGLRef.programEdgeMarkID, "RenderStates"); - glUniformBlockBinding(OGLRef.programEdgeMarkID, OGLRef.uniformBlockRenderStatesEdgeMark, OGLBindingPointID_RenderStates); + const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(OGLRef.programEdgeMarkID, "RenderStates"); + glUniformBlockBinding(OGLRef.programEdgeMarkID, uniformBlockRenderStates, OGLBindingPointID_RenderStates); - OGLRef.uniformTexGDepth_EdgeMark = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragDepth"); - OGLRef.uniformTexGPolyID_EdgeMark = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInPolyID"); - glUniform1i(OGLRef.uniformTexGDepth_EdgeMark, OGLTextureUnitID_GDepth); - glUniform1i(OGLRef.uniformTexGPolyID_EdgeMark, OGLTextureUnitID_GPolyID); + const GLint uniformTexGDepth = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragDepth"); + const GLint uniformTexGPolyID = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInPolyID"); + glUniform1i(uniformTexGDepth, OGLTextureUnitID_GDepth); + glUniform1i(uniformTexGPolyID, OGLTextureUnitID_GPolyID); return OGLERROR_NOERR; } @@ -574,15 +574,15 @@ Render3DError OpenGLRenderer_3_2::InitFogProgramShaderLocations() { OGLRenderRef &OGLRef = *this->ref; - OGLRef.uniformBlockRenderStatesFog = glGetUniformBlockIndex(OGLRef.programFogID, "RenderStates"); - glUniformBlockBinding(OGLRef.programFogID, OGLRef.uniformBlockRenderStatesFog, OGLBindingPointID_RenderStates); + const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(OGLRef.programFogID, "RenderStates"); + glUniformBlockBinding(OGLRef.programFogID, uniformBlockRenderStates, OGLBindingPointID_RenderStates); - OGLRef.uniformTexGColor_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFragColor"); - OGLRef.uniformTexGDepth_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFragDepth"); - OGLRef.uniformTexGFog_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFogAttributes"); - glUniform1i(OGLRef.uniformTexGColor_Fog, OGLTextureUnitID_GColor); - glUniform1i(OGLRef.uniformTexGDepth_Fog, OGLTextureUnitID_GDepth); - glUniform1i(OGLRef.uniformTexGFog_Fog, OGLTextureUnitID_FogAttr); + const GLint uniformTexGColor = glGetUniformLocation(OGLRef.programFogID, "texInFragColor"); + const GLint uniformTexGDepth = glGetUniformLocation(OGLRef.programFogID, "texInFragDepth"); + const GLint uniformTexGFog = glGetUniformLocation(OGLRef.programFogID, "texInFogAttributes"); + glUniform1i(uniformTexGColor, OGLTextureUnitID_GColor); + glUniform1i(uniformTexGDepth, OGLTextureUnitID_GDepth); + glUniform1i(uniformTexGFog, OGLTextureUnitID_FogAttr); return OGLERROR_NOERR; } @@ -915,11 +915,11 @@ Render3DError OpenGLRenderer_3_2::InitGeometryProgramShaderLocations() OGLRenderRef &OGLRef = *this->ref; // Set up render states UBO - OGLRef.uniformBlockRenderStatesGeometry = glGetUniformBlockIndex(OGLRef.programGeometryID, "RenderStates"); - glUniformBlockBinding(OGLRef.programGeometryID, OGLRef.uniformBlockRenderStatesGeometry, OGLBindingPointID_RenderStates); + const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(OGLRef.programGeometryID, "RenderStates"); + glUniformBlockBinding(OGLRef.programGeometryID, uniformBlockRenderStates, OGLBindingPointID_RenderStates); GLint uboSize = 0; - glGetActiveUniformBlockiv(OGLRef.programGeometryID, OGLRef.uniformBlockRenderStatesGeometry, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize); + glGetActiveUniformBlockiv(OGLRef.programGeometryID, uniformBlockRenderStates, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize); assert(uboSize == sizeof(OGLRenderStates)); glGenBuffers(1, &OGLRef.uboRenderStatesID); @@ -939,12 +939,12 @@ Render3DError OpenGLRenderer_3_2::InitGeometryProgramShaderLocations() glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA8UI, OGLRef.tboPolyStatesID); glActiveTexture(GL_TEXTURE0); - OGLRef.uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID, "texRenderObject"); - OGLRef.uniformTexBufferPolyStates = glGetUniformLocation(OGLRef.programGeometryID, "PolyStates"); - glUniform1i(OGLRef.uniformTexRenderObject, 0); - glUniform1i(OGLRef.uniformTexBufferPolyStates, OGLTextureUnitID_PolyStates); + const GLint uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID, "texRenderObject"); + const GLint uniformTexBufferPolyStates = glGetUniformLocation(OGLRef.programGeometryID, "PolyStates"); + glUniform1i(uniformTexRenderObject, 0); + glUniform1i(uniformTexBufferPolyStates, OGLTextureUnitID_PolyStates); - OGLRef.uniformPolyStateIndex = glGetUniformLocation(OGLRef.programGeometryID, "polyIndex"); + OGLRef.uniformPolyStateIndex = glGetUniformLocation(OGLRef.programGeometryID, "polyIndex"); return OGLERROR_NOERR; } @@ -1112,7 +1112,7 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) PolygonAttributes polyAttr = thePoly->getAttributes(); PolygonTexParams texParams = thePoly->getTexParams(); - polyStates[i].enableTexture = (thePoly->texParam != 0 && texParams.texFormat != TEXMODE_NONE && engine.renderState.enableTexturing) ? GL_TRUE : GL_FALSE; + polyStates[i].enableTexture = (texParams.texFormat != TEXMODE_NONE && engine.renderState.enableTexturing) ? GL_TRUE : GL_FALSE; polyStates[i].enableFog = (polyAttr.enableRenderFog) ? GL_TRUE : GL_FALSE; polyStates[i].enableDepthWrite = ((!polyAttr.isTranslucent || polyAttr.enableAlphaDepthWrite) && !(polyAttr.polygonMode == 3 && polyAttr.polygonID == 0)) ? GL_TRUE : GL_FALSE; polyStates[i].setNewDepthForTranslucent = (polyAttr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE; @@ -1374,7 +1374,7 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT const PolygonTexParams params = thePoly.getTexParams(); // Check if we need to use textures - if (thePoly.texParam == 0 || params.texFormat == TEXMODE_NONE || !enableTexturing) + if (params.texFormat == TEXMODE_NONE || !enableTexturing) { return OGLERROR_NOERR; } diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index fa4699a77..d137ca744 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -120,8 +120,6 @@ static FORCEINLINE int fastFloor(float f) // verts[vert_index] = &rawvert; //} -static SoftRasterizerRenderer *_SoftRastRenderer = NULL; - static FORCEINLINE int iround(float f) { return (int)f; //lol } @@ -1118,60 +1116,26 @@ void _HACK_Viewer_ExecUnit() _HACK_viewer_rasterizerUnit.mainLoop(); } -static char SoftRastInit(void) +static Render3D* SoftRastInit() { - char result = Default3D_Init(); - if (result == 0) - { - return result; - } - - if (_SoftRastRenderer == NULL) - { - _SoftRastRenderer = new SoftRasterizerRenderer; - } - - return result; -} - -static void SoftRastReset() -{ - _SoftRastRenderer->Reset(); -} - -static void SoftRastClose() -{ - delete _SoftRastRenderer; - _SoftRastRenderer = NULL; -} - -static void SoftRastRender() -{ - _SoftRastRenderer->Render(gfx3d); -} - -static void SoftRastVramReconfigureSignal() -{ - _SoftRastRenderer->VramReconfigureSignal(); -} - -static void SoftRastRenderFinish() -{ - _SoftRastRenderer->RenderFinish(); + return new SoftRasterizerRenderer; } GPU3DInterface gpu3DRasterize = { "SoftRasterizer", SoftRastInit, - SoftRastReset, - SoftRastClose, - SoftRastRender, - SoftRastRenderFinish, - SoftRastVramReconfigureSignal + Default3D_Close, + Default3D_Reset, + Default3D_Render, + Default3D_RenderFinish, + Default3D_VramReconfigureSignal }; SoftRasterizerRenderer::SoftRasterizerRenderer() { + _renderID = RENDERID_SOFTRASTERIZER; + _renderName = "SoftRasterizer"; + _debug_drawClippedUserPoly = -1; clippedPolys = clipper.clippedPolys = new GFX3D_Clipper::TClippedPoly[POLYLIST_SIZE*2]; @@ -1235,8 +1199,6 @@ SoftRasterizerRenderer::~SoftRasterizerRenderer() free(screenAttributes); free(screenColor); - - Default3D_Close(); } Render3DError SoftRasterizerRenderer::InitTables() @@ -1507,7 +1469,7 @@ Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine) return RENDER3DERROR_NOERR; } -Render3DError SoftRasterizerRenderer::RenderGeometry(const GFX3D_State &renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) +Render3DError SoftRasterizerRenderer::RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList) { // If multithreaded, allow for states to finish setting up if (this->_stateSetupNeedsFinish) @@ -1812,7 +1774,14 @@ Render3DError SoftRasterizerRenderer::Reset() this->_stateSetupNeedsFinish = false; this->_renderGeometryNeedsFinish = false; - Default3D_Reset(); + + memset(this->clearImageColor16Buffer, 0, sizeof(this->clearImageColor16Buffer)); + 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(); return RENDER3DERROR_NOERR; } @@ -1827,7 +1796,7 @@ Render3DError SoftRasterizerRenderer::Render(const GFX3D &engine) return error; } - this->RenderGeometry(engine.renderState, engine.vertlist, engine.polylist, &engine.indexlist); + this->RenderGeometry(engine.renderState, engine.polylist, &engine.indexlist); this->EndRender(engine.frameCtr); return error; diff --git a/desmume/src/rasterize.h b/desmume/src/rasterize.h index 267639451..ddf2b8b54 100644 --- a/desmume/src/rasterize.h +++ b/desmume/src/rasterize.h @@ -43,7 +43,7 @@ protected: // Base rendering methods virtual Render3DError BeginRender(const GFX3D &engine); - virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList); + virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList); virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias); virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly); virtual Render3DError EndRender(const u64 frameCount); diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index 0d1117835..7a6588f63 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -31,76 +31,118 @@ int cur3DCore = GPU3D_NULL; GPU3DInterface gpu3DNull = { "None", Default3D_Init, - Default3D_Reset, Default3D_Close, + Default3D_Reset, Default3D_Render, Default3D_RenderFinish, Default3D_VramReconfigureSignal }; GPU3DInterface *gpu3D = &gpu3DNull; -static bool default3DAlreadyClearedLayer = false; +static Render3D *_baseRenderer = NULL; +Render3D *CurrentRenderer = NULL; -char Default3D_Init() +void Render3D_Init() { - default3DAlreadyClearedLayer = false; - - return 1; -} - -void Default3D_Reset() -{ - default3DAlreadyClearedLayer = false; - - TexCache_Reset(); -} - -void Default3D_Close() -{ - memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); - default3DAlreadyClearedLayer = false; -} - -void Default3D_Render() -{ - if (!default3DAlreadyClearedLayer) + if (_baseRenderer == NULL) { - memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); - default3DAlreadyClearedLayer = true; + _baseRenderer = new Render3D; + } + + if (CurrentRenderer == NULL) + { + gpu3D = &gpu3DNull; + cur3DCore = GPU3D_NULL; + CurrentRenderer = _baseRenderer; } } -void Default3D_RenderFinish() +void Render3D_DeInit() { - // Do nothing -} - -void Default3D_VramReconfigureSignal() -{ - TexCache_Invalidate(); -} - -void NDS_3D_SetDriver (int core3DIndex) -{ - cur3DCore = core3DIndex; - gpu3D = core3DList[cur3DCore]; + gpu3D->NDS_3D_Close(); + delete _baseRenderer; + _baseRenderer = NULL; } bool NDS_3D_ChangeCore(int newCore) { - gpu3D->NDS_3D_Close(); - NDS_3D_SetDriver(newCore); - if(gpu3D->NDS_3D_Init() == 0) + bool result = false; + + Render3DInterface *newRenderInterface = core3DList[newCore]; + if (newRenderInterface->NDS_3D_Init == NULL) { - NDS_3D_SetDriver(GPU3D_NULL); - gpu3D->NDS_3D_Init(); - return false; + return result; } - return true; + + if (newRenderInterface == gpu3D) + { + result = true; + return result; + } + + // Some resources are shared between renderers, such as the texture cache, + // so we need to shut down the current renderer now to ensure that any + // shared resources aren't in use. + CurrentRenderer->RenderFinish(); + gpu3D->NDS_3D_Close(); + gpu3D = &gpu3DNull; + cur3DCore = GPU3D_NULL; + CurrentRenderer = _baseRenderer; + + Render3D *newRenderer = newRenderInterface->NDS_3D_Init(); + if (newRenderer == NULL) + { + return result; + } + + gpu3D = newRenderInterface; + cur3DCore = newCore; + CurrentRenderer = newRenderer; + + result = true; + return result; +} + +Render3D* Default3D_Init() +{ + _baseRenderer->Reset(); + return _baseRenderer; +} + +void Default3D_Close() +{ + if (CurrentRenderer != _baseRenderer) + { + delete CurrentRenderer; + CurrentRenderer = NULL; + } +} + +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; + _renderName = "None"; + static bool needTableInit = true; if (needTableInit) @@ -116,12 +158,28 @@ Render3D::Render3D() Reset(); } +Render3D::~Render3D() +{ + memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); + TexCache_Reset(); +} + +RendererID Render3D::GetRenderID() +{ + return this->_renderID; +} + +std::string Render3D::GetName() +{ + return this->_renderName; +} + Render3DError Render3D::BeginRender(const GFX3D &engine) { return RENDER3DERROR_NOERR; } -Render3DError Render3D::RenderGeometry(const GFX3D_State &renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) +Render3DError Render3D::RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList) { return RENDER3DERROR_NOERR; } @@ -251,6 +309,9 @@ 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(); return RENDER3DERROR_NOERR; } @@ -268,7 +329,7 @@ Render3DError Render3D::Render(const GFX3D &engine) this->UpdateToonTable(engine.renderState.u16ToonTable); this->ClearFramebuffer(engine.renderState); - this->RenderGeometry(engine.renderState, engine.vertlist, engine.polylist, &engine.indexlist); + this->RenderGeometry(engine.renderState, engine.polylist, &engine.indexlist); if (engine.renderState.enableEdgeMarking) { @@ -287,6 +348,7 @@ Render3DError Render3D::Render(const GFX3D &engine) Render3DError Render3D::RenderFinish() { + memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen)); return RENDER3DERROR_NOERR; } diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index b0108aa8f..a08c9489a 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -22,36 +22,35 @@ #include "gfx3d.h" #include "types.h" -//not using this right now -#define CALL_CONVENTION - #define kUnsetTranslucentPolyID 255 +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 - char (CALL_CONVENTION* NDS_3D_Init) (); + const char *name; - //called when the emulator resets (is this necessary?) - void (CALL_CONVENTION* NDS_3D_Reset) (); + //called once when the plugin starts up + Render3D* (*NDS_3D_Init)(); //called when the plugin shuts down - void (CALL_CONVENTION* NDS_3D_Close) (); + 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 (CALL_CONVENTION* NDS_3D_Render) (); + 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 (CALL_CONVENTION* NDS_3D_RenderFinish) (); - + void (*NDS_3D_RenderFinish)(); + //called when the emulator reconfigures its vram. you may need to invalidate your texture cache. - void (CALL_CONVENTION* NDS_3D_VramReconfigureSignal) (); - + void (*NDS_3D_VramReconfigureSignal)(); + } GPU3DInterface; extern int cur3DCore; @@ -64,18 +63,29 @@ extern GPU3DInterface *core3DList[]; extern GPU3DInterface gpu3DNull; // Extern pointer +extern Render3D *CurrentRenderer; extern GPU3DInterface *gpu3D; -char Default3D_Init(); -void Default3D_Reset(); +Render3D* Default3D_Init(); void Default3D_Close(); +void Default3D_Reset(); void Default3D_Render(); void Default3D_RenderFinish(); void Default3D_VramReconfigureSignal(); -void NDS_3D_SetDriver (int core3DIndex); +void Render3D_Init(); +void Render3D_DeInit(); bool NDS_3D_ChangeCore(int newCore); +enum RendererID +{ + RENDERID_NULL = 0, + RENDERID_SOFTRASTERIZER = 1, + RENDERID_OPENGL_AUTO = 1000, + RENDERID_OPENGL_LEGACY = 1001, + RENDERID_OPENGL_3_2 = 1002 +}; + enum Render3DErrorCode { RENDER3DERROR_NOERR = 0 @@ -112,13 +122,16 @@ inline FragmentColor MakeFragmentColor(u8 r, u8 g,u8 b,u8 a) class Render3D { protected: + RendererID _renderID; + std::string _renderName; + CACHE_ALIGN u16 clearImageColor16Buffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; CACHE_ALIGN u32 clearImageDepthBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; CACHE_ALIGN bool clearImageFogBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; CACHE_ALIGN u8 clearImagePolyIDBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT]; virtual Render3DError BeginRender(const GFX3D &engine); - virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList); + virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList); virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias); virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly); virtual Render3DError EndRender(const u64 frameCount); @@ -132,6 +145,10 @@ protected: public: Render3D(); + ~Render3D(); + + RendererID GetRenderID(); + std::string GetName(); virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer); virtual Render3DError ClearFramebuffer(const GFX3D_State &renderState); @@ -143,4 +160,3 @@ public: }; #endif -