diff --git a/src/itdelatrisu/opsu/Container.java b/src/itdelatrisu/opsu/Container.java index 7e789160..070fe6e7 100644 --- a/src/itdelatrisu/opsu/Container.java +++ b/src/itdelatrisu/opsu/Container.java @@ -23,6 +23,7 @@ import itdelatrisu.opsu.beatmap.Beatmap; import itdelatrisu.opsu.beatmap.BeatmapSetList; import itdelatrisu.opsu.downloads.DownloadList; import itdelatrisu.opsu.downloads.Updater; +import itdelatrisu.opsu.render.CurveRenderState; import itdelatrisu.opsu.ui.UI; import org.lwjgl.opengl.Display; @@ -132,6 +133,9 @@ public class Container extends AppGameContainer { // reset BeatmapSetList data if (BeatmapSetList.get() != null) BeatmapSetList.get().reset(); + + // delete OpenGL objects involved in the Curve rendering + CurveRenderState.shutdown(); } @Override diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index 287ebd63..2d93e235 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -75,6 +75,12 @@ public class CurveRenderState { //scale = scale * 118 / 128; //for curves exactly as big as the sliderball FrameBufferCache.init(width, height); } + + public static void shutdown() + { + staticState.shutdown(); + FrameBufferCache.shutdown(); + } /** * Creates an object to hold the render state that's necessary to draw a curve. @@ -447,5 +453,25 @@ public class CurveRenderState { colBorderLoc = GL20.glGetUniformLocation(program, "col_border"); } } + + private void shutdown() + { + if(gradientTexture != 0) + { + GL11.glDeleteTextures(gradientTexture); + gradientTexture = 0; + } + + if(program != 0) + { + GL20.glDeleteProgram(program); + program = 0; + attribLoc = 0; + texCoordLoc = 0; + colLoc = 0; + colBorderLoc = 0; + texLoc = 0; + } + } } } diff --git a/src/itdelatrisu/opsu/render/FrameBufferCache.java b/src/itdelatrisu/opsu/render/FrameBufferCache.java index 2558dd15..83d62a03 100644 --- a/src/itdelatrisu/opsu/render/FrameBufferCache.java +++ b/src/itdelatrisu/opsu/render/FrameBufferCache.java @@ -122,6 +122,20 @@ public class FrameBufferCache { return buffer; } + public static void shutdown() + { + //if there were any previous Framebuffers in the cache delete them + //this is necessary for cases when the game gets re-started with a + //different resolution without closing the process + FrameBufferCache fbcInstance = FrameBufferCache.getInstance(); + for(Rendertarget target: fbcInstance.cache) + { + target.destroyRTT(); + } + fbcInstance.cache.clear(); + fbcInstance.freeMap(); + } + /** * There should only ever be one framebuffer cache, this function returns * that one framebuffer cache instance. diff --git a/src/itdelatrisu/opsu/render/Rendertarget.java b/src/itdelatrisu/opsu/render/Rendertarget.java index 00599f5f..75894000 100644 --- a/src/itdelatrisu/opsu/render/Rendertarget.java +++ b/src/itdelatrisu/opsu/render/Rendertarget.java @@ -35,9 +35,12 @@ public class Rendertarget { /** The FBO ID. */ private final int fboID; - /** The texture ID. */ + /** The texture ID. for the color buffer this rendertarget renders into. */ private final int textureID; + /** The renderbuffer ID for the depth buffer that this rendertarget renders into. */ + private final int depthBufferID; + /** * Create a new FBO. * @param width the width @@ -48,6 +51,7 @@ public class Rendertarget { this.height = height; fboID = GL30.glGenFramebuffers(); textureID = GL11.glGenTextures(); + depthBufferID = GL30.glGenRenderbuffers(); } /** @@ -99,10 +103,9 @@ public class Rendertarget { GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); - int fboDepth = GL30.glGenRenderbuffers(); - GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, fboDepth); + GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, buffer.depthBufferID); GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width, height); - GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, fboDepth); + GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, buffer.depthBufferID); GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, fboTexture, 0); GL20.glDrawBuffers(GL30.GL_COLOR_ATTACHMENT0); @@ -112,4 +115,15 @@ public class Rendertarget { return buffer; } + + /** + * Destroy the OpenGL objects associated with this Rendertarget. Do not try + * to use this rendertarget with OpenGL after calling this method. + */ + public void destroyRTT() + { + GL30.glDeleteFramebuffers(fboID); + GL30.glDeleteRenderbuffers(depthBufferID); + GL11.glDeleteTextures(textureID); + } }