aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java55
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java29
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java76
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java281
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java111
5 files changed, 438 insertions, 114 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index 88cb3303f..e0bbbc33c 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.opengl.util;
@@ -120,6 +147,17 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
return adc;
}
+ @Override
+ public void associate(Object obj, boolean enable) {
+ if(obj instanceof ShaderState) {
+ if(enable) {
+ shaderState = (ShaderState)obj;
+ } else {
+ shaderState = null;
+ }
+ }
+ }
+
//
// Data read access
//
@@ -157,7 +195,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
seal(seal);
enableBuffer(gl, seal);
}
-
+
@Override
public void enableBuffer(GL gl, boolean enable) {
if( enableBufferAlways || bufferEnabled != enable ) {
@@ -166,16 +204,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
// init/generate VBO name if not done yet
init_vbo(gl);
}
- final Object ext;
- if(usesGLSL) {
- ext = ShaderState.getShaderState(gl);
- if(null == ext) {
- throw new GLException("A ShaderState must be bound to the GL context, use 'ShaderState.setShaderState(gl)'");
- }
- } else {
- ext = null;
- }
- glArrayHandler.enableState(gl, enable, ext);
+ glArrayHandler.enableState(gl, enable, usesGLSL ? shaderState : null);
bufferEnabled = enable;
}
}
@@ -297,6 +326,8 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
", index "+index+
", location "+location+
", isVertexAttribute "+isVertexAttribute+
+ ", usesGLSL "+usesGLSL+
+ ", usesShaderState "+(null!=shaderState)+
", dataType 0x"+Integer.toHexString(componentType)+
", bufferClazz "+componentClazz+
", elements "+getElementCount()+
@@ -421,5 +452,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
protected GLArrayHandler glArrayHandler;
protected boolean usesGLSL;
+ protected ShaderState shaderState;
+
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
index c9dd98751..7e7d27b36 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.opengl.util;
@@ -332,6 +359,8 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
", index "+index+
", location "+location+
", isVertexAttribute "+isVertexAttribute+
+ ", usesGLSL "+usesGLSL+
+ ", usesShaderState "+(null!=shaderState)+
", dataType 0x"+Integer.toHexString(componentType)+
", bufferClazz "+componentClazz+
", elements "+getElementCount()+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index f4a197be1..7d08ad08f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.opengl.util;
@@ -97,53 +124,91 @@ public class GLArrayDataWrapper implements GLArrayData {
return glp.isValidArrayDataType(getIndex(), getComponentCount(), getComponentType(), isVertexAttribute(), throwException);
}
+ @Override
+ public void associate(Object obj, boolean enable) {
+ // nop
+ }
+
//
// Data read access
//
+ @Override
public final boolean isVertexAttribute() { return isVertexAttribute; }
+ @Override
public final int getIndex() { return index; }
+ @Override
public final int getLocation() { return location; }
- public final void setLocation(int v) { location = v; }
+ @Override
+ public final int setLocation(int v) { location = v; return location; }
+ @Override
+ public final int setLocation(GL2ES2 gl, int program) {
+ location = gl.glGetAttribLocation(program, name);
+ return location;
+ }
+
+ @Override
+ public final int setLocation(GL2ES2 gl, int program, int location) {
+ this.location = location;
+ gl.glBindAttribLocation(program, location, name);
+ return location;
+ }
+
+ @Override
public final String getName() { return name; }
+ @Override
public final long getVBOOffset() { return vboEnabled?vboOffset:0; }
+ @Override
public final int getVBOName() { return vboEnabled?vboName:0; }
+ @Override
public final boolean isVBO() { return vboEnabled; }
+ @Override
public final int getVBOUsage() { return vboEnabled?vboUsage:0; }
+ @Override
public final int getVBOTarget() { return vboEnabled?vboTarget:0; }
+ @Override
public final Buffer getBuffer() { return buffer; }
+ @Override
public final int getComponentCount() { return components; }
+ @Override
public final int getComponentType() { return componentType; }
+ @Override
public final int getComponentSizeInBytes() { return componentByteSize; }
+ @Override
public final int getElementCount() {
if(null==buffer) return 0;
return ( buffer.position()==0 ) ? ( buffer.limit() / components ) : ( buffer.position() / components ) ;
}
+
+ @Override
public final int getSizeInBytes() {
if(null==buffer) return 0;
return ( buffer.position()==0 ) ? ( buffer.limit() * componentByteSize ) : ( buffer.position() * componentByteSize ) ;
}
+ @Override
public final boolean getNormalized() { return normalized; }
+ @Override
public final int getStride() { return strideB; }
- public final Class getBufferClass() { return componentClazz; }
+ public final Class<?> getBufferClass() { return componentClazz; }
+ @Override
public void destroy(GL gl) {
buffer = null;
vboName=0;
@@ -152,6 +217,7 @@ public class GLArrayDataWrapper implements GLArrayData {
alive = false;
}
+ @Override
public String toString() {
return "GLArrayDataWrapper["+name+
", index "+index+
@@ -172,7 +238,7 @@ public class GLArrayDataWrapper implements GLArrayData {
"]";
}
- public static final Class getBufferClass(int dataType) {
+ public static final Class<?> getBufferClass(int dataType) {
switch(dataType) {
case GL.GL_BYTE:
case GL.GL_UNSIGNED_BYTE:
@@ -189,6 +255,7 @@ public class GLArrayDataWrapper implements GLArrayData {
}
}
+ @Override
public void setName(String newName) {
location = -1;
name = newName;
@@ -310,14 +377,13 @@ public class GLArrayDataWrapper implements GLArrayData {
protected String name;
protected int components;
protected int componentType;
- protected Class componentClazz;
+ protected Class<?> componentClazz;
protected int componentByteSize;
protected boolean normalized;
protected int strideB; // stride in bytes
protected int strideL; // stride in logical components
protected Buffer buffer;
protected boolean isVertexAttribute;
-
protected long vboOffset;
protected int vboName;
protected boolean vboEnabled;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index f01896b96..27ce7d8ec 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -35,7 +35,7 @@ import com.jogamp.opengl.util.glsl.ShaderState;
* via {@link #glEnd(GL, boolean) glEnd(gl, false)} for deferred rendering via {@link #draw(GL, boolean)}.
* </p>
* <a name="storageDetails"><h5>Buffer storage and it's creation via {@link #createFixed(int, int, int, int, int, int, int, int, int, int) createFixed(..)}
- * and {@link #createGLSL(int, int, int, int, int, int, int, int, int, int) createGLSL(..)}</h5></a>
+ * and {@link #createGLSL(int, int, int, int, int, int, int, int, int, int, ShaderState) createGLSL(..)}</h5></a>
* <p>
* If unsure whether <i>colors</i>, <i>normals</i> and <i>textures</i> will be used,
* simply add them with an expected component count.
@@ -82,13 +82,11 @@ public class ImmModeSink {
int glBufferUsage) {
return new ImmModeSink(initialElementCount,
vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
- false, glBufferUsage);
+ false, glBufferUsage, null, 0);
}
/**
- * Uses a GL2ES2 GLSL shader immediate mode sink.
- * To issue the draw() command,
- * a ShaderState must be current, using ShaderState.glUseProgram().
+ * Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given ShaderState.
* <p>
* See <a href="#storageDetails"> buffer storage details</a>.
* </p>
@@ -104,7 +102,7 @@ public class ImmModeSink {
* @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
* @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
* set to <code>0</code> for no VBO usage
- *
+ * @param st ShaderState to locate the vertex attributes
* @see #draw(GL, boolean)
* @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
* @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
@@ -114,12 +112,45 @@ public class ImmModeSink {
int cComps, int cDataType,
int nComps, int nDataType,
int tComps, int tDataType,
- int glBufferUsage) {
+ int glBufferUsage, ShaderState st) {
return new ImmModeSink(initialElementCount,
vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
- true, glBufferUsage);
+ true, glBufferUsage, st, 0);
}
+ /**
+ * Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given shader-program.
+ * <p>
+ * See <a href="#storageDetails"> buffer storage details</a>.
+ * </p>
+ *
+ * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
+ * @param vComps mandatory vertex component count, should be 2, 3 or 4.
+ * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
+ * @param cComps optional color component count, may be 0, 3 or 4
+ * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
+ * @param nComps optional normal component count, may be 0, 3 or 4
+ * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
+ * @param tComps optional texture-coordinate component count, may be 0, 2 or 3
+ * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
+ * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
+ * set to <code>0</code> for no VBO usage
+ * @param shaderProgram shader-program name to locate the vertex attributes
+ * @see #draw(GL, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
+ */
+ public static ImmModeSink createGLSL(int initialElementCount,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType,
+ int glBufferUsage, int shaderProgram) {
+ return new ImmModeSink(initialElementCount,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ true, glBufferUsage, null, shaderProgram);
+ }
+
public void destroy(GL gl) {
destroyList(gl);
@@ -330,10 +361,10 @@ public class ImmModeSink {
int cComps, int cDataType,
int nComps, int nDataType,
int tComps, int tDataType,
- boolean useGLSL, int glBufferUsage) {
- vboSet = new VBOSet(initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
- useGLSL, glBufferUsage);
+ boolean useGLSL, int glBufferUsage, ShaderState st, int shaderProgram) {
+ vboSet = new VBOSet(initialElementCount,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ useGLSL, glBufferUsage, st, shaderProgram);
this.vboSetList = new ArrayList<VBOSet>();
}
@@ -349,7 +380,7 @@ public class ImmModeSink {
* Sets the additional element count if buffer resize is required,
* defaults to <code>initialElementCount</code> of factory method.
* @see #createFixed(int, int, int, int, int, int, int, int, int, int)
- * @see #createGLSL(int, int, int, int, int, int, int, int, int, int)
+ * @see #createGLSL(int, int, int, int, int, int, int, int, int, int, ShaderState)
*/
public void setResizeElementCount(int v) { vboSet.setResizeElementCount(v); }
@@ -369,9 +400,19 @@ public class ImmModeSink {
int cComps, int cDataType,
int nComps, int nDataType,
int tComps, int tDataType,
- boolean useGLSL, int glBufferUsage) {
+ boolean useGLSL, int glBufferUsage, ShaderState st, int shaderProgram) {
+ // final ..
this.glBufferUsage=glBufferUsage;
this.initialElementCount=initialElementCount;
+ this.useVBO = 0 != glBufferUsage;
+ this.useGLSL=useGLSL;
+ this.shaderState = st;
+ this.shaderProgram = shaderProgram;
+
+ if(useGLSL && null == shaderState && 0 == shaderProgram) {
+ throw new IllegalArgumentException("Using GLSL but neither a valid shader-program nor ShaderState has been passed!");
+ }
+ // variable ..
this.resizeElementCount=initialElementCount;
this.vDataType=vDataType;
this.vDataTypeSigned=GLBuffers.isSignedGLType(vDataType);
@@ -389,8 +430,6 @@ public class ImmModeSink {
this.tDataTypeSigned=GLBuffers.isSignedGLType(tDataType);
this.tComps=tComps;
this.tCompsBytes=tComps * GLBuffers.sizeOfGLType(tDataType);
- this.useGLSL=useGLSL;
- this.useVBO = 0 != glBufferUsage;
this.vboName = 0;
this.vCount=0;
@@ -414,6 +453,7 @@ public class ImmModeSink {
this.bufferEnabled=false;
this.bufferWritten=false;
this.bufferWrittenOnce=false;
+ this.glslLocationSet = false;
}
protected int getResizeElementCount() { return resizeElementCount; }
@@ -423,7 +463,8 @@ public class ImmModeSink {
protected final VBOSet regenerate(GL gl) {
return new VBOSet(initialElementCount, vComps,
- vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL, glBufferUsage);
+ vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ useGLSL, glBufferUsage, shaderState, shaderProgram);
}
protected void checkSeal(boolean test) throws GLException {
@@ -439,10 +480,27 @@ public class ImmModeSink {
}
}
+ private boolean usingShaderProgram = false;
+
+ protected void useShaderProgram(GL2ES2 gl, boolean force) {
+ if( force || !usingShaderProgram ) {
+ if(null != shaderState) {
+ shaderState.useProgram(gl, true);
+ } else /* if( 0 != shaderProgram) */ {
+ gl.glUseProgram(shaderProgram);
+ }
+ usingShaderProgram = true;
+ }
+ }
+
protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i)
{
enableBuffer(gl, true);
-
+
+ if(null != shaderState || 0 != shaderProgram) {
+ useShaderProgram(gl.getGL2ES2(), false);
+ }
+
if(DEBUG_DRAW) {
System.err.println("ImmModeSink.draw["+i+"].0 (disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
}
@@ -788,6 +846,51 @@ public class ImmModeSink {
}
}
+ public void setShaderProgram(int program) {
+ if(null == shaderState && 0 == program) {
+ throw new IllegalArgumentException("Not allowed to zero shader program if no ShaderState is set");
+ }
+ shaderProgram = program;
+ glslLocationSet = false; // enforce location reset!
+ }
+
+ /**
+ * @param gl
+ * @return true if all locations for all used arrays are found (min 1 array), otherwise false.
+ * Also sets 'glslLocationSet' to the return value!
+ */
+ private boolean resetGLSLArrayLocation(GL2ES2 gl) {
+ int iA = 0;
+ int iL = 0;
+
+ if(null != vArrayData) {
+ iA++;
+ if( vArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ if(null != cArrayData) {
+ iA++;
+ if( cArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ if(null != nArrayData) {
+ iA++;
+ if( nArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ if(null != tArrayData) {
+ iA++;
+ if( tArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ glslLocationSet = iA == iL;
+ return glslLocationSet;
+ }
+
public void destroy(GL gl) {
reset(gl);
@@ -868,8 +971,13 @@ public class ImmModeSink {
checkSeal(true);
}
bufferEnabled = enable;
- if(useGLSL) {
- enableBufferGLSL(gl, enable);
+ if(useGLSL) {
+ useShaderProgram(gl.getGL2ES2(), true);
+ if(null != shaderState) {
+ enableBufferGLSLShaderState(gl, enable);
+ } else {
+ enableBufferGLSLSimple(gl, enable);
+ }
} else {
enableBufferFixed(gl, enable);
}
@@ -901,7 +1009,7 @@ public class ImmModeSink {
}
}
- public void enableBufferFixed(GL gl, boolean enable) {
+ private void enableBufferFixed(GL gl, boolean enable) {
GL2ES1 glf = gl.getGL2ES1();
final boolean useV = vComps>0 && vElems>0 ;
@@ -969,11 +1077,75 @@ public class ImmModeSink {
}
}
- public void enableBufferGLSL(GL gl, boolean enable) {
- ShaderState st = ShaderState.getShaderState(gl);
- if(null==st) {
- throw new GLException("No ShaderState in "+gl);
- }
+ private void enableBufferGLSLShaderState(GL gl, boolean enable) {
+ GL2ES2 glsl = gl.getGL2ES2();
+
+ final boolean useV = vComps>0 && vElems>0 ;
+ final boolean useC = cComps>0 && cElems>0 ;
+ final boolean useN = nComps>0 && nElems>0 ;
+ final boolean useT = tComps>0 && tElems>0 ;
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableGLSL.A.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ }
+
+ if(enable) {
+ if(useVBO) {
+ if(0 == vboName) {
+ throw new InternalError("Using VBO but no vboName");
+ }
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+ if(!bufferWritten) {
+ writeBuffer(gl);
+ }
+ }
+ bufferWritten=true;
+ }
+
+ if(useV) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, vArrayData);
+ shaderState.vertexAttribPointer(glsl, vArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, vArrayData);
+ }
+ }
+ if(useC) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, cArrayData);
+ shaderState.vertexAttribPointer(glsl, cArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, cArrayData);
+ }
+ }
+ if(useN) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, nArrayData);
+ shaderState.vertexAttribPointer(glsl, nArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, nArrayData);
+ }
+ }
+ if(useT) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, tArrayData);
+ shaderState.vertexAttribPointer(glsl, tArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, tArrayData);
+ }
+ }
+ glslLocationSet = true; // ShaderState does set the location implicit
+
+ if(enable && useVBO) {
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableGLSL.A.X ");
+ }
+ }
+
+ private void enableBufferGLSLSimple(GL gl, boolean enable) {
GL2ES2 glsl = gl.getGL2ES2();
final boolean useV = vComps>0 && vElems>0 ;
@@ -982,7 +1154,20 @@ public class ImmModeSink {
final boolean useT = tComps>0 && tElems>0 ;
if(DEBUG_DRAW) {
- System.err.println("ImmModeSink.enableGLSL.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ System.err.println("ImmModeSink.enableGLSL.B.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ }
+
+ if(!glslLocationSet) {
+ if( !resetGLSLArrayLocation(glsl) ) {
+ if(DEBUG_DRAW) {
+ final int vLoc = null != vArrayData ? vArrayData.getLocation() : -1;
+ final int cLoc = null != cArrayData ? cArrayData.getLocation() : -1;
+ final int nLoc = null != nArrayData ? nArrayData.getLocation() : -1;
+ final int tLoc = null != tArrayData ? tArrayData.getLocation() : -1;
+ System.err.println("ImmModeSink.enableGLSL.B.X attribute locations in shader program "+shaderProgram+", incomplete ["+vLoc+", "+cLoc+", "+nLoc+", "+tLoc+"] - glslLocationSet "+glslLocationSet);
+ }
+ return;
+ }
}
if(enable) {
@@ -1000,34 +1185,34 @@ public class ImmModeSink {
if(useV) {
if(enable) {
- st.enableVertexAttribArray(glsl, vArrayData);
- st.vertexAttribPointer(glsl, vArrayData);
+ glsl.glEnableVertexAttribArray(vArrayData.getLocation());
+ glsl.glVertexAttribPointer(vArrayData);
} else {
- st.disableVertexAttribArray(glsl, vArrayData);
+ glsl.glDisableVertexAttribArray(vArrayData.getLocation());
}
}
if(useC) {
if(enable) {
- st.enableVertexAttribArray(glsl, cArrayData);
- st.vertexAttribPointer(glsl, cArrayData);
+ glsl.glEnableVertexAttribArray(cArrayData.getLocation());
+ glsl.glVertexAttribPointer(cArrayData);
} else {
- st.disableVertexAttribArray(glsl, cArrayData);
+ glsl.glDisableVertexAttribArray(cArrayData.getLocation());
}
}
if(useN) {
if(enable) {
- st.enableVertexAttribArray(glsl, nArrayData);
- st.vertexAttribPointer(glsl, nArrayData);
+ glsl.glEnableVertexAttribArray(nArrayData.getLocation());
+ glsl.glVertexAttribPointer(nArrayData);
} else {
- st.disableVertexAttribArray(glsl, nArrayData);
+ glsl.glDisableVertexAttribArray(nArrayData.getLocation());
}
}
if(useT) {
if(enable) {
- st.enableVertexAttribArray(glsl, tArrayData);
- st.vertexAttribPointer(glsl, tArrayData);
+ glsl.glEnableVertexAttribArray(tArrayData.getLocation());
+ glsl.glVertexAttribPointer(tArrayData);
} else {
- st.disableVertexAttribArray(glsl, tArrayData);
+ glsl.glDisableVertexAttribArray(tArrayData.getLocation());
}
}
@@ -1036,11 +1221,16 @@ public class ImmModeSink {
}
if(DEBUG_DRAW) {
- System.err.println("ImmModeSink.enableGLSL.X ");
+ System.err.println("ImmModeSink.enableGLSL.B.X ");
}
}
-
+
public String toString() {
+ final String glslS = useGLSL ?
+ ", useShaderState "+(null!=shaderState)+
+ ", shaderProgram "+shaderProgram+
+ ", glslLocationSet "+glslLocationSet : "";
+
return "VBOSet[mode "+mode+
", modeOrig "+modeOrig+
", use/count "+getElemUseCountStr()+
@@ -1049,6 +1239,8 @@ public class ImmModeSink {
", bufferEnabled "+bufferEnabled+
", bufferWritten "+bufferWritten+" (once "+bufferWrittenOnce+")"+
", useVBO "+useVBO+", vboName "+vboName+
+ ", useGLSL "+useGLSL+
+ glslS+
",\n\t"+vArrayData+
",\n\t"+cArrayData+
",\n\t"+nArrayData+
@@ -1264,7 +1456,9 @@ public class ImmModeSink {
}
final private int glBufferUsage, initialElementCount;
- final private boolean useVBO;
+ final private boolean useVBO, useGLSL;
+ final private ShaderState shaderState;
+ private int shaderProgram;
private int mode, modeOrig, resizeElementCount;
private ByteBuffer buffer;
@@ -1286,8 +1480,9 @@ public class ImmModeSink {
private Buffer vertexArray, colorArray, normalArray, textCoordArray;
private GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
- private boolean sealed, sealedGL, useGLSL;
+ private boolean sealed, sealedGL;
private boolean bufferEnabled, bufferWritten, bufferWrittenOnce;
+ private boolean glslLocationSet;
}
}
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 ff8982ddf..9d71ee276 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -35,7 +35,6 @@ import java.util.Iterator;
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;
@@ -58,7 +57,6 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
*/
public class ShaderState {
public static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLSLState", true);
- private static final String currentStateKey = "jogamp.opengl.glsl.ShaderState" ;
public ShaderState() {
}
@@ -68,46 +66,6 @@ public class ShaderState {
public void setVerbose(boolean v) { verbose = DEBUG || v; }
/**
- * Fetches the current shader state from this thread (TLS) current GLContext
- *
- * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#setShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
- */
- public static ShaderState getCurrentShaderState() {
- return getShaderState(GLContext.getCurrentGL());
- }
-
- /**
- * Gets the shader state attached to the GL object's GLContext
- *
- * @param gl the GL object referencing the GLContext
- *
- * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#setShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
- */
- public static ShaderState getShaderState(GL gl) {
- return (ShaderState) gl.getContext().getAttachedObject(currentStateKey);
- }
-
- /**
- * Attaches the shader state to the GL object's GLContext
- *
- * @param gl the GL object referencing the GLContext
- *
- * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#setShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
- */
- public final ShaderState setShaderState(GL gl) {
- return (ShaderState) gl.getContext().attachObject(currentStateKey, this);
- }
-
- /**
* Returns the attached user object for the given name to this ShaderState.
*/
public final Object getAttachedObject(String name) {
@@ -135,19 +93,14 @@ public class ShaderState {
/**
* 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
*
* @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
public synchronized void useProgram(GL2ES2 gl, boolean on) throws GLException {
if(null==shaderProgram) { throw new GLException("No program is attached"); }
if(on) {
- setShaderState(gl);
if(shaderProgram.linked()) {
shaderProgram.useProgram(gl, true);
if(resetAllShaderData) {
@@ -332,6 +285,10 @@ public class ShaderState {
return activeAttribDataMap.get(name);
}
+ public boolean isActiveAttribute(GLArrayData attribute) {
+ return attribute == activeAttribDataMap.get(attribute.getName());
+ }
+
/**
* Binds or unbinds the {@link GLArrayData} lifecycle to this ShaderState.
*
@@ -343,11 +300,14 @@ public class ShaderState {
*
* <p>The data will not be transfered to the GPU, use {@link #vertexAttribPointer(GL2ES2, GLArrayData)} additionally.</p>
*
+ * <p>The data will also be {@link GLArrayData#associate(Object, boolean) associated} with this ShaderState.</p>
+ *
* @param attribute the {@link GLArrayData} which lifecycle shall be managed
* @param own true if <i>owning</i> shall be performs, false if <i>disowning</i>.
*
* @see #bindAttribLocation(GL2ES2, int, String)
* @see #getAttribute(String)
+ * @see GLArrayData#associate(Object, boolean)
*/
public void ownAttribute(GLArrayData attribute, boolean own) {
if(own) {
@@ -359,6 +319,7 @@ public class ShaderState {
} else {
managedAttributes.remove(attribute);
}
+ attribute.associate(this, own);
}
public boolean ownsAttribute(GLArrayData attribute) {
@@ -402,8 +363,12 @@ public class ShaderState {
* @see #getAttribute(String)
*/
public void bindAttribLocation(GL2ES2 gl, int location, GLArrayData data) {
- bindAttribLocation(gl, location, data.getName());
- data.setLocation(location);
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(shaderProgram.linked()) throw new GLException("Program is already linked");
+ final String name = data.getName();
+ final Integer loc = new Integer(location);
+ activeAttribLocationMap.put(name, loc);
+ data.setLocation(gl, shaderProgram.program(), location);
activeAttribDataMap.put(data.getName(), data);
}
@@ -465,8 +430,27 @@ public class ShaderState {
* @see #getAttribute(String)
*/
public int getAttribLocation(GL2ES2 gl, GLArrayData data) {
- int location = getAttribLocation(gl, data.getName());
- data.setLocation(location);
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ final String name = data.getName();
+ int location = getCachedAttribLocation(name);
+ if(0<=location) {
+ data.setLocation(location);
+ } else {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ location = data.setLocation(gl, shaderProgram.program());
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ activeAttribLocationMap.put(name, idx);
+ if(DEBUG) {
+ System.err.println("ShaderState: glGetAttribLocation: "+name+", loc: "+location);
+ }
+ } else if(verbose) {
+ System.err.println("ShaderState: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ }
+ }
activeAttribDataMap.put(data.getName(), data);
return location;
}
@@ -873,6 +857,7 @@ public class ShaderState {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
int location = getCachedUniformLocation(name);
if(0>location) {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
location = gl.glGetUniformLocation(shaderProgram.program(), name);
if(0<=location) {
Integer idx = new Integer(location);
@@ -886,7 +871,7 @@ public class ShaderState {
}
return location;
}
-
+
/**
* Validates and returns the location of a shader uniform.<br>
* Uses either the cached value {@link #getCachedUniformLocation(String)} if valid,
@@ -908,9 +893,25 @@ public class ShaderState {
* @see ShaderProgram#glReplaceShader
*/
public int getUniformLocation(GL2ES2 gl, GLUniformData data) {
- int location = getUniformLocation(gl, data.getName());
- data.setLocation(location);
- activeUniformDataMap.put(data.getName(), data);
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ final String name = data.getName();
+ int location = getCachedUniformLocation(name);
+ if(0<=location) {
+ data.setLocation(location);
+ } else {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ location = data.setLocation(gl, shaderProgram.program());
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ activeUniformLocationMap.put(name, idx);
+ } else if(verbose) {
+ System.err.println("ShaderState: glUniform failed, no location for: "+name+", index: "+location);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ }
+ }
+ activeUniformDataMap.put(name, data);
return location;
}