In previous code, there is no method for Shader memory release.
And no code for deleting shader object handle (only for deletiong frag/vert shader handle)
This patch cleans up most of the memory, but not completely.
Sorry for the JOGL version. I don't really know about JOGL at all.
Patch code
Index: src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java (revision 4157)
+++ src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java (working copy)
@@ -220,7 +220,6 @@
ARBShaderObjects.glAttachObjectARB(programID, vertexShaderID);
} else if (vertexShaderID != -1) {
removeVertShader();
- vertexShaderID = -1;
}
if (fragmentByteBuffer != null) {
@@ -245,7 +244,6 @@
ARBShaderObjects.glAttachObjectARB(programID, fragmentShaderID);
} else if (fragmentShaderID != -1) {
removeFragShader();
- fragmentShaderID = -1;
}
ARBShaderObjects.glLinkProgramARB(programID);
@@ -258,6 +256,7 @@
if (fragmentShaderID != -1) {
ARBShaderObjects.glDetachObjectARB(programID, fragmentShaderID);
ARBShaderObjects.glDeleteObjectARB(fragmentShaderID);
+ fragmentShaderID = -1;
}
}
@@ -266,6 +265,7 @@
if (vertexShaderID != -1) {
ARBShaderObjects.glDetachObjectARB(programID, vertexShaderID);
ARBShaderObjects.glDeleteObjectARB(vertexShaderID);
+ vertexShaderID = -1;
}
}
@@ -384,6 +384,19 @@
@Override
public void checkUniformSizeLimits() {
}
+
+ /**
+ * @see com.jme.scene.state.GLSLShaderObjectsState#cleanup()
+ */
+ @Override
+ public void cleanup() {
+ removeVertShader();
+ removeFragShader();
+ if (programID != -1) {
+ ARBShaderObjects.glDeleteObjectARB(programID);
+ programID = -1;
+ }
+ }
}
Index: src/com/jme/system/dummy/DummyRenderer.java
===================================================================
--- src/com/jme/system/dummy/DummyRenderer.java (revision 4157)
+++ src/com/jme/system/dummy/DummyRenderer.java (working copy)
@@ -341,6 +341,10 @@
@Override
protected void sendToGL(ByteBuffer vertexByteBuffer, ByteBuffer fragmentByteBuffer) {
}
+
+ @Override
+ public void cleanup() {
+ }
};
}
Index: src/com/jme/scene/state/GLSLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/GLSLShaderObjectsState.java (revision 4157)
+++ src/com/jme/scene/state/GLSLShaderObjectsState.java (working copy)
@@ -928,4 +928,9 @@
}
}
}
+
+ /**
+ * Frees the memory and invalidates the shader handle
+ */
+ public abstract void cleanup();
}
Index: src/com/jme/scene/state/jogl/JOGLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/jogl/JOGLShaderObjectsState.java (revision 4157)
+++ src/com/jme/scene/state/jogl/JOGLShaderObjectsState.java (working copy)
@@ -383,4 +383,11 @@
public void checkUniformSizeLimits() {
}
+ /**
+ * @see com.jme.scene.state.GLSLShaderObjectsState#cleanup()
+ */
+ @Override
+ public void cleanup() {
+ }
+
}
Test Code
package mulova.advance;
import java.util.ArrayList;
import com.jme.app.SimpleGame;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.scene.state.GLSLShaderObjectsState;
public class TestDeleteShader extends SimpleGame {
private static final String GC = "GC";
private static final String CREATE = "Create";
private static final String vert =
" void main(void) { n" +
"gl_Position = ftransform(); n"+
"}";
private static final String frag=
"void main(void) { n"+
"gl_FragColor = vec4(1); n"+
"}";
private ArrayList<GLSLShaderObjectsState> shaders = new ArrayList<GLSLShaderObjectsState>();
@Override
protected void simpleInitGame() {
KeyBindingManager.getKeyBindingManager().add(CREATE, KeyInput.KEY_1);
KeyBindingManager.getKeyBindingManager().add(GC, KeyInput.KEY_2);
}
@Override
protected void simpleUpdate() {
super.simpleUpdate();
if (KeyBindingManager.getKeyBindingManager().isValidCommand(CREATE)) {
createShader();
} else if (KeyBindingManager.getKeyBindingManager().isValidCommand(GC)) {
for (GLSLShaderObjectsState glsl : shaders) {
glsl.cleanup();
}
shaders.clear();
System.gc();
}
}
private void createShader() {
GLSLShaderObjectsState shader = this.display.getRenderer().createGLSLShaderObjectsState();
shader.load(vert, frag);
shader.apply();
shaders.add(shader);
}
public static void main(String[] args) {
TestDeleteShader shader = new TestDeleteShader();
shader.start();
}
}