[COMMITTED] Releasing Shader Memory

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();
   }
   
}