aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/util/glsl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-04-22 14:29:12 +0200
committerSven Gothel <[email protected]>2011-04-22 14:29:12 +0200
commit54f58c0cb990eb2b4fc8c3be785cc47bde575f37 (patch)
tree20a3d4b0a4b4d6aceab9a8f65a8b05560ae3d8b3 /src/jogl/classes/com/jogamp/opengl/util/glsl
parentc1688186ece849002650bdb667a71bbcc628a684 (diff)
ShaderState: Validated impl./state-handling / Added comments
Capable of glBinAttribLocation(..) Proper state check (has program, linked program, ..) for attrib/uniform methods.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/glsl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java674
1 files changed, 453 insertions, 221 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
index 57ae6cfda..fe695ecb3 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -28,13 +28,22 @@
package com.jogamp.opengl.util.glsl;
-import javax.media.opengl.*;
-import jogamp.opengl.Debug;
-
+import java.security.AccessController;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.security.*;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLUniformData;
+
+import jogamp.opengl.Debug;
+
+import com.jogamp.common.util.IntObjectHashMap;
+import com.jogamp.opengl.util.GLArrayDataEditable;
public class ShaderState {
public static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLSLState", true, AccessController.getContext());
@@ -47,41 +56,106 @@ public class ShaderState {
public void setVerbose(boolean v) { verbose=v; }
/**
- * Fetches the current shader state from the thread local storage (TLS)
+ * Fetches the current shader state from this thread (TLS) current GLContext
*
* @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
- public static synchronized ShaderState getCurrent() {
- GLContext current = GLContext.getCurrent();
- if(null==current) {
- throw new GLException("No context is current on this thread");
- }
- return (ShaderState) current.getAttachedObject(ShaderState.class.getName());
+ public static synchronized ShaderState getCurrentShaderState() {
+ return getShaderState(GLContext.getCurrentGL());
+ }
+
+ /**
+ * Fetches the shader state from the GL object's GLContext
+ *
+ * @param gl the GL object referencing the GLContext
+ *
+ * @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
+ */
+ public static synchronized ShaderState getShaderState(GL gl) {
+ return (ShaderState) gl.getContext().getAttachedObject(ShaderState.class.getName());
+ }
+
+ /**
+ * Returns the attached user object for the given name to this ShaderState.
+ */
+ public final Object getAttachedObject(String name) {
+ return attachedObjectsByString.get(name);
+ }
+
+ /**
+ * Attach user object for the given name to this ShaderState.
+ * Returns the previously set object or null.
+ *
+ * @return the previous mapped object or null if none
+ */
+ public final Object attachObject(String name, Object obj) {
+ return attachedObjectsByString.put(name, obj);
+ }
+
+ /**
+ * @param name name of the mapped object to detach
+ *
+ * @return the previous mapped object or null if none
+ */
+ public final Object detachObject(String name) {
+ return attachedObjectsByString.remove(name);
+ }
+
+ /**
+ * Returns the attached user object for the given name to this ShaderState.
+ */
+ public final Object getAttachedObject(int name) {
+ return attachedObjectsByInt.get(name);
+ }
+
+ /**
+ * Attach user object for the given name to this ShaderState.
+ * Returns the previously set object or null.
+ */
+ public final Object attachObject(int name, Object obj) {
+ return attachedObjectsByInt.put(name, obj);
}
+ public final Object detachObject(int name) {
+ return attachedObjectsByInt.remove(name);
+ }
+
/**
* Turns the shader program on or off.<br>
* Puts this ShaderState to to the thread local storage (TLS),
* if <code>on</code> is <code>true</code>.
*
+ * @throws GLException if no program is attached
+ * @throws GLException if no program is not linked
+ *
* @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
public synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ if(null==shaderProgram) { throw new GLException("No program is attached"); }
if(on) {
- if(null!=shaderProgram) {
- shaderProgram.glUseProgram(gl, true);
- } else {
- throw new GLException("No program is attached");
- }
+ shaderProgram.glUseProgram(gl, true);
// update the current ShaderState to the TLS ..
- gl.getContext().putAttachedObject(ShaderState.class.getName(), this);
- } else if(null!=shaderProgram) {
+ gl.getContext().attachObject(ShaderState.class.getName(), this);
+ if(resetAllShaderData) {
+ resetAllShaderData = false;
+ glResetAllVertexAttributes(gl);
+ glResetAllUniforms(gl);
+ }
+ } else {
shaderProgram.glUseProgram(gl, false);
}
}
+ public synchronized void glUseProgram(GL2ES2 gl, ShaderProgram prog, boolean on) {
+
+ }
+
public boolean linked() {
return (null!=shaderProgram)?shaderProgram.linked():false;
}
@@ -118,7 +192,8 @@ public class ShaderState {
return;
}
prgInUse = shaderProgram.inUse();
- shaderProgram.glUseProgram(gl, false);
+ glUseProgram(gl, false);
+ resetAllShaderData = true;
}
// register new one
@@ -126,11 +201,11 @@ public class ShaderState {
if(null!=shaderProgram) {
// reinstall all data ..
- shaderProgram.glUseProgram(gl, true);
- glResetAllVertexAttributes(gl);
- glResetAllUniforms(gl);
- if(!prgInUse) {
- shaderProgram.glUseProgram(gl, false);
+ if(shaderProgram.linked()) {
+ glUseProgram(gl, true);
+ if(!prgInUse) {
+ shaderProgram.glUseProgram(gl, false);
+ }
}
}
if(DEBUG) {
@@ -149,6 +224,8 @@ public class ShaderState {
*/
public synchronized void destroy(GL2ES2 gl) {
release(gl, true, true);
+ attachedObjectsByString.clear();
+ attachedObjectsByInt.clear();
}
/**
@@ -191,193 +268,358 @@ public class ShaderState {
//
/**
- * Binds an attribute to the shader.
- * This must be done before the program is linked !
- * n name - 1 idx, where name is a uniq key
+ * Gets the cached location of a shader attribute.
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+ *
+ * @see #glBindAttribLocation(GL2ES2, int, String)
+ * @see #glBindAttribLocation(GL2ES2, int, GLArrayData)
+ * @see #glGetAttribLocation(GL2ES2, String)
+ * @see GL2ES2#glGetAttribLocation(int, String)
+ */
+ public int getAttribLocation(String name) {
+ Integer idx = (Integer) attribMap2Location.get(name);
+ return (null!=idx)?idx.intValue():-1;
+ }
+
+ /**
+ * Get the previous cached vertex attribute data.
+ *
+ * @return the GLArrayData object, null if not previously set.
*
- * @throws GLException is the program is already linked
+ * @see #bindAttribute(GLArrayData)
*
- * @see #glBindAttribLocation
- * @see javax.media.opengl.GL2ES2#glBindAttribLocation
- * @see #glGetAttribLocation
- * @see javax.media.opengl.GL2ES2#glGetAttribLocation
- * @see #getAttribLocation
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
* @see ShaderProgram#glReplaceShader
*/
- public void glBindAttribLocation(GL2ES2 gl, int index, String name) {
- if(null==shaderProgram) throw new GLException("No program is attached");
- if(shaderProgram.linked()) throw new GLException("Program is already linked");
- Integer idx = new Integer(index);
- if(!attribMap2Idx.containsKey(name)) {
- attribMap2Idx.put(name, idx);
- gl.glBindAttribLocation(shaderProgram.program(), index, name);
+ public GLArrayData getAttribute(String name) {
+ return (GLArrayData) vertexAttribMap2Data.get(name);
+ }
+
+ /**
+ * Bind the {@link GLArrayData} to this ShaderState.
+ * If an attribute location is cached (ie {@link #glBindAttribLocation(GL2ES2, int, String)})
+ * it is promoted to the {@link GLArrayData} instance.
+ * To bind a {@link GLArrayData} with a given location
+ * {@link #glBindAttribLocation(GL2ES2, int, GLArrayData)} shall be used.
+ *
+ * @param data the {@link GLArrayData} to be processed
+ * @see #glBindAttribLocation(GL2ES2, int, String)
+ * @see #getAttribute(String)
+ */
+ public void bindAttribute(GLArrayData data) {
+ final int location = getAttribLocation(data.getName());
+ if(0<=location) {
+ data.setLocation(location);
}
+ vertexAttribMap2Data.put(data.getName(), data);
+ }
+
+ /**
+ * Binds a shader attribute to a location.
+ * Multiple names can be bound to one location.
+ * The value will be cached and can be retrieved via {@link #getAttribLocation(String)}
+ * before or after linking.
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is already linked
+ *
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation(int, int, String)
+ * @see #glGetAttribLocation(GL2ES2, String)
+ * @see #getAttribLocation(String)
+ */
+ public void glBindAttribLocation(GL2ES2 gl, int location, String name) {
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(shaderProgram.linked()) throw new GLException("Program is already linked");
+ final Integer loc = new Integer(location);
+ attribMap2Location.put(name, loc);
+ gl.glBindAttribLocation(shaderProgram.program(), location, name);
}
/**
- * Gets the index of a shader attribute.
- * This must be done after the program is linked !
+ * Binds a shader {@link GLArrayData} attribute to a location.
+ * Multiple names can be bound to one location.
+ * The value will be cached and can be retrieved via {@link #getAttribLocation(String)}
+ * and {@link #getAttribute(String)}before or after linking.
+ * The {@link GLArrayData}'s location will be set as well.
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is already linked
+ *
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation(int, int, String)
+ * @see #glGetAttribLocation(GL2ES2, String)
+ * @see #getAttribLocation(String)
+ * @see #getAttribute(String)
+ */
+ public void glBindAttribLocation(GL2ES2 gl, int location, GLArrayData data) {
+ glBindAttribLocation(gl, location, data.getName());
+ data.setLocation(location);
+ vertexAttribMap2Data.put(data.getName(), data);
+ }
+
+ /**
+ * Gets the location of a shader attribute,
+ * either the cached value {@link #getAttribLocation(String)} if valid or
+ * the retrieved one {@link GL2ES2#glGetAttribLocation(int, String)}.
+ * In the latter case the value will be cached.
*
* @return -1 if there is no such attribute available,
* otherwise >= 0
- * @throws GLException is the program is not linked
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
*
- * @see #glBindAttribLocation
- * @see javax.media.opengl.GL2ES2#glBindAttribLocation
- * @see #glGetAttribLocation
- * @see javax.media.opengl.GL2ES2#glGetAttribLocation
- * @see #getAttribLocation
- * @see ShaderProgram#glReplaceShader
+ * @see #getAttribLocation(String)
+ * @see #glBindAttribLocation(GL2ES2, int, GLArrayData)
+ * @see #glBindAttribLocation(GL2ES2, int, String)
+ * @see GL2ES2#glGetAttribLocation(int, String)
*/
public int glGetAttribLocation(GL2ES2 gl, String name) {
- if(!shaderProgram.linked()) throw new GLException("Program is not linked");
- int index = getAttribLocation(name);
- if(0>index) {
- index = gl.glGetAttribLocation(shaderProgram.program(), name);
- if(0<=index) {
- Integer idx = new Integer(index);
- attribMap2Idx.put(name, idx);
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ int location = getAttribLocation(name);
+ if(0>location) {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ location = gl.glGetAttribLocation(shaderProgram.program(), name);
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ attribMap2Location.put(name, idx);
if(DEBUG) {
- System.err.println("Info: glGetAttribLocation: "+name+", loc: "+index);
+ System.err.println("Info: glGetAttribLocation: "+name+", loc: "+location);
}
} else if(verbose) {
- Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", index: "+index);
+ Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
tX.printStackTrace();
}
}
- return index;
+ return location;
}
- protected int getAttribLocation(String name) {
- Integer idx = (Integer) attribMap2Idx.get(name);
- return (null!=idx)?idx.intValue():-1;
+ /**
+ * Gets the location of a shader attribute,
+ * either the cached value {@link #getAttribLocation(String)} if valid or
+ * the retrieved one {@link GL2ES2#glGetAttribLocation(int, String)}.
+ * In the latter case the value will be cached.
+ * The {@link GLArrayData}'s location will be set as well.
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
+ *
+ * @see #getAttribLocation(String)
+ * @see #glBindAttribLocation(GL2ES2, int, GLArrayData)
+ * @see #glBindAttribLocation(GL2ES2, int, String)
+ * @see GL2ES2#glGetAttribLocation(int, String)
+ * @see #getAttribute(String)
+ */
+ public int glGetAttribLocation(GL2ES2 gl, GLArrayData data) {
+ int location = glGetAttribLocation(gl, data.getName());
+ data.setLocation(location);
+ vertexAttribMap2Data.put(data.getName(), data);
+ return location;
}
-
-
+
//
// Enabled Vertex Arrays and its data
//
/**
- * Enable a vertex attribute array
+ * @return true if the named attribute is enable
+ */
+ public final boolean isVertexAttribArrayEnabled(String name) {
+ return enabledVertexAttribArraySet.contains(name);
+ }
+
+ /**
+ * @return true if the {@link GLArrayData} attribute is enable
+ */
+ public final boolean isVertexAttribArrayEnabled(GLArrayData data) {
+ return isVertexAttribArrayEnabled(data.getName());
+ }
+
+ private boolean glEnableVertexAttribArray(GL2ES2 gl, String name, int location) {
+ enabledVertexAttribArraySet.add(name);
+ if(0>location) {
+ location = glGetAttribLocation(gl, name);
+ if(0>location) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
+ }
+ }
+ if(DEBUG) {
+ System.err.println("Info: glEnableVertexAttribArray: "+name+", loc: "+location);
+ }
+ gl.glEnableVertexAttribArray(location);
+ return true;
+ }
+
+ /**
+ * Enables a vertex attribute array.
+ *
+ * This method retrieves the the location via {@link #glGetAttribLocation(GL2ES2, GLArrayData)}
+ * hence {@link #glEnableVertexAttribArray(GL2ES2, GLArrayData)} shall be preferred.
*
* Even if the attribute is not found in the current shader,
- * it is stored in this state.
+ * it is marked enabled in this state.
*
* @return false, if the name is not found, otherwise true
*
- * @throws GLException if the program is not in use
- *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
+ *
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
* @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
*/
public boolean glEnableVertexAttribArray(GL2ES2 gl, String name) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- enabledVertexAttribArraySet.add(name);
- int index = glGetAttribLocation(gl, name);
- if(0>index) {
- if(verbose) {
- Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
- tX.printStackTrace();
- }
- return false;
- }
- if(DEBUG) {
- System.err.println("Info: glEnableVertexAttribArray: "+name+", loc: "+index);
- }
- gl.glEnableVertexAttribArray(index);
- return true;
- }
-
- public boolean isVertexAttribArrayEnabled(String name) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- return enabledVertexAttribArraySet.contains(name);
+ return glEnableVertexAttribArray(gl, name, -1);
}
+
/**
- * Disables a vertex attribute array
+ * Enables a vertex attribute array, usually invoked by {@link GLArrayDataEditable#enableBuffer(GL, boolean)}.
*
+ * This method uses the {@link GLArrayData}'s location if set
+ * and is the preferred alternative to {@link #glEnableVertexAttribArray(GL2ES2, String)}.
+ * If data location is unset it will be retrieved via {@link #glGetAttribLocation(GL2ES2, GLArrayData)} set
+ * and cached in this state.
+ *
* Even if the attribute is not found in the current shader,
- * it is removed from this state.
+ * it is marked enabled in this state.
*
* @return false, if the name is not found, otherwise true
*
- * @throws GLException if the program is not in use
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
*
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
* @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
+ * @see GLArrayDataEditable#enableBuffer(GL, boolean)
*/
- public boolean glDisableVertexAttribArray(GL2ES2 gl, String name) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ public boolean glEnableVertexAttribArray(GL2ES2 gl, GLArrayData data) {
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(0 > data.getLocation()) {
+ glGetAttribLocation(gl, data);
+ }
+ return glEnableVertexAttribArray(gl, data.getName(), data.getLocation());
+ }
+
+ private boolean glDisableVertexAttribArray(GL2ES2 gl, String name, int location) {
enabledVertexAttribArraySet.remove(name);
- int index = glGetAttribLocation(gl, name);
- if(0>index) {
- if(verbose) {
- Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
- tX.printStackTrace();
+ if(0>location) {
+ location = glGetAttribLocation(gl, name);
+ if(0>location) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
}
- return false;
}
if(DEBUG) {
System.err.println("Info: glDisableVertexAttribArray: "+name);
}
- gl.glDisableVertexAttribArray(index);
+ gl.glDisableVertexAttribArray(location);
return true;
}
-
+
/**
- * Set the vertex attribute data.
- * Enable the attribute, if it is not enabled yet.
+ * Disables a vertex attribute array
*
+ * This method retrieves the the location via {@link #glGetAttribLocation(GL2ES2, GLArrayData)}
+ * hence {@link #glDisableVertexAttribArray(GL2ES2, GLArrayData)} shall be preferred.
+ *
* Even if the attribute is not found in the current shader,
- * it is stored in this state.
+ * it is removed from this state enabled list.
*
- * @param data the GLArrayData's name must match the attributes one,
- * it's index will be set with the attribute's location,
- * if found.
+ * @return false, if the name is not found, otherwise true
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ */
+ public boolean glDisableVertexAttribArray(GL2ES2 gl, String name) {
+ return glDisableVertexAttribArray(gl, name, -1);
+ }
+
+ /**
+ * Disables a vertex attribute array
+ *
+ * This method uses the {@link GLArrayData}'s location if set
+ * and is the preferred alternative to {@link #glDisableVertexAttribArray(GL2ES2, String)}.
+ * If data location is unset it will be retrieved via {@link #glGetAttribLocation(GL2ES2, GLArrayData)} set
+ * and cached in this state.
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is removed from this state enabled list.
*
* @return false, if the name is not found, otherwise true
*
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ */
+ public boolean glDisableVertexAttribArray(GL2ES2 gl, GLArrayData data) {
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(0 > data.getLocation()) {
+ glGetAttribLocation(gl, data);
+ }
+ return glDisableVertexAttribArray(gl, data.getName(), data.getLocation());
+ }
+
+ /**
+ * Set the {@link GLArrayData} vertex attribute data.
+ *
+ * This method uses the {@link GLArrayData}'s location if set.
+ * If data location is unset it will be retrieved via {@link #glGetAttribLocation(GL2ES2, GLArrayData)}, set
+ * and cached in this state.
+ *
+ * Enables the attribute via {@link #glEnableVertexAttribArray(GL2ES2, GLArrayData)} , if it is not enabled yet.
+ *
+ * @return false, if the location could not be determined, otherwise true
+ *
* @throws GLException if the program is not in use
*
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
* @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
*/
public boolean glVertexAttribPointer(GL2ES2 gl, GLArrayData data) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ // if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ if(0 > data.getLocation()) {
+ glGetAttribLocation(gl, data);
+ }
if(!enabledVertexAttribArraySet.contains(data.getName())) {
- if(!glEnableVertexAttribArray(gl, data.getName())) {
+ if(!glEnableVertexAttribArray(gl, data)) {
if(verbose) {
Throwable tX = new Throwable("Info: glVertexAttribPointer: couldn't enable: "+data);
tX.printStackTrace();
}
}
}
- int index = getAttribLocation(data.getName());
- if(0>index) {
- if(verbose) {
- Throwable tX = new Throwable("Info: glVertexAttribPointer failed, no index for: "+data);
- tX.printStackTrace();
- }
- }
- data.setLocation(index);
- vertexAttribMap2Data.put(data.getName(), data);
- if(0<=index) {
+ if(0 <= data.getLocation()) {
// only pass the data, if the attribute exists in the current shader
if(DEBUG) {
System.err.println("Info: glVertexAttribPointer: "+data);
@@ -389,23 +631,6 @@ public class ShaderState {
}
/**
- * Get the vertex attribute data, previously set.
- *
- * @return the GLArrayData object, null if not previously set.
- *
- * @see #glEnableVertexAttribArray
- * @see #glDisableVertexAttribArray
- * @see #glVertexAttribPointer
- * @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
- */
- public GLArrayData getVertexAttribPointer(String name) {
- return (GLArrayData) vertexAttribMap2Data.get(name);
- }
-
- /**
* Releases all mapped vertex attribute data,
* disables all enabled attributes and loses all indices
*
@@ -423,8 +648,8 @@ public class ShaderState {
public void glReleaseAllVertexAttributes(GL2ES2 gl) {
if(null!=shaderProgram) {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- for(Iterator iter = vertexAttribMap2Data.keySet().iterator(); iter.hasNext(); ) {
- if(!glDisableVertexAttribArray(gl, (String) iter.next())) {
+ for(Iterator<GLArrayData> iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
+ if(!glDisableVertexAttribArray(gl, iter.next())) {
throw new GLException("Internal Error: mapped vertex attribute couldn't be disabled");
}
}
@@ -436,7 +661,7 @@ public class ShaderState {
}
vertexAttribMap2Data.clear();
enabledVertexAttribArraySet.clear();
- attribMap2Idx.clear();
+ attribMap2Location.clear();
}
/**
@@ -474,51 +699,40 @@ public class ShaderState {
}
/**
- * Reset all previously enabled mapped vertex attribute data,
- * incl enabling them
+ * Reset all previously enabled mapped vertex attribute data.
+ *
+ * Attribute data is bound to the GL state<br>
+ * Attribute location is bound to the program<br>
+ *
+ * However, since binding an attribute to a location via {@link #glBindAttribLocation(GL2ES2, int, GLArrayData)}
+ * <i>must</i> happen before linking <b>and</b> we try to promote the attributes to the new program,
+ * we have to gather the probably new location etc.
*
* @throws GLException is the program is not in use
*
- * @see #glEnableVertexAttribArray
- * @see #glDisableVertexAttribArray
- * @see #glVertexAttribPointer
- * @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
+ * @see #attachShaderProgram(GL2ES2, ShaderProgram)
*/
public void glResetAllVertexAttributes(GL2ES2 gl) {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- attribMap2Idx.clear();
-
- /**
- *
- for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
- glEnableVertexAttribArray(gl, (String) iter.next());
- }
- for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
- GLArrayData data = (GLArrayData) iter.next();
-
- ...
- } */
-
- for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ attribMap2Location.clear();
+
+ for(Iterator<GLArrayData> iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
+ GLArrayData data = iter.next();
+
// get new location ..
- String name = (String) iter.next();
+ String name = data.getName();
int loc = glGetAttribLocation(gl, name);
-
- // get & update data ..
- GLArrayData data = getVertexAttribPointer(name);
data.setLocation(loc);
- vertexAttribMap2Data.put(name, data);
if(0>loc) {
// not used in shader
continue;
}
-
- // enable attrib, VBO and pass location/data
- gl.glEnableVertexAttribArray(loc);
+
+ if(enabledVertexAttribArraySet.contains(name)) {
+ // enable attrib, VBO and pass location/data
+ gl.glEnableVertexAttribArray(loc);
+ }
if( data.isVBO() ) {
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, data.getVBOName());
@@ -548,22 +762,22 @@ public class ShaderState {
*/
protected int glGetUniformLocation(GL2ES2 gl, String name) {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- int index = getUniformLocation(name);
- if(0>index) {
- index = gl.glGetUniformLocation(shaderProgram.program(), name);
- if(0<=index) {
- Integer idx = new Integer(index);
- uniformMap2Idx.put(name, idx);
+ int location = getUniformLocation(name);
+ if(0>location) {
+ location = gl.glGetUniformLocation(shaderProgram.program(), name);
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ uniformMap2Location.put(name, idx);
} else if(verbose) {
- Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+index);
+ Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+location);
tX.printStackTrace();
}
}
- return index;
+ return location;
}
protected int getUniformLocation(String name) {
- Integer idx = (Integer) uniformMap2Idx.get(name);
+ Integer idx = (Integer) uniformMap2Location.get(name);
return (null!=idx)?idx.intValue():-1;
}
@@ -608,7 +822,7 @@ public class ShaderState {
* @return the GLUniformData object, null if not previously set.
*/
public GLUniformData getUniform(String name) {
- return (GLUniformData) uniformMap2Data.get(name);
+ return uniformMap2Data.get(name);
}
/**
@@ -619,58 +833,76 @@ public class ShaderState {
*/
public void glReleaseAllUniforms(GL2ES2 gl) {
uniformMap2Data.clear();
- uniformMap2Idx.clear();
+ uniformMap2Location.clear();
}
/**
* Reset all previously mapped uniform data
+ *
+ * Uniform data and location is bound to the program,
+ * hence both are updated here
*
* @throws GLException is the program is not in use
+ *
+ * @see #attachShaderProgram(GL2ES2, ShaderProgram)
*/
public void glResetAllUniforms(GL2ES2 gl) {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- uniformMap2Idx.clear();
- for(Iterator iter = uniformMap2Data.values().iterator(); iter.hasNext(); ) {
- glUniform(gl, (GLUniformData) iter.next());
+ uniformMap2Location.clear();
+ for(Iterator<GLUniformData> iter = uniformMap2Data.values().iterator(); iter.hasNext(); ) {
+ glUniform(gl, iter.next());
}
}
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append("ShaderState[");
- buf.append(shaderProgram.toString());
- buf.append(",EnabledStates: [");
+ public StringBuilder toString(StringBuilder sb) {
+ if(null==sb) {
+ sb = new StringBuilder();
+ }
+
+ sb.append("ShaderState[");
+ sb.append(shaderProgram.toString());
+ sb.append(",EnabledStates: [");
for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
- buf.append("\n ");
- buf.append((String)iter.next());
+ sb.append("\n ");
+ sb.append((String)iter.next());
}
- buf.append("], [");
- for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
- GLArrayData data = (GLArrayData) iter.next();
+ sb.append("], [");
+ for(Iterator<GLArrayData> iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
+ GLArrayData data = iter.next();
if(data.getLocation()>=0) {
- buf.append("\n ");
- buf.append(data);
+ sb.append("\n ");
+ sb.append(data);
}
}
- buf.append("], [");
- for(Iterator iter=uniformMap2Data.values().iterator(); iter.hasNext(); ) {
- GLUniformData data = (GLUniformData) iter.next();
+ sb.append("], [");
+ for(Iterator<GLUniformData> iter=uniformMap2Data.values().iterator(); iter.hasNext(); ) {
+ GLUniformData data = iter.next();
if(data.getLocation()>=0) {
- buf.append("\n ");
- buf.append(data);
+ sb.append("\n ");
+ sb.append(data);
}
}
- buf.append("]");
- return buf.toString();
+ sb.append("]");
+ return sb;
}
-
+
+ @Override
+ public String toString() {
+ return toString(null).toString();
+ }
+
protected boolean verbose = false;
protected ShaderProgram shaderProgram=null;
- protected HashMap attribMap2Idx = new HashMap();
- protected HashSet enabledVertexAttribArraySet = new HashSet();
- protected HashMap vertexAttribMap2Data = new HashMap();
- protected HashMap uniformMap2Idx = new HashMap();
- protected HashMap uniformMap2Data = new HashMap();
-
+
+ protected HashSet<String> enabledVertexAttribArraySet = new HashSet<String>();
+ protected HashMap<String, Integer> attribMap2Location = new HashMap<String, Integer>();
+ protected HashMap<String, GLArrayData> vertexAttribMap2Data = new HashMap<String, GLArrayData>();
+
+ protected HashMap<String, Integer> uniformMap2Location = new HashMap<String, Integer>();
+ protected HashMap<String, GLUniformData> uniformMap2Data = new HashMap<String, GLUniformData>();
+
+ private HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
+ private IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();
+ private boolean resetAllShaderData = false;
}