29package com.jogamp.opengl.util.glsl;
31import java.util.ArrayList;
32import java.util.HashMap;
33import java.util.Iterator;
35import com.jogamp.opengl.GL;
36import com.jogamp.opengl.GL2ES2;
37import com.jogamp.opengl.GLArrayData;
38import com.jogamp.opengl.GLException;
39import com.jogamp.opengl.GLUniformData;
41import jogamp.opengl.Debug;
43import com.jogamp.common.ExceptionUtils;
44import com.jogamp.common.os.Platform;
45import com.jogamp.common.util.PropertyAccess;
46import com.jogamp.opengl.util.GLArrayDataEditable;
61 public static final boolean DEBUG;
64 Debug.initSingleton();
65 DEBUG = PropertyAccess.isPropertyDefined(
"jogl.debug.GLSLState",
true);
79 return attachedObjectsByString.get(name);
88 public final Object
attachObject(
final String name,
final Object obj) {
89 return attachedObjectsByString.put(name, obj);
98 return attachedObjectsByString.remove(name);
109 if(
null==shaderProgram) {
throw new GLException(
"No program is attached"); }
111 if(shaderProgram.
linked()) {
113 if(resetAllShaderData) {
114 resetAllAttributes(gl);
115 resetAllUniforms(gl);
118 if(resetAllShaderData) {
119 setAllAttributes(gl);
121 if(!shaderProgram.
link(gl, System.err)) {
122 throw new GLException(
"could not link program: "+shaderProgram);
125 if(resetAllShaderData) {
126 resetAllUniforms(gl);
129 resetAllShaderData =
false;
136 return (
null!=shaderProgram)?shaderProgram.
linked():
false;
140 return (
null!=shaderProgram)?shaderProgram.
inUse():
false;
161 final int curId = (
null!=shaderProgram)?shaderProgram.id():-1;
162 final int newId = (
null!=prog)?prog.id():-1;
163 System.err.println(
"ShaderState: attachShaderProgram: "+curId+
" -> "+newId+
" (enable: "+enable+
")\n\t"+shaderProgram+
"\n\t"+prog);
165 ExceptionUtils.dumpStack(System.err);
168 if(
null!=shaderProgram) {
169 if(shaderProgram.
equals(prog)) {
175 System.err.println(
"ShaderState: attachShaderProgram: No switch, equal id: "+shaderProgram.id()+
", enabling "+enable);
179 if(shaderProgram.
inUse()) {
180 if(
null != prog && enable) {
187 resetAllShaderData =
true;
191 shaderProgram = prog;
193 if(
null!=shaderProgram) {
196 if(resetAllShaderData || enable) {
204 System.err.println(
"Info: attachShaderProgram: END");
220 attachedObjectsByString.clear();
231 release(gl,
false,
false,
false);
239 public synchronized void release(
final GL2ES2 gl,
final boolean destroyBoundAttributes,
final boolean destroyShaderProgram,
final boolean destroyShaderCode) {
240 if(
null!=shaderProgram && shaderProgram.
linked() ) {
243 if(destroyBoundAttributes) {
244 for(
final Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
245 iter.next().destroy(gl);
250 if(
null!=shaderProgram && destroyShaderProgram) {
251 shaderProgram.
release(gl, destroyShaderCode);
271 final Integer idx = activeAttribLocationMap.get(name);
272 return (
null!=idx)?idx.intValue():-1;
291 return activeAttribDataMap.get(name);
295 return attribute == activeAttribDataMap.get(attribute.
getName());
324 managedAttributes.add(managedAttributes.size(), attribute);
326 managedAttributes.remove(attribute);
332 return managedAttributes.contains(attribute);
349 if(
null==shaderProgram)
throw new GLException(
"No program is attached");
351 activeAttribLocationMap.put(name, Integer.valueOf(location));
371 if(
null==shaderProgram)
throw new GLException(
"No program is attached");
373 final String name = data.
getName();
374 activeAttribLocationMap.put(name, Integer.valueOf(location));
376 activeAttribDataMap.put(data.
getName(), data);
397 if(
null==shaderProgram)
throw new GLException(
"No program is attached");
403 activeAttribLocationMap.put(name, Integer.valueOf(location));
405 System.err.println(
"ShaderState: glGetAttribLocation: "+name+
", loc: "+location);
408 System.err.println(
"ShaderState: glGetAttribLocation failed, no location for: "+name+
", loc: "+location);
410 ExceptionUtils.dumpStack(System.err);
437 if(
null==shaderProgram)
throw new GLException(
"No program is attached");
438 final String name = data.
getName();
446 activeAttribLocationMap.put(name, Integer.valueOf(location));
448 System.err.println(
"ShaderState: glGetAttribLocation: "+name+
", loc: "+location);
451 System.err.println(
"ShaderState: glGetAttribLocation failed, no location for: "+name+
", loc: "+location);
453 ExceptionUtils.dumpStack(System.err);
457 activeAttribDataMap.put(data.
getName(), data);
469 final Boolean v = activedAttribEnabledMap.get(name);
470 return null != v && v.booleanValue();
480 private boolean enableVertexAttribArray(
final GL2ES2 gl,
final String name,
int location) {
481 activedAttribEnabledMap.put(name, Boolean.TRUE);
486 System.err.println(
"ShaderState: glEnableVertexAttribArray failed, no index for: "+name);
488 ExceptionUtils.dumpStack(System.err);
495 System.err.println(
"ShaderState: glEnableVertexAttribArray: "+name+
", loc: "+location);
520 return enableVertexAttribArray(gl, name, -1);
550 activeAttribDataMap.put(data.
getName(), data);
555 private boolean disableVertexAttribArray(
final GL2ES2 gl,
final String name,
int location) {
556 activedAttribEnabledMap.put(name, Boolean.FALSE);
561 System.err.println(
"ShaderState: glDisableVertexAttribArray failed, no index for: "+name);
563 ExceptionUtils.dumpStack(System.err);
570 System.err.println(
"ShaderState: glDisableVertexAttribArray: "+name);
596 return disableVertexAttribArray(gl, name, -1);
653 System.err.println(
"ShaderState: glVertexAttribPointer: "+data);
675 if(
null!=shaderProgram) {
676 for(
final Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
677 disableVertexAttribArray(gl, iter.next());
679 for(
final Iterator<String> iter = activedAttribEnabledMap.keySet().iterator(); iter.hasNext(); ) {
680 disableVertexAttribArray(gl, iter.next());
683 activeAttribDataMap.clear();
684 activedAttribEnabledMap.clear();
685 activeAttribLocationMap.clear();
686 managedAttributes.clear();
707 for(
final Iterator<String> iter = activedAttribEnabledMap.keySet().iterator(); iter.hasNext(); ) {
708 final String name = iter.next();
709 if(removeFromState) {
710 activedAttribEnabledMap.remove(name);
719 private final void relocateAttribute(
final GL2ES2 gl,
final GLArrayData attribute) {
721 final String name = attribute.
getName();
724 activeAttribLocationMap.put(name, Integer.valueOf(loc));
726 System.err.println(
"ShaderState: relocateAttribute: "+name+
", loc: "+loc);
733 if( attribute.
isVBO() ) {
764 private final void resetAllAttributes(
final GL2ES2 gl) {
765 if(!shaderProgram.
linked())
throw new GLException(
"Program is not linked");
766 activeAttribLocationMap.clear();
768 for(
int i=0; i<managedAttributes.size(); i++) {
769 managedAttributes.get(i).setLocation(-1);
771 for(
final Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
772 relocateAttribute(gl, iter.next());
776 private final void setAttribute(
final GL2ES2 gl,
final GLArrayData attribute) {
778 final String name = attribute.getName();
779 final int loc = attribute.getLocation();
786 gl.glEnableVertexAttribArray(loc);
789 if( attribute.isVBO() ) {
790 gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName());
791 gl.glVertexAttribPointer(attribute);
792 gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
794 gl.glVertexAttribPointer(attribute);
802 private final void setAllAttributes(
final GL2ES2 gl) {
803 for(
final Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
804 setAttribute(gl, iter.next());
819 final Integer idx = activeUniformLocationMap.get(name);
820 return (
null!=idx)?idx.intValue():-1;
847 return managedUniforms.contains(
uniform);
876 activeUniformLocationMap.put(name, Integer.valueOf(location));
878 System.err.println(
"ShaderState: glUniform failed, no location for: "+name+
", index: "+location);
880 ExceptionUtils.dumpStack(System.err);
909 final String name = data.
getName();
917 activeUniformLocationMap.put(name, Integer.valueOf(location));
919 System.err.println(
"ShaderState: glUniform failed, no location for: "+name+
", index: "+location);
921 ExceptionUtils.dumpStack(System.err);
925 activeUniformDataMap.put(name, data);
954 System.err.println(
"ShaderState: glUniform: "+data);
968 return activeUniformDataMap.get(name);
976 activeUniformDataMap.clear();
977 activeUniformLocationMap.clear();
978 managedUniforms.clear();
996 private final void resetAllUniforms(
final GL2ES2 gl) {
998 activeUniformLocationMap.clear();
999 for(
final Iterator<GLUniformData> iter = managedUniforms.iterator(); iter.hasNext(); ) {
1000 iter.next().setLocation(-1);
1002 for(
final Iterator<GLUniformData> iter = activeUniformDataMap.values().iterator(); iter.hasNext(); ) {
1007 activeUniformLocationMap.put(data.
getName(), Integer.valueOf(loc));
1009 System.err.println(
"ShaderState: resetAllUniforms: "+data);
1016 public StringBuilder
toString(StringBuilder sb,
final boolean alsoUnlocated) {
1018 sb =
new StringBuilder();
1021 sb.append(
"ShaderState[ ");
1023 sb.append(Platform.getNewline()).append(
" ");
1024 if(
null != shaderProgram) {
1027 sb.append(
"ShaderProgram: null");
1029 sb.append(Platform.getNewline()).append(
" enabledAttributes [");
1031 final Iterator<String> names = activedAttribEnabledMap.keySet().iterator();
1032 final Iterator<Boolean> values = activedAttribEnabledMap.values().iterator();
1033 while( names.hasNext() ) {
1034 sb.append(Platform.getNewline()).append(
" ").append(names.next()).append(
": ").append(values.next());
1037 sb.append(Platform.getNewline()).append(
" ],").append(
" activeAttributes [");
1038 for(
final Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
1041 sb.append(Platform.getNewline()).append(
" ").append(ad);
1044 sb.append(Platform.getNewline()).append(
" ],").append(
" managedAttributes [");
1045 for(
final Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
1048 sb.append(Platform.getNewline()).append(
" ").append(ad);
1051 sb.append(Platform.getNewline()).append(
" ],").append(
" activeUniforms [");
1052 for(
final Iterator<GLUniformData> iter=activeUniformDataMap.values().iterator(); iter.hasNext(); ) {
1055 sb.append(Platform.getNewline()).append(
" ").append(ud);
1058 sb.append(Platform.getNewline()).append(
" ],").append(
" managedUniforms [");
1059 for(
final Iterator<GLUniformData> iter = managedUniforms.iterator(); iter.hasNext(); ) {
1062 sb.append(Platform.getNewline()).append(
" ").append(ud);
1065 sb.append(Platform.getNewline()).append(
" ]").append(Platform.getNewline()).append(
"]");
1074 private boolean verbose =
DEBUG;
1077 private final HashMap<String, Boolean> activedAttribEnabledMap =
new HashMap<String, Boolean>();
1078 private final HashMap<String, Integer> activeAttribLocationMap =
new HashMap<String, Integer>();
1079 private final HashMap<String, GLArrayData> activeAttribDataMap =
new HashMap<String, GLArrayData>();
1080 private final ArrayList<GLArrayData> managedAttributes =
new ArrayList<GLArrayData>();
1082 private final HashMap<String, Integer> activeUniformLocationMap =
new HashMap<String, Integer>();
1083 private final HashMap<String, GLUniformData> activeUniformDataMap =
new HashMap<String, GLUniformData>();
1084 private final ArrayList<GLUniformData> managedUniforms =
new ArrayList<GLUniformData>();
1086 private final HashMap<String, Object> attachedObjectsByString =
new HashMap<String, Object>();
1087 private boolean resetAllShaderData =
false;
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
StringBuilder toString(StringBuilder sb)
int program()
Returns the shader program name, which is non zero if valid.
synchronized void useProgram(final GL2ES2 gl, boolean on)
synchronized void release(final GL2ES2 gl)
Detaches all shader codes and deletes the program, but leaves the shader code intact.
boolean equals(final Object obj)
synchronized void notifyNotInUse()
synchronized boolean link(final GL2ES2 gl, final PrintStream verboseOut)
Links the shader code to the program.
ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...
void ownAttribute(final GLArrayData attribute, final boolean own)
Binds or unbinds the GLArrayData lifecycle to this ShaderState.
void releaseAllUniforms(final GL2ES2 gl)
Releases all mapped uniform data and loses all indices.
int getAttribLocation(final GL2ES2 gl, final String name)
Gets the location of a shader attribute with given name.
boolean ownsAttribute(final GLArrayData attribute)
boolean vertexAttribPointer(final GL2ES2 gl, final GLArrayData data)
Set the GLArrayData vertex attribute data, if it's location is valid, i.e.
final int getUniformLocation(final GL2ES2 gl, final String name)
Gets the location of a shader uniform with given name.
int getCachedAttribLocation(final String name)
Gets the cached location of a shader attribute.
void setVerbose(final boolean v)
boolean ownsUniform(final GLUniformData uniform)
int getAttribLocation(final GL2ES2 gl, final GLArrayData data)
Validates and returns the location of a shader attribute.
final Object getAttachedObject(final String name)
Returns the attached user object for the given name to this ShaderState.
synchronized void useProgram(final GL2ES2 gl, final boolean on)
Turns the shader program on or off.
synchronized boolean attachShaderProgram(final GL2ES2 gl, final ShaderProgram prog, final boolean enable)
Attach or switch a shader program.
GLUniformData getUniform(final String name)
Get the uniform data, previously set.
boolean disableVertexAttribArray(final GL2ES2 gl, final GLArrayData data)
Disables a vertex attribute array.
void bindAttribLocation(final GL2ES2 gl, final int location, final GLArrayData data)
Binds a shader GLArrayData attribute to a location.
void disableAllVertexAttributeArrays(final GL2ES2 gl, final boolean removeFromState)
Disables all vertex attribute arrays.
boolean isActiveAttribute(final GLArrayData attribute)
StringBuilder toString(StringBuilder sb, final boolean alsoUnlocated)
final Object detachObject(final String name)
final Object attachObject(final String name, final Object obj)
Attach user object for the given name to this ShaderState.
synchronized void destroy(final GL2ES2 gl)
Calls release(gl, true, true, true).
synchronized void releaseAllData(final GL2ES2 gl)
Calls release(gl, false, false, false).
boolean uniform(final GL2ES2 gl, final GLUniformData data)
Set the uniform data, if it's location is valid, i.e.
void releaseAllAttributes(final GL2ES2 gl)
Releases all mapped vertex attribute data, disables all enabled attributes and loses all indices.
boolean disableVertexAttribArray(final GL2ES2 gl, final String name)
Disables a vertex attribute array.
final boolean isVertexAttribArrayEnabled(final String name)
static final boolean DEBUG
final boolean isVertexAttribArrayEnabled(final GLArrayData data)
boolean enableVertexAttribArray(final GL2ES2 gl, final GLArrayData data)
Enables a vertex attribute array, usually invoked by GLArrayDataEditable#enableBuffer(GL,...
boolean enableVertexAttribArray(final GL2ES2 gl, final String name)
Enables a vertex attribute array.
final int getCachedUniformLocation(final String name)
Gets the cached location of the shader uniform.
int getUniformLocation(final GL2ES2 gl, final GLUniformData data)
Validates and returns the location of a shader uniform.
synchronized void release(final GL2ES2 gl, final boolean destroyBoundAttributes, final boolean destroyShaderProgram, final boolean destroyShaderCode)
ShaderProgram shaderProgram()
GLArrayData getAttribute(final String name)
Get the previous cached vertex attribute data.
void ownUniform(final GLUniformData uniform)
Bind the GLUniform lifecycle to this ShaderState.
void bindAttribLocation(final GL2ES2 gl, final int location, final String name)
Binds a shader attribute to a location.
void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer_buffer_offset)
Entry point to C language function: void {@native glVertexAttribPointer}(GLuint index,...
void glBindAttribLocation(int program, int index, String name)
Entry point to C language function: void {@native glBindAttribLocation}(GLuint program,...
void glEnableVertexAttribArray(int index)
Entry point to C language function: void {@native glEnableVertexAttribArray}(GLuint index) Part of...
int glGetAttribLocation(int program, String name)
Entry point to C language function: GLint {@native glGetAttribLocation}(GLuint program,...
void glUniform(GLUniformData data)
int glGetUniformLocation(int program, String name)
Entry point to C language function: GLint {@native glGetUniformLocation}(GLuint program,...
void glDisableVertexAttribArray(int index)
Entry point to C language function: void {@native glDisableVertexAttribArray}(GLuint index) Part o...
The total number of bytes hold by the referenced buffer is: getComponentSize()* getComponentNumber() ...
int setLocation(int v)
Sets the given location of the shader attribute.
boolean isVBO()
Determines whether the data is server side (VBO) and enabled, or a client side array (false).
String getName()
The name of the reflecting shader array attribute.
int getVBOName()
The VBO name or 0 if not a VBO.
void associate(Object obj, boolean enable)
Implementation and type dependent object association.
int getLocation()
Returns the shader attribute location for this name, -1 if not yet determined.
void glBindBuffer(int target, int buffer)
Entry point to C language function: void {@native glBindBuffer}(GLenum target, GLuint buffer) Part...
static final int GL_ARRAY_BUFFER
GL_VERSION_1_5, GL_ES_VERSION_2_0, GL_VERSION_ES_1_0, GL_ARB_vertex_buffer_object Alias for: GL_ARRAY...