diff --git a/src/video/glnode.c b/src/video/glnode.c index 1909079a..933ecff1 100644 --- a/src/video/glnode.c +++ b/src/video/glnode.c @@ -116,9 +116,26 @@ int64_t glnode_onTouchEvent(interface_touch_event_t action, int pointer_count, i } #endif +static void *_destroy_glnodes(void) { + LOG("..."); + + glnode_array_node_s *p = head; + while (p) { + glnode_array_node_s *next = p->next; + FREE(p); + p = next; + } + + head=NULL; + tail=NULL; +} + __attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_glnode_manager(void) { LOG("Initializing GLNode manager subsystem"); + + atexit(&_destroy_glnodes); + #if INTERFACE_TOUCH interface_onTouchEvent = &glnode_onTouchEvent; #endif diff --git a/src/video/glvideo.c b/src/video/glvideo.c index 0b7256d9..2b3f3a58 100644 --- a/src/video/glvideo.c +++ b/src/video/glvideo.c @@ -347,10 +347,6 @@ static GLuint _build_program(demoSource *vertexSource, demoSource *fragmentSourc // Attach the vertex shader to our program glAttachShader(prgName, vertexShader); - // Delete the vertex shader since it is now attached - // to the program, which will retain a reference to it - glDeleteShader(vertexShader); - ///////////////////////////////////////// // Specify and compile Fragment Shader // ///////////////////////////////////////// @@ -389,10 +385,6 @@ static GLuint _build_program(demoSource *vertexSource, demoSource *fragmentSourc // Attach the fragment shader to our program glAttachShader(prgName, fragShader); - // Delete the fragment shader since it is now attached - // to the program, which will retain a reference to it - glDeleteShader(fragShader); - ////////////////////// // Link the program // ////////////////////// @@ -406,6 +398,17 @@ static GLuint _build_program(demoSource *vertexSource, demoSource *fragmentSourc free(log); } + glDetachShader(prgName, vertexShader); + glDetachShader(prgName, fragShader); + + // Delete the vertex shader since it is now attached and linked + // to the program, which will retain a reference to it + glDeleteShader(vertexShader); + + // Delete the fragment shader since it is now attached and linked + // to the program, which will retain a reference to it + glDeleteShader(fragShader); + glGetProgramiv(prgName, GL_LINK_STATUS, &status); if (status == 0) { LOG("Failed to link program"); @@ -616,19 +619,35 @@ static void gldriver_init_common(void) { } static void _gldriver_shutdown(void) { + LOG("Beginning GLDriver shutdown ..."); + // Cleanup all OpenGL objects - glDeleteTextures(1, &a2TextureName); - a2TextureName = UNINITIALIZED_GL; - _destroy_VAO(crtVAOName); - crtVAOName = UNINITIALIZED_GL; + if (a2TextureName != UNINITIALIZED_GL) { + glDeleteTextures(1, &a2TextureName); + a2TextureName = UNINITIALIZED_GL; + } + + if (crtVAOName != UNINITIALIZED_GL) { + _destroy_VAO(crtVAOName); + crtVAOName = UNINITIALIZED_GL; + } + mdlDestroyModel(&crtModel); - glDeleteProgram(program); - program = UNINITIALIZED_GL; + + glUseProgram(0); + if (program != UNINITIALIZED_GL) { + glDeleteProgram(program); + program = UNINITIALIZED_GL; + } + glnode_shutdownNodes(); LOG("Completed GLDriver shutdown ..."); } static void gldriver_shutdown(void) { + if (renderer_shutting_down) { + return; + } #if USE_GLUT glutLeaveMainLoop(); #endif @@ -847,6 +866,7 @@ static void gldriver_init_glut(GLuint fbo) { glutTimerFunc(16, gldriver_update, 0); glutDisplayFunc(gldriver_render); glutReshapeFunc(gldriver_reshape); + glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); #if !TESTING glutKeyboardFunc(gldriver_on_key_down); @@ -868,9 +888,7 @@ static void gldriver_init(void *fbo) { #pragma GCC diagnostic ignored "-Wpointer-to-int-cast" defaultFBO = (GLuint)fbo; #pragma GCC diagnostic pop -#if defined(__APPLE__) - gldriver_init_common(); -#elif defined(ANDROID) +#if defined(__APPLE__) || defined(ANDROID) gldriver_init_common(); #elif USE_GLUT gldriver_init_glut(defaultFBO); @@ -882,7 +900,6 @@ static void gldriver_init(void *fbo) { static void gldriver_main_loop(void) { #if USE_GLUT - glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); glutMainLoop(); LOG("GLUT main loop finished..."); #endif diff --git a/src/video_util/modelUtil.c b/src/video_util/modelUtil.c index 68005426..768be1ab 100644 --- a/src/video_util/modelUtil.c +++ b/src/video_util/modelUtil.c @@ -547,6 +547,7 @@ void mdlDestroyModel(INOUT GLModel **model) { FREE(m->texCoords); FREE(m->texPixels); + glBindTexture(GL_TEXTURE_2D, 0); if (m->textureName != UNINITIALIZED_GL) { glDeleteTextures(1, &(m->textureName)); m->textureName = UNINITIALIZED_GL; @@ -584,6 +585,10 @@ void mdlDestroyModel(INOUT GLModel **model) { glDeleteVertexArrays(1, &(m->vaoName)); } #else + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if (m->posBufferName != UNINITIALIZED_GL) { glDeleteBuffers(1, &(m->posBufferName)); m->posBufferName = UNINITIALIZED_GL; diff --git a/src/video_util/modelUtil.h b/src/video_util/modelUtil.h index 8dccbfcd..9be2bbf5 100644 --- a/src/video_util/modelUtil.h +++ b/src/video_util/modelUtil.h @@ -16,7 +16,8 @@ #include "common.h" -#define UNINITIALIZED_GL 31337 +#define UNINITIALIZED_GL (-31337) +#warning FIXME TODO : is there an official OpenGL value we can use to signify an uninitialized state? enum { POS_ATTRIB_IDX,