From dc5883b13f157586dd2d89a84f9ea91d945edf70 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 4 Aug 2008 12:11:21 +0000 Subject: ../jogl.log git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1741 232f8b59-042b-4e1e-8c03-345bb8c30851 --- src/classes/javax/media/opengl/GLArrayData.java | 153 ++++++ .../javax/media/opengl/GLArrayDataClient.java | 498 ++++++++++++++++++ .../javax/media/opengl/GLArrayDataServer.java | 265 ++++++++++ src/classes/javax/media/opengl/GLContext.java | 59 +++ src/classes/javax/media/opengl/GLProfile.java | 302 +++++++++++ src/classes/javax/media/opengl/GLUniformData.java | 159 ++++++ .../javax/media/opengl/util/ImmModeSink.java | 455 +++++++++++++--- src/classes/javax/media/opengl/util/PMVMatrix.java | 283 ++++++---- .../javax/media/opengl/util/VBOBufferDraw.java | 392 -------------- .../javax/media/opengl/util/glsl/ShaderCode.java | 122 +++++ .../media/opengl/util/glsl/ShaderProgram.java | 201 +++++++ .../javax/media/opengl/util/glsl/ShaderState.java | 583 +++++++++++++++++++++ 12 files changed, 2917 insertions(+), 555 deletions(-) create mode 100644 src/classes/javax/media/opengl/GLArrayData.java create mode 100644 src/classes/javax/media/opengl/GLArrayDataClient.java create mode 100644 src/classes/javax/media/opengl/GLArrayDataServer.java create mode 100644 src/classes/javax/media/opengl/GLUniformData.java delete mode 100644 src/classes/javax/media/opengl/util/VBOBufferDraw.java create mode 100644 src/classes/javax/media/opengl/util/glsl/ShaderCode.java create mode 100644 src/classes/javax/media/opengl/util/glsl/ShaderProgram.java create mode 100644 src/classes/javax/media/opengl/util/glsl/ShaderState.java (limited to 'src/classes/javax/media/opengl') diff --git a/src/classes/javax/media/opengl/GLArrayData.java b/src/classes/javax/media/opengl/GLArrayData.java new file mode 100644 index 000000000..db017b00a --- /dev/null +++ b/src/classes/javax/media/opengl/GLArrayData.java @@ -0,0 +1,153 @@ + +package javax.media.opengl; + +import java.nio.*; + +public interface GLArrayData { + + /** + * Returns true if this data set is intended for a GLSL vertex shader attribute, + * otherwise false, ie intended for fixed function vertex pointer + */ + public boolean isVertexAttribute(); + + /** + * The index of the predefined array index, see list below, + * or -1 in case of a shader attribute array. + * + * @see javax.media.opengl.GL#GL_VERTEX_ARRAY + * @see javax.media.opengl.GL#GL_NORMAL_ARRAY + * @see javax.media.opengl.GL#GL_COLOR_ARRAY + * @see javax.media.opengl.GL#GL_TEXTURE_COORD_ARRAY + */ + public int getIndex(); + + /** + * The name of the reflecting shader array attribute. + */ + public String getName(); + + /** + * Set a new name for this array. + */ + public void setName(String newName); + + + /** + * Returns the shader attribute location for this name, + * -1 if not yet determined + */ + public int getLocation(); + + /** + * Sets the determined location of the shader attribute + * This is usually done within ShaderState. + * + * @see javax.media.opengl.util.glsl.ShaderState#glVertexAttribPointer(GL2ES2, GLArrayData) + */ + public void setLocation(int v); + + + public boolean sealed(); + + /** + * The offset, if it's an VBO, otherwise -1 + */ + public long getOffset(); + + /** + * The Buffer holding the data, may be null in case of VBO + */ + public Buffer getBuffer(); + + /** + * Determines wheather the data is server side (VBO), + * or a client side array (false). + */ + public boolean isVBO(); + + /** + * The number of components per element + */ + public int getComponents(); + + /** + * The GL data type of the components, ie. GL_FLOAT + */ + public int getDataType(); + + /** + * True, if GL shall normalize fixed point data while converting + * them into float + */ + public boolean getNormalized(); + + /** + * The distance to the next payload, + * allowing interleaved arrays. + */ + public int getStride(); + + public int getVerticeNumber(); + + public int getBufferCompSize(); + + public String toString(); + + // + // Data and GL state modification .. + // + + public void destroy(GL gl); + + public void reset(GL gl); + + /** + * If seal is true, it + * disable write operations to the buffer. + * Calls flip, ie limit:=position and position:=0. + * Also enables the buffer for OpenGL, and passes the data. + * + * If seal is false, it + * enable write operations continuing + * at the buffer position, where you left off at seal(true), + * ie position:=limit and limit:=capacity. + * Also disables the buffer for OpenGL. + * + * @see #seal(boolean) + */ + public void seal(GL gl, boolean seal); + + public void enableBuffer(GL gl, boolean enable); + + // + // Data modification .. + // + + public void reset(); + + /** + * If seal is true, it + * disable write operations to the buffer. + * Calls flip, ie limit:=position and position:=0. + * + * If seal is false, it + * enable write operations continuing + * at the buffer position, where you left off at seal(true), + * ie position:=limit and limit:=capacity. + * + */ + public void seal(boolean seal); + + public void rewind(); + public void padding(int done); + public void put(Buffer v); + public void putb(byte v); + public void puts(short v); + public void puti(int v); + public void putx(int v); + public void putf(float v); + public void putd(double v); + +} + diff --git a/src/classes/javax/media/opengl/GLArrayDataClient.java b/src/classes/javax/media/opengl/GLArrayDataClient.java new file mode 100644 index 000000000..5048e15c3 --- /dev/null +++ b/src/classes/javax/media/opengl/GLArrayDataClient.java @@ -0,0 +1,498 @@ + +package javax.media.opengl; + +import javax.media.opengl.util.*; +import com.sun.opengl.impl.GLReflection; + +import java.nio.*; + +public class GLArrayDataClient implements GLArrayData { + + /** + * @arg index The GL array index + * @arg name The optional custom name for the GL array index, maybe null. + * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'. + * This name might be used as the shader attribute name. + * @arg comps The array component number + * @arg dataType The array index GL data type + * @arg normalized Wheather the data shall be normalized + * + * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int) + */ + public static GLArrayDataClient createFixed(int index, String name, int comps, int dataType, boolean normalized, + int initialSize) + throws GLException + { + GLProfile.isValidateArrayDataType(index, comps, dataType, false, true); + GLArrayDataClient adc = new GLArrayDataClient(); + adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, false); + return adc; + } + + public static GLArrayDataClient createFixed(int index, String name, int comps, int dataType, boolean normalized, + int stride, Buffer buffer) + throws GLException + { + GLProfile.isValidateArrayDataType(index, comps, dataType, false, true); + GLArrayDataClient adc = new GLArrayDataClient(); + adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, false); + return adc; + } + + public static GLArrayDataClient createGLSL(int index, String name, int comps, int dataType, boolean normalized, + int initialSize) + throws GLException + { + GLProfile.isValidateArrayDataType(index, comps, dataType, true, true); + GLArrayDataClient adc = new GLArrayDataClient(); + adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, true); + return adc; + } + + public static GLArrayDataClient createGLSL(int index, String name, int comps, int dataType, boolean normalized, + int stride, Buffer buffer) + throws GLException + { + GLProfile.isValidateArrayDataType(index, comps, dataType, true, true); + GLArrayDataClient adc = new GLArrayDataClient(); + adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, true); + return adc; + } + + // + // Data read access + // + + public boolean isVertexAttribute() { return isVertexAttribute; } + + public int getIndex() { return index; } + + public int getLocation() { return location; } + + public void setLocation(int v) { location = v; } + + public String getName() { return name; } + + public long getOffset() { return -1; } + + public Buffer getBuffer() { return buffer; } + + public boolean isVBO() { return false; } + + public int getComponents() { return components; } + + public int getDataType() { return dataType; } + + public boolean getNormalized() { return normalized; } + + public int getStride() { return stride; } + + public boolean sealed() { return sealed; } + + public Class getBufferClass() { + return clazz; + } + + public int getVerticeNumber() { + return ( buffer!=null ) ? ( buffer.limit() / components ) : 0 ; + } + + // + // Data and GL state modification .. + // + + public void setName(String newName) { + location = -1; + name = newName; + } + + public void destroy(GL gl) { + reset(gl); + } + + public void reset(GL gl) { + enableBuffer(gl, false); + reset(); + } + + public void seal(GL gl, boolean seal) + { + seal(seal); + if(sealedGL==seal) return; + sealedGL = seal; + if(seal) { + init_vbo(gl); + + enableBuffer(gl, true); + } else { + enableBuffer(gl, false); + } + } + + public void enableBuffer(GL gl, boolean enable) + { + if(enable) { + checkSeal(true); + if(!bufferEnabled && null!=buffer) { + buffer.rewind(); + enableBufferGLImpl(gl, true); + } + } else if(bufferEnabled) { + enableBufferGLImpl(gl, false); + } + } + + // + // Data modification .. + // + + public void reset() { + if(buffer!=null) { + buffer.clear(); + } + this.sealed=false; + this.bufferEnabled=false; + this.bufferWritten=false; + } + + public void seal(boolean seal) + { + if(sealed==seal) return; + sealed = seal; + if(seal) { + bufferWritten=false; + if (null!=buffer) { + buffer.flip(); + } + } else { + if (null!=buffer) { + buffer.position(buffer.limit()); + buffer.limit(buffer.capacity()); + } + } + } + + + public void rewind() { + if(buffer!=null) { + buffer.rewind(); + } + } + + public void padding(int done) { + if ( buffer==null || sealed ) return; + while(done0) { + int osize = (buffer!=null)?buffer.capacity():0; + if(clazz==ByteBuffer.class) { + ByteBuffer newBBuffer = BufferUtil.newByteBuffer( (osize+additional) * components ); + if(buffer!=null) { + buffer.flip(); + newBBuffer.put((ByteBuffer)buffer); + } + buffer = newBBuffer; + } else if(clazz==ShortBuffer.class) { + ShortBuffer newSBuffer = BufferUtil.newShortBuffer( (osize+additional) * components ); + if(buffer!=null) { + buffer.flip(); + newSBuffer.put((ShortBuffer)buffer); + } + buffer = newSBuffer; + } else if(clazz==IntBuffer.class) { + IntBuffer newIBuffer = BufferUtil.newIntBuffer( (osize+additional) * components ); + if(buffer!=null) { + buffer.flip(); + newIBuffer.put((IntBuffer)buffer); + } + buffer = newIBuffer; + } else if(clazz==FloatBuffer.class) { + FloatBuffer newFBuffer = BufferUtil.newFloatBuffer( (osize+additional) * components ); + if(buffer!=null) { + buffer.flip(); + newFBuffer.put((FloatBuffer)buffer); + } + buffer = newFBuffer; + } else { + throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this); + } + } + } + + protected final void checkSeal(boolean test) throws GLException { + if(sealed!=test) { + if(test) { + throw new GLException("Not Sealed yet, seal first:\n\t"+this); + } else { + throw new GLException("Already Sealed, can't modify VBO:\n\t"+this); + } + } + } + + protected void init(String name, int index, int comps, int dataType, boolean normalized, int stride, Buffer data, + int initialSize, boolean isVertexAttribute) + throws GLException + { + this.isVertexAttribute = isVertexAttribute; + this.index = index; + this.location = -1; + this.name = (null==name)?GLContext.getPredefinedArrayIndexName(index):name; + if(null==this.name) { + throw new GLException("Not a valid GL array index: "+index); + } + this.dataType = dataType; + this.clazz = getBufferClass(dataType); + switch(dataType) { + case GL.GL_BYTE: + case GL.GL_UNSIGNED_BYTE: + case GL.GL_SHORT: + case GL.GL_UNSIGNED_SHORT: + case GL2ES1.GL_FIXED: + this.normalized = normalized; + break; + default: + this.normalized = false; + } + + int bpc = getBufferCompSize(); + if(0rows || rows>4 || 2>columns || columns>4 ) { + throw new GLException("rowsXcolumns must be within [2..4]X[2..4], is: "+rows+"X"+columns); + } + this.name=name; + this.rows=rows; + this.columns=columns; + this.isMatrix=true; + this.location=-1; + init(data); + } + + private void init(String name, int components, Object data) { + if( 1>components || components>4 ) { + throw new GLException("components must be within [1..4], is: "+components); + } + this.name=name; + this.columns=components; + this.rows=1; + this.isMatrix=false; + this.location=-1; + init(data); + } + + private void init(Object data) { + if(data instanceof Buffer) { + int sz = rows*columns; + Buffer buffer = (Buffer)data; + if(buffer.limit()0) { + sb.append("\n\t],\nVBO current: NOP]"); + } else { + sb.append("\n\t],\nVBO current: \n"); + sb.append(vboSet); + sb.append("\n]"); + } + return sb.toString(); } public void draw(GL gl, boolean disableBufferAfterDraw) { @@ -58,7 +85,18 @@ public class ImmModeSink { } int n=0; for(Iterator i=vboSetList.iterator(); i.hasNext() ; n++) { - ((VBOSet)i.next()).draw(gl, disableBufferAfterDraw, n); + ((VBOSet)i.next()).draw(gl, null, disableBufferAfterDraw, n); + } + } + + public void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw) { + if(DEBUG_DRAW) { + Exception e = new Exception("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); + e.printStackTrace(); + } + int n=0; + for(Iterator i=vboSetList.iterator(); i.hasNext() ; n++) { + ((VBOSet)i.next()).draw(gl, indices, disableBufferAfterDraw, n); } } @@ -69,9 +107,10 @@ public class ImmModeSink { } vboSet.modeOrig = mode; switch(mode) { - case GL_QUADS: - mode=GL.GL_TRIANGLE_STRIP; - break; + // Needs data manipulation .. + //case GL_QUADS: + // mode=GL.GL_LINES; + // break; case GL_QUAD_STRIP: mode=GL.GL_TRIANGLE_STRIP; break; @@ -84,17 +123,25 @@ public class ImmModeSink { } public final void glEnd(GL gl) { - glEnd(gl, true); + glEnd(gl, null, true); } public void glEnd(GL gl, boolean immediateDraw) { + glEnd(gl, null, immediateDraw); + } + + public final void glEnd(GL gl, Buffer indices) { + glEnd(gl, indices, true); + } + + private void glEnd(GL gl, Buffer indices, boolean immediateDraw) { if(DEBUG_BEGIN_END) { Exception e = new Exception("ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this); e.printStackTrace(); } if(immediateDraw) { vboSet.seal(gl, false); - vboSet.draw(gl, true, -1); + vboSet.draw(gl, indices, true, -1); reset(gl); } else { vboSet.seal(gl, true); @@ -103,6 +150,9 @@ public class ImmModeSink { } } + public void glVertexv(Buffer v) { + vboSet.glVertexv(v); + } public final void glVertex2f(float x, float y) { vboSet.glVertex2f(x,y); } @@ -111,14 +161,27 @@ public class ImmModeSink { vboSet.glVertex3f(x,y,z); } + public void glNormalv(Buffer v) { + vboSet.glNormalv(v); + } public final void glNormal3f(float x, float y, float z) { vboSet.glNormal3f(x,y,z); } + public void glColorv(Buffer v) { + vboSet.glColorv(v); + } public final void glColor3f(float x, float y, float z) { vboSet.glColor3f(x,y,z); } + public final void glColor4f(float x, float y, float z, float a) { + vboSet.glColor4f(x,y,z, a); + } + + public void glTexCoordv(Buffer v) { + vboSet.glTexCoordv(v); + } public final void glTexCoord2f(float x, float y) { vboSet.glTexCoord2f(x,y); } @@ -127,29 +190,114 @@ public class ImmModeSink { vboSet.glTexCoord3f(x,y,z); } + public final void glVertex2s(short x, short y) { + vboSet.glVertex2s(x,y); + } + + public final void glVertex3s(short x, short y, short z) { + vboSet.glVertex3s(x,y,z); + } + + public final void glNormal3s(short x, short y, short z) { + vboSet.glNormal3s(x,y,z); + } + + public final void glColor3s(short x, short y, short z) { + vboSet.glColor3s(x,y,z); + } + + public final void glColor4s(short x, short y, short z, short a) { + vboSet.glColor4s(x,y,z,a); + } + + public final void glTexCoord2s(short x, short y) { + vboSet.glTexCoord2s(x,y); + } + + public final void glTexCoord3s(short x, short y, short z) { + vboSet.glTexCoord3s(x,y,z); + } + + public final void glVertex2b(byte x, byte y) { + vboSet.glVertex2b(x,y); + } + + public final void glVertex3b(byte x, byte y, byte z) { + vboSet.glVertex3b(x,y,z); + } + + public final void glNormal3b(byte x, byte y, byte z) { + vboSet.glNormal3b(x,y,z); + } + + public final void glColor3b(byte x, byte y, byte z) { + vboSet.glColor3b(x,y,z); + } + + public final void glColor4b(byte x, byte y, byte z, byte a) { + vboSet.glColor4b(x,y,z,a); + } + + public final void glTexCoord2b(byte x, byte y) { + vboSet.glTexCoord2b(x,y); + } + + public final void glTexCoord3b(byte x, byte y, byte z) { + vboSet.glTexCoord3b(x,y,z); + } + + protected ImmModeSink(int glBufferUsage, int initialSize, + int vComps, int vDataType, + int cComps, int cDataType, + int nComps, int nDataType, + int tComps, int tDataType, boolean useGLSL) { + if(useGLSL && !GLProfile.isGL2ES2()) { + throw new GLException("ImmModeSink GLSL usage not supported for profile: "+GLProfile.getProfile()); + } + vboSet = new VBOSet(glBufferUsage, initialSize, + vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL); + this.vboSetList = new ArrayList(); + } + + private void destroyList(GL gl) { + for(Iterator i=vboSetList.iterator(); i.hasNext() ; ) { + ((VBOSet)i.next()).destroy(gl); + } + vboSetList.clear(); + } + private VBOSet vboSet; private ArrayList vboSetList; protected static class VBOSet { - protected VBOSet(int glDataType, int glDrawUsage, - int vComps, int nComps, int cComps, int tComps, int initialSize) { - nComps = 0; - tComps = 0; - if(FLOAT2FIXED && glDataType==GL.GL_FLOAT) { - glDataType=GL2ES1.GL_FIXED; - } - this.glDataType=glDataType; - this.glDrawUsage=glDrawUsage; + protected VBOSet (int glBufferUsage, int initialSize, + int vComps, int vDataType, + int cComps, int cDataType, + int nComps, int nDataType, + int tComps, int tDataType, boolean useGLSL) { + this.glBufferUsage=glBufferUsage; + this.initialSize=initialSize; + this.vDataType=vDataType; this.vComps=vComps; - this.nComps=nComps; + this.cDataType=cDataType; this.cComps=cComps; + this.nDataType=nDataType; + this.nComps=nComps; + this.tDataType=tDataType; this.tComps=tComps; - this.initialSize=initialSize; - - this.vertexVBO = VBOBufferDraw.create(GL2ES1.GL_VERTEX_ARRAY, glDataType, glDrawUsage, vComps, initialSize); - this.normalVBO = VBOBufferDraw.create(GL2ES1.GL_NORMAL_ARRAY, glDataType, glDrawUsage, nComps, initialSize); - this.colorVBO = VBOBufferDraw.create(GL2ES1.GL_COLOR_ARRAY, glDataType, glDrawUsage, cComps, initialSize); - this.texcoordVBO = VBOBufferDraw.create(GL2ES1.GL_TEXTURE_COORD_ARRAY, glDataType, glDrawUsage, tComps, initialSize); + this.useGLSL=useGLSL; + + if(!useGLSL) { + this.vertexVBO = GLArrayDataServer.createFixed(GL.GL_VERTEX_ARRAY, null, vComps, vDataType, false, initialSize, glBufferUsage); + this.colorVBO = GLArrayDataServer.createFixed(GL.GL_COLOR_ARRAY, null, cComps, cDataType, false, initialSize, glBufferUsage); + this.normalVBO = GLArrayDataServer.createFixed(GL.GL_NORMAL_ARRAY, null, nComps, nDataType, false, initialSize, glBufferUsage); + this.texcoordVBO = GLArrayDataServer.createFixed(GL.GL_TEXTURE_COORD_ARRAY, null, tComps, tDataType, false, initialSize, glBufferUsage); + } else { + this.vertexVBO = GLArrayDataServer.createGLSL(GLContext.mgl_Vertex, vComps, vDataType, false, initialSize, glBufferUsage); + this.colorVBO = GLArrayDataServer.createGLSL(GLContext.mgl_Color, cComps, cDataType, false, initialSize, glBufferUsage); + this.normalVBO = GLArrayDataServer.createGLSL(GLContext.mgl_Normal, nComps, nDataType, false, initialSize, glBufferUsage); + this.texcoordVBO = GLArrayDataServer.createGLSL(GLContext.mgl_MultiTexCoord, tComps, tDataType, false, initialSize, glBufferUsage); + } this.sealed=false; this.mode = -1; @@ -157,7 +305,8 @@ public class ImmModeSink { } protected final VBOSet regenerate() { - return new VBOSet(glDataType, glDrawUsage, vComps, nComps, cComps, tComps, initialSize); + return new VBOSet(glBufferUsage, initialSize, + vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL); } protected void destroy(GL gl) { @@ -186,10 +335,10 @@ public class ImmModeSink { return "VBOSet[mode "+mode+ ", modeOrig "+modeOrig+ ", sealed "+sealed+ - ",\n\t vertexVBO "+vertexVBO+ - ",\n\t normalVBO "+normalVBO+ - ",\n\t colorVBO "+colorVBO+ - ",\n\t texcoordVBO "+texcoordVBO+ + ",\n\t"+vertexVBO+ + ",\n\t"+normalVBO+ + ",\n\t"+colorVBO+ + ",\n\t"+texcoordVBO+ "]"; } @@ -220,35 +369,60 @@ public class ImmModeSink { checkSeal(false); sealed = true; - vertexVBO.seal(gl, disableBufferAfterSeal); - normalVBO.seal(gl, disableBufferAfterSeal); - colorVBO.seal(gl, disableBufferAfterSeal); - texcoordVBO.seal(gl, disableBufferAfterSeal); + vertexVBO.seal(gl, true); + normalVBO.seal(gl, true); + colorVBO.seal(gl, true); + texcoordVBO.seal(gl, true); + + if(disableBufferAfterSeal) { + vertexVBO.enableBuffer(gl, false); + normalVBO.enableBuffer(gl, false); + colorVBO.enableBuffer(gl, false); + texcoordVBO.enableBuffer(gl, false); + } } - protected void draw(GL gl, boolean disableBufferAfterDraw, int i) + protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i) { if(DEBUG_DRAW) { Exception e = new Exception("ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); e.printStackTrace(); } - vertexVBO.enableBuffer(gl); - normalVBO.enableBuffer(gl); - colorVBO.enableBuffer(gl); - texcoordVBO.enableBuffer(gl); + vertexVBO.enableBuffer(gl, true); + normalVBO.enableBuffer(gl, true); + colorVBO.enableBuffer(gl, true); + texcoordVBO.enableBuffer(gl, true); if (vertexVBO.getBuffer()!=null) { - gl.glDrawArrays(mode, 0, vertexVBO.getVerticeNumber()); + if(null==indices) { + gl.glDrawArrays(mode, 0, vertexVBO.getVerticeNumber()); + } else { + Class clazz = indices.getClass(); + int type=-1; + if(GLReflection.instanceOf(clazz, ByteBuffer.class.getName())) { + type = GL.GL_UNSIGNED_BYTE; + } else if(GLReflection.instanceOf(clazz, ShortBuffer.class.getName())) { + type = GL.GL_UNSIGNED_SHORT; + } + if(0>type) { + throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this); + } + gl.glDrawElements(mode, indices.remaining(), type, indices); + } } if(disableBufferAfterDraw) { - vertexVBO.disableBuffer(gl); - normalVBO.disableBuffer(gl); - colorVBO.disableBuffer(gl); - texcoordVBO.disableBuffer(gl); + vertexVBO.enableBuffer(gl, false); + normalVBO.enableBuffer(gl, false); + colorVBO.enableBuffer(gl, false); + texcoordVBO.enableBuffer(gl, false); } } + protected void glVertexv(Buffer v) { + checkSeal(false); + vertexVBO.put(v); + } protected void glVertex2f(float x, float y) { checkSeal(false); vertexVBO.putf(x); @@ -256,7 +430,6 @@ public class ImmModeSink { vertexVBO.putf(y); vertexVBO.padding(2); } - protected void glVertex3f(float x, float y, float z) { checkSeal(false); vertexVBO.putf(x); @@ -267,6 +440,10 @@ public class ImmModeSink { vertexVBO.padding(3); } + protected void glNormalv(Buffer v) { + checkSeal(false); + normalVBO.put(v); + } protected void glNormal3f(float x, float y, float z) { checkSeal(false); normalVBO.putf(x); @@ -277,6 +454,10 @@ public class ImmModeSink { normalVBO.padding(3); } + protected void glColorv(Buffer v) { + checkSeal(false); + colorVBO.put(v); + } protected void glColor3f(float x, float y, float z) { checkSeal(false); colorVBO.putf(x); @@ -286,7 +467,22 @@ public class ImmModeSink { colorVBO.putf(z); colorVBO.padding(3); } + protected void glColor4f(float x, float y, float z, float a) { + checkSeal(false); + colorVBO.putf(x); + if(colorVBO.getComponents()>1) + colorVBO.putf(y); + if(colorVBO.getComponents()>2) + colorVBO.putf(z); + if(colorVBO.getComponents()>3) + colorVBO.putf(a); + colorVBO.padding(4); + } + protected void glTexCoordv(Buffer v) { + checkSeal(false); + texcoordVBO.put(v); + } protected void glTexCoord2f(float x, float y) { checkSeal(false); texcoordVBO.putf(x); @@ -294,7 +490,6 @@ public class ImmModeSink { texcoordVBO.putf(y); texcoordVBO.padding(2); } - protected void glTexCoord3f(float x, float y, float z) { checkSeal(false); texcoordVBO.putf(x); @@ -305,13 +500,145 @@ public class ImmModeSink { texcoordVBO.padding(3); } - VBOBufferDraw vertexVBO; - VBOBufferDraw normalVBO; - VBOBufferDraw colorVBO; - VBOBufferDraw texcoordVBO; + protected void glVertex2s(short x, short y) { + checkSeal(false); + vertexVBO.puts(x); + if(vertexVBO.getComponents()>1) + vertexVBO.puts(y); + vertexVBO.padding(2); + } + protected void glVertex3s(short x, short y, short z) { + checkSeal(false); + vertexVBO.puts(x); + if(vertexVBO.getComponents()>1) + vertexVBO.puts(y); + if(vertexVBO.getComponents()>2) + vertexVBO.puts(z); + vertexVBO.padding(3); + } + + protected void glNormal3s(short x, short y, short z) { + checkSeal(false); + normalVBO.puts(x); + if(normalVBO.getComponents()>1) + normalVBO.puts(y); + if(normalVBO.getComponents()>2) + normalVBO.puts(z); + normalVBO.padding(3); + } + + protected void glColor3s(short x, short y, short z) { + checkSeal(false); + colorVBO.puts(x); + if(colorVBO.getComponents()>1) + colorVBO.puts(y); + if(colorVBO.getComponents()>2) + colorVBO.puts(z); + colorVBO.padding(3); + } + protected void glColor4s(short x, short y, short z, short a) { + checkSeal(false); + colorVBO.puts(x); + if(colorVBO.getComponents()>1) + colorVBO.puts(y); + if(colorVBO.getComponents()>2) + colorVBO.puts(z); + if(colorVBO.getComponents()>3) + colorVBO.puts(a); + colorVBO.padding(4); + } + + protected void glTexCoord2s(short x, short y) { + checkSeal(false); + texcoordVBO.puts(x); + if(texcoordVBO.getComponents()>1) + texcoordVBO.puts(y); + texcoordVBO.padding(2); + } + protected void glTexCoord3s(short x, short y, short z) { + checkSeal(false); + texcoordVBO.puts(x); + if(texcoordVBO.getComponents()>1) + texcoordVBO.puts(y); + if(texcoordVBO.getComponents()>2) + texcoordVBO.puts(z); + texcoordVBO.padding(3); + } + + protected void glVertex2b(byte x, byte y) { + checkSeal(false); + vertexVBO.putb(x); + if(vertexVBO.getComponents()>1) + vertexVBO.putb(y); + vertexVBO.padding(2); + } + protected void glVertex3b(byte x, byte y, byte z) { + checkSeal(false); + vertexVBO.putb(x); + if(vertexVBO.getComponents()>1) + vertexVBO.putb(y); + if(vertexVBO.getComponents()>2) + vertexVBO.putb(z); + vertexVBO.padding(3); + } + + protected void glNormal3b(byte x, byte y, byte z) { + checkSeal(false); + normalVBO.putb(x); + if(normalVBO.getComponents()>1) + normalVBO.putb(y); + if(normalVBO.getComponents()>2) + normalVBO.putb(z); + normalVBO.padding(3); + } + + protected void glColor3b(byte x, byte y, byte z) { + checkSeal(false); + colorVBO.putb(x); + if(colorVBO.getComponents()>1) + colorVBO.putb(y); + if(colorVBO.getComponents()>2) + colorVBO.putb(z); + colorVBO.padding(3); + } + protected void glColor4b(byte x, byte y, byte z, byte a) { + checkSeal(false); + colorVBO.putb(x); + if(colorVBO.getComponents()>1) + colorVBO.putb(y); + if(colorVBO.getComponents()>2) + colorVBO.putb(z); + if(colorVBO.getComponents()>3) + colorVBO.putb(a); + colorVBO.padding(4); + } + protected void glTexCoord2b(byte x, byte y) { + checkSeal(false); + texcoordVBO.putb(x); + if(texcoordVBO.getComponents()>1) + texcoordVBO.putb(y); + texcoordVBO.padding(2); + } + + protected void glTexCoord3b(byte x, byte y, byte z) { + checkSeal(false); + texcoordVBO.putb(x); + if(texcoordVBO.getComponents()>1) + texcoordVBO.putb(y); + if(texcoordVBO.getComponents()>2) + texcoordVBO.putb(z); + texcoordVBO.padding(3); + } + + GLArrayDataServer vertexVBO; + GLArrayDataServer normalVBO; + GLArrayDataServer colorVBO; + GLArrayDataServer texcoordVBO; int mode, modeOrig; - int glDataType, glDrawUsage, vComps, nComps, cComps, tComps, initialSize; - boolean sealed; + int glBufferUsage, initialSize; + int vComps, cComps, nComps, tComps; + int vDataType, cDataType, nDataType, tDataType; + boolean sealed, useGLSL; } } diff --git a/src/classes/javax/media/opengl/util/PMVMatrix.java b/src/classes/javax/media/opengl/util/PMVMatrix.java index 4e8693be0..37472dfe6 100755 --- a/src/classes/javax/media/opengl/util/PMVMatrix.java +++ b/src/classes/javax/media/opengl/util/PMVMatrix.java @@ -9,55 +9,54 @@ import java.util.List; public class PMVMatrix { - protected ProjectFloat pvmProjectf = null; - protected FloatBuffer matrixPMV, matrixP, matrixMV; - protected FloatBuffer matrixTemp, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixPersp, matrixFrustum; - protected float[] vec3f; - protected List/*FloatBuffer*/ matrixPStack, matrixMVStack; - protected int matrixMode = GL.GL_MODELVIEW; - protected boolean modifiedPMV = false; - public PMVMatrix() { - pvmProjectf = new ProjectFloat(); + projectFloat = new ProjectFloat(); + + matrixIdent = BufferUtil.newFloatBuffer(1*16); + projectFloat.gluMakeIdentityf(matrixIdent); + matrixIdent.rewind(); + + matrixPMvMviT = BufferUtil.newFloatBuffer(4*16); // grouping P + Mv + Mvi + MviT + matrixPMvMvi = slice(matrixPMvMviT, 0*16, 3*16); // grouping P + Mv + Mvi + matrixPMv = slice(matrixPMvMviT, 0*16, 2*16); // grouping P + Mv + matrixP = slice(matrixPMvMviT, 0*16, 1*16); + matrixMv = slice(matrixPMvMviT, 1*16, 1*16); + matrixMvi = slice(matrixPMvMviT, 2*16, 1*16); + matrixMvit = slice(matrixPMvMviT, 3*16, 1*16); + matrixPMvMviT.rewind(); - matrixPMV = BufferUtil.newFloatBuffer(2*16); - matrixP = slice(matrixPMV, 0*16, 16); - matrixMV = slice(matrixPMV, 1*16, 16); - matrixPMV.rewind(); + matrixMvit3 = BufferUtil.newFloatBuffer(3*3); - FloatBuffer buf = BufferUtil.newFloatBuffer(7*16); + FloatBuffer buf = BufferUtil.newFloatBuffer(6*16); - matrixTemp=slice(buf, 0*16, 16); + matrixMult=slice(buf, 0*16, 16); matrixTrans=slice(buf, 1*16, 16); - pvmProjectf.gluMakeIdentityf(matrixTrans); + projectFloat.gluMakeIdentityf(matrixTrans); matrixRot=slice(buf, 2*16, 16); - pvmProjectf.gluMakeIdentityf(matrixRot); + projectFloat.gluMakeIdentityf(matrixRot); matrixScale=slice(buf, 3*16, 16); - pvmProjectf.gluMakeIdentityf(matrixScale); + projectFloat.gluMakeIdentityf(matrixScale); matrixOrtho=slice(buf, 4*16, 16); - pvmProjectf.gluMakeIdentityf(matrixOrtho); + projectFloat.gluMakeIdentityf(matrixOrtho); matrixFrustum=slice(buf, 5*16, 16); - pvmProjectf.gluMakeZero(matrixFrustum); - - matrixPersp=slice(buf, 6*16, 16); - pvmProjectf.gluMakeIdentityf(matrixPersp); + projectFloat.gluMakeZero(matrixFrustum); vec3f=new float[3]; matrixPStack = new ArrayList(); - matrixMVStack= new ArrayList(); + matrixMvStack= new ArrayList(); // default values and mode glMatrixMode(GL.GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL.GL_MODELVIEW); glLoadIdentity(); - modifiedPMV = true; + modified = true; } private static FloatBuffer slice(FloatBuffer buf, int pos, int len) { @@ -67,11 +66,16 @@ public class PMVMatrix { } public boolean isDirty() { - return modifiedPMV; + return modified; } - public void clear() { - modifiedPMV=false; + public boolean update() { + boolean res = modified; + if(res) { + setMviMvit(); + modified=false; + } + return res; } public final int glGetMatrixMode() { @@ -89,8 +93,24 @@ public class PMVMatrix { matrixMode = matrixName; } - public final FloatBuffer glGetPMVMatrixf() { - return matrixPMV; + public final FloatBuffer glGetPMvMviTMatrixf() { + return matrixPMvMviT; + } + + public final FloatBuffer glGetPMvMviMatrixf() { + return matrixPMvMvi; + } + + public final FloatBuffer glGetPMvMatrixf() { + return matrixPMv; + } + + public final FloatBuffer glGetMviMatrixf() { + return matrixMvi; + } + + public final FloatBuffer glGetNormalMatrixf() { + return matrixMvit3; } public final FloatBuffer glGetMatrixf() { @@ -99,82 +119,116 @@ public class PMVMatrix { public final FloatBuffer glGetMatrixf(int matrixName) { if(matrixName==GL.GL_MODELVIEW) { - return matrixMV; + return matrixMv; } else if(matrixName==GL.GL_PROJECTION) { return matrixP; } return null; } + public void glLoadMatrixf(float[] values, int offset) { + int len = values.length-offset; + if(matrixMode==GL.GL_MODELVIEW) { + matrixMv.clear(); + matrixMv.put(values, offset, len); + matrixMv.rewind(); + } else if(matrixMode==GL.GL_PROJECTION) { + matrixP.clear(); + matrixP.put(values, offset, len); + matrixP.rewind(); + } + modified = true; + } + public void glLoadMatrixf(java.nio.FloatBuffer m) { + int spos = m.position(); if(matrixMode==GL.GL_MODELVIEW) { - matrixMV.clear(); - matrixMV.put(m); - matrixMV.rewind(); + matrixMv.clear(); + matrixMv.put(m); + matrixMv.rewind(); } else if(matrixMode==GL.GL_PROJECTION) { matrixP.clear(); matrixP.put(m); matrixP.rewind(); } - modifiedPMV = true; + m.position(spos); + modified = true; } public void glPopMatrix() { + float[] stackEntry=null; if(matrixMode==GL.GL_MODELVIEW) { - matrixMV=(FloatBuffer)matrixMVStack.remove(0); + stackEntry = (float[])matrixMvStack.remove(0); } else if(matrixMode==GL.GL_PROJECTION) { - matrixP=(FloatBuffer)matrixPStack.remove(0); + stackEntry = (float[])matrixPStack.remove(0); } - modifiedPMV = true; + glLoadMatrixf(stackEntry, 0); } public void glPushMatrix() { + float[] stackEntry = new float[1*16]; if(matrixMode==GL.GL_MODELVIEW) { - matrixMVStack.add(0, matrixMV); + matrixMv.get(stackEntry); + matrixMv.rewind(); + matrixMvStack.add(0, stackEntry); } else if(matrixMode==GL.GL_PROJECTION) { - matrixPStack.add(0, matrixP); - } + matrixP.get(stackEntry); + matrixP.rewind(); + matrixPStack.add(0, stackEntry); + } } public void glLoadIdentity() { if(matrixMode==GL.GL_MODELVIEW) { - matrixMV.clear(); - pvmProjectf.gluMakeIdentityf(matrixMV); - matrixMV.rewind(); + matrixMv.clear(); + matrixMv.put(matrixIdent); + matrixMv.rewind(); + matrixIdent.rewind(); } else if(matrixMode==GL.GL_PROJECTION) { matrixP.clear(); - pvmProjectf.gluMakeIdentityf(matrixP); + matrixP.put(matrixIdent); matrixP.rewind(); + matrixIdent.rewind(); } - modifiedPMV = true; + modified = true; + } + + public void glMultMatrixf(FloatBuffer a, FloatBuffer b, FloatBuffer p) { + for (int i = 0; i < 4; i++) { + final float ai0=a.get(i+0*4), ai1=a.get(i+1*4), ai2=a.get(i+2*4), ai3=a.get(i+3*4); + p.put(i+0*4 , ai0 * b.get(0+0*4) + ai1 * b.get(1+0*4) + ai2 * b.get(2+0*4) + ai3 * b.get(3+0*4) ); + p.put(i+1*4 , ai0 * b.get(0+1*4) + ai1 * b.get(1+1*4) + ai2 * b.get(2+1*4) + ai3 * b.get(3+1*4) ); + p.put(i+2*4 , ai0 * b.get(0+2*4) + ai1 * b.get(1+2*4) + ai2 * b.get(2+2*4) + ai3 * b.get(3+2*4) ); + p.put(i+3*4 , ai0 * b.get(0+3*4) + ai1 * b.get(1+3*4) + ai2 * b.get(2+3*4) + ai3 * b.get(3+3*4) ); + } + // or .. projectFloat.gluMultMatricesf(b, a, p); } public void glMultMatrixf(FloatBuffer m) { if(matrixMode==GL.GL_MODELVIEW) { - pvmProjectf.gluMultMatricesf(m, matrixMV, matrixTemp); - matrixMV.clear(); - matrixMV.put(matrixTemp); - matrixMV.rewind(); + glMultMatrixf(matrixMv, m, matrixMult); + matrixMv.clear(); + matrixMv.put(matrixMult); + matrixMv.rewind(); } else if(matrixMode==GL.GL_PROJECTION) { - pvmProjectf.gluMultMatricesf(m, matrixP, matrixTemp); + glMultMatrixf(matrixP, m, matrixMult); matrixP.clear(); - matrixP.put(matrixTemp); + matrixP.put(matrixMult); matrixP.rewind(); } - matrixTemp.rewind(); - modifiedPMV = true; + matrixMult.rewind(); + modified = true; } public void glTranslatef(float x, float y, float z) { // Translation matrix: - // 1 0 0 0 - // 0 1 0 0 - // 0 0 1 0 - // x y z 1 - matrixTrans.put(3*4+0, x); - matrixTrans.put(3*4+1, y); - matrixTrans.put(3*4+2, z); - + // 1 0 0 x + // 0 1 0 y + // 0 0 1 z + // 0 0 0 1 + matrixTrans.put(0+4*3, x); + matrixTrans.put(1+4*3, y); + matrixTrans.put(2+4*3, z); glMultMatrixf(matrixTrans); } @@ -185,7 +239,7 @@ public class PMVMatrix { float s = (float)Math.sin(angrad); vec3f[0]=x; vec3f[1]=y; vec3f[2]=z; - pvmProjectf.normalize(vec3f); + projectFloat.normalize(vec3f); x = vec3f[0]; y = vec3f[1]; z = vec3f[2]; // Rotation matrix: @@ -199,6 +253,19 @@ public class PMVMatrix { float ys = y*s; float yz = y*z; float zs = z*s; + if(false) { + matrixRot.put(0+4*0, x*x*ic+c); + matrixRot.put(0+4*1, xy*ic+zs); + matrixRot.put(0+4*2, xz*ic-ys); + + matrixRot.put(1+4*0, xy*ic+zs); + matrixRot.put(1+4*1, y*y*ic+c); + matrixRot.put(1+4*2, yz*ic-xs); + + matrixRot.put(2+4*0, xz*ic-ys); + matrixRot.put(2+4*1, yz*ic+xs); + matrixRot.put(2+4*2, z*z*ic+c); + } else { matrixRot.put(0*4+0, x*x*ic+c); matrixRot.put(0*4+1, xy*ic+zs); matrixRot.put(0*4+2, xz*ic-ys); @@ -210,6 +277,7 @@ public class PMVMatrix { matrixRot.put(2*4+0, xz*ic+ys); matrixRot.put(2*4+1, yz*ic-xs); matrixRot.put(2*4+2, z*z*ic+c); + } glMultMatrixf(matrixRot); } @@ -220,19 +288,19 @@ public class PMVMatrix { // 0 y 0 0 // 0 0 z 0 // 0 0 0 1 - matrixScale.put(0*4+0, x); - matrixScale.put(1*4+1, y); - matrixScale.put(2*4+2, z); + matrixScale.put(0+4*0, x); + matrixScale.put(1+4*1, y); + matrixScale.put(2+4*2, z); glMultMatrixf(matrixScale); } public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) { // Ortho matrix: - // 2/dx 0 0 0 - // 0 2/dy 0 0 - // 0 0 2/dz 0 - // tx tx tx 1 + // 2/dx 0 0 tx + // 0 2/dy 0 ty + // 0 0 2/dz tz + // 0 0 0 1 float dx=right-left; float dy=top-bottom; float dz=zFar-zNear; @@ -240,12 +308,12 @@ public class PMVMatrix { float ty=-1.0f*(top+bottom)/dy; float tz=-1.0f*(zFar+zNear)/dz; - matrixOrtho.put(0*4+0, 2.0f/dx); - matrixOrtho.put(1*4+1, 2.0f/dy); - matrixOrtho.put(2*4+2, -2.0f/dz); - matrixOrtho.put(3*4+0, tx); - matrixOrtho.put(3*4+1, ty); - matrixOrtho.put(3*4+2, tz); + matrixOrtho.put(0+4*0, 2.0f/dx); + matrixOrtho.put(1+4*1, 2.0f/dy); + matrixOrtho.put(2+4*2, -2.0f/dz); + matrixOrtho.put(0+4*3, tx); + matrixOrtho.put(1+4*3, ty); + matrixOrtho.put(2+4*3, tz); glMultMatrixf(matrixOrtho); } @@ -271,40 +339,57 @@ public class PMVMatrix { float C=-1.0f*(zFar+zNear)/dz; float D=-2.0f*(zFar*zNear)/dz; - matrixFrustum.put(0*4+0, zNear2/dx); - matrixFrustum.put(1*4+1, zNear2/dy); - matrixFrustum.put(2*4+2, C); - matrixFrustum.put(0*4+2, A); - matrixFrustum.put(1*4+2, B); - matrixFrustum.put(2*4+3, D); - matrixFrustum.put(3*4+2, -1.0f); + matrixFrustum.put(0+4*0, zNear2/dx); + matrixFrustum.put(1+4*1, zNear2/dy); + matrixFrustum.put(2+4*2, C); + + matrixFrustum.put(0+4*2, A); + matrixFrustum.put(1+4*2, B); + + matrixFrustum.put(2+4*3, D); + matrixFrustum.put(3+4*2, -1.0f); glMultMatrixf(matrixFrustum); } public void gluPerspective(float fovy, float aspect, float zNear, float zFar) { - float radians = fovy/2 * (float) Math.PI / 180; - - float sine, cotangent, deltaZ; + float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear; + float bottom=-1.0f*top; + float left=aspect*bottom; + float right=aspect*top; + glFrustumf(left, right, bottom, top, zNear, zFar); + } - deltaZ = zFar - zNear; - sine = (float) Math.sin(radians); + private void setMviMvit() { + if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) { + throw new GLException("Invalid source Mv matrix, can't compute inverse"); + } - if ((deltaZ == 0.0f) || (sine == 0.0f) || (aspect == 0.0f)) { - return; + // transpose matrix + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + matrixMvit.put(j+i*4, matrixMvi.get(i+j*4)); + } } - cotangent = (float) Math.cos(radians) / sine; + // fetch 3x3 + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + matrixMvit3.put(i+j*3, matrixMvit.get(i+j*4)); + } + } + } - matrixPersp.put(0 * 4 + 0, cotangent / aspect); - matrixPersp.put(1 * 4 + 1, cotangent); - matrixPersp.put(2 * 4 + 2, - (zFar + zNear) / deltaZ); - matrixPersp.put(2 * 4 + 3, -1); - matrixPersp.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ); - matrixPersp.put(3 * 4 + 3, 0); + protected FloatBuffer matrixIdent; + protected FloatBuffer matrixPMvMviT, matrixPMvMvi, matrixPMv, matrixP, matrixMv, matrixMvi, matrixMvit; + protected FloatBuffer matrixMvit3; + protected FloatBuffer matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum; + protected float[] vec3f; + protected List/*FloatBuffer*/ matrixPStack, matrixMvStack; + protected int matrixMode = GL.GL_MODELVIEW; + protected boolean modified = false; + protected ProjectFloat projectFloat; - glMultMatrixf(matrixPersp); - } } diff --git a/src/classes/javax/media/opengl/util/VBOBufferDraw.java b/src/classes/javax/media/opengl/util/VBOBufferDraw.java deleted file mode 100644 index 8ce1b3232..000000000 --- a/src/classes/javax/media/opengl/util/VBOBufferDraw.java +++ /dev/null @@ -1,392 +0,0 @@ - -package javax.media.opengl.util; - -import javax.media.opengl.*; -import java.nio.*; -import com.sun.opengl.impl.*; - -public abstract class VBOBufferDraw { - - public static VBOBufferDraw create(int glArrayType, int glDataType, int glBufferUsage, int comps, int initialSize) - throws GLException - { - Class[] types = new Class[]{ int.class, int.class, int.class, int.class, int.class }; - Object[] args = new Integer[]{ new Integer(glArrayType), new Integer(glDataType), new Integer(glBufferUsage), - new Integer(comps), new Integer(initialSize) } ; - - if(GLProfile.isGL2ES1()) { - return (VBOBufferDraw) GLReflection.createInstance("com.sun.opengl.impl.gl2es1.VBOBufferDrawGL2ES1", types, args); - } else if(GLProfile.isGLES2()) { - return (VBOBufferDraw) GLReflection.createInstance("com.sun.opengl.impl.es2.VBOBufferDrawGLES2", types, args); - } - throw new GLException("VBOBufferDraw not supported for profile: "+GLProfile.getProfile()); - } - - protected void init(int glArrayType, int glDataType, int glBufferUsage, int comps, int initialSize) - throws GLException - { - vboUsage=true; - - switch(glArrayType) { - case GL2ES1.GL_VERTEX_ARRAY: - case GL2ES1.GL_NORMAL_ARRAY: - if(3!=comps && 0!=comps) { - throw new GLException("component size for NORMAL_ARRAY must be 3 or 0: "+comps+" \n\t"+this); - } - case GL2ES1.GL_COLOR_ARRAY: - case GL2ES1.GL_TEXTURE_COORD_ARRAY: - break; - default: - throw new GLException("invalid glArrayType: "+glArrayType+":\n\t"+this); - } - this.glArrayType = glArrayType; - this.glDataType = glDataType; - this.clazz = getBufferClass(glDataType); - this.buffer = null; - this.components = comps; - this.initialSize = initialSize; - if( ! (GLProfile.isGL2ES2() && glBufferUsage==GL2ES2.GL_STREAM_DRAW) ) { - switch(glBufferUsage) { - case GL2ES1.GL_STATIC_DRAW: - case GL2ES1.GL_DYNAMIC_DRAW: - break; - default: - throw new GLException("invalid glBufferUsage: "+glBufferUsage+":\n\t"+this); - } - } - this.glBufferUsage = glBufferUsage; - this.vboName = 0; - this.sealed=false; - this.bufferEnabled=false; - growVBO(initialSize); - } - - public boolean usesVBO() { return vboUsage; } - - public void setVBOUsage(boolean vboUsage) { - checkSeal(false); - this.vboUsage=vboUsage; - } - - public int getGLArrayType() { - return glArrayType; - } - - public int getGlDataType() { - return glDataType; - } - - public int getComponents() { - return components; - } - - public Class getBufferClass() { - return clazz; - } - - public Buffer getBuffer() { - return buffer; - } - - public int getBufferUsage() { - return glBufferUsage; - } - - public void destroy(GL gl) { - reset(gl); - if(vboName!=0) { - int[] tmp = new int[1]; - tmp[0] = vboName; - gl.glDeleteBuffers(1, tmp, 0); - vboName = 0; - } - } - - public void reset() { - reset(null); - } - - public void reset(GL gl) { - if(gl!=null) { - disableBuffer(gl); - } - this.sealed=false; - if(buffer!=null) { - buffer.clear(); - } - } - - private final void init_vbo(GL gl) { - if(vboUsage && vboName==0) { - int[] tmp = new int[1]; - gl.glGenBuffers(1, tmp, 0); - vboName = tmp[0]; - } - } - - private final void checkSeal(boolean test) throws GLException { - if(sealed!=test) { - if(test) { - throw new GLException("Not Sealed yet, seal first:\n\t"+this); - } else { - throw new GLException("Already Sealed, can't modify VBO:\n\t"+this); - } - } - } - - public final boolean growVBOIfNecessary(int spare) { - if(buffer==null) { - throw new GLException("buffer no configured:\n\t"+this); - } - if(buffer!=null && buffer.remaining()0) { - osize = (buffer!=null)?buffer.capacity():0; - if(clazz==ByteBuffer.class) { - ByteBuffer newBBuffer = BufferUtil.newByteBuffer( (osize+additional) * components ); - if(buffer!=null) { - buffer.flip(); - newBBuffer.put((ByteBuffer)buffer); - } - buffer = newBBuffer; - } else if(clazz==ShortBuffer.class) { - ShortBuffer newSBuffer = BufferUtil.newShortBuffer( (osize+additional) * components ); - if(buffer!=null) { - buffer.flip(); - newSBuffer.put((ShortBuffer)buffer); - } - buffer = newSBuffer; - } else if(clazz==IntBuffer.class) { - IntBuffer newIBuffer = BufferUtil.newIntBuffer( (osize+additional) * components ); - if(buffer!=null) { - buffer.flip(); - newIBuffer.put((IntBuffer)buffer); - } - buffer = newIBuffer; - } else if(clazz==FloatBuffer.class) { - FloatBuffer newFBuffer = BufferUtil.newFloatBuffer( (osize+additional) * components ); - if(buffer!=null) { - buffer.flip(); - newFBuffer.put((FloatBuffer)buffer); - } - buffer = newFBuffer; - } else { - throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this); - } - } - } - - public void rewind() { - checkSeal(true); - - if(buffer!=null) { - buffer.rewind(); - } - } - - public int getVerticeNumber() { - return ( buffer!=null ) ? ( buffer.limit() / components ) : 0 ; - } - - public void seal(GL gl, boolean disableAfterSeal) - { - checkSeal(false); - sealed = true; - init_vbo(gl); - - if (null!=buffer) { - buffer.flip(); - enableBuffer(gl, true); - } - if(null==buffer || disableAfterSeal) { - disableBuffer(gl); - } - - } - - public void enableBuffer(GL gl) - { - enableBuffer(gl, false); - } - - private void enableBuffer(GL gl, boolean newData) - { - checkSeal(true); - enableBufferGLImpl(gl, newData); - } - - protected abstract void enableBufferGLImpl(GL gl, boolean newData); - - public void disableBuffer(GL gl) { - disableBufferGLImpl(gl); - } - - protected abstract void disableBufferGLImpl(GL gl) ; - - public void padding(int done) { - if(buffer==null) return; // JAU - if(buffer==null) { - throw new GLException("buffer no configured:\n\t"+this); - } - while(done=0) { + ShaderCode oldShader = (ShaderCode) shaderMap.remove(new Integer(oldShaderID)); + if(null!=oldShader) { + gl.glDetachShader(shaderProgram, oldShader.shader()); + } + } + add(newShader); + + gl.glAttachShader(shaderProgram, newShader.shader()); + gl.glLinkProgram(shaderProgram); + if ( ! gl.glIsProgramValid(shaderProgram, System.err) ) { + return false; + } + + if(shaderWasInUse) { + glUseProgram(gl, true); + } + return true; + } + + public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) { + if(programLinked) throw new GLException("Program is already linked"); + + if(0>shaderProgram) { + shaderProgram = gl.glCreateProgram(); + } + + for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) { + ShaderCode shaderCode = (ShaderCode) iter.next(); + if(!shaderCode.compile(gl, verboseOut)) { + return false; + } + gl.glAttachShader(shaderProgram, shaderCode.shader()); + } + + // Link the program + gl.glLinkProgram(shaderProgram); + + if ( ! gl.glIsProgramValid(shaderProgram, System.err) ) { + return false; + } + programLinked=true; + + return true; + } + + public boolean equals(Object obj) { + if(this==obj) return true; + if(obj instanceof ShaderCode) { + return id()==((ShaderCode)obj).id(); + } + return false; + } + public int hashCode() { + return id.intValue(); + } + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("ShaderProgram[id="+id); + buf.append(", linked="+programLinked+", inUse="+programInUse+", program: "+shaderProgram+", ["); + for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) { + buf.append((ShaderCode) iter.next()); + buf.append(" "); + } + buf.append("]"); + return buf.toString(); + } + + protected synchronized void glUseProgram(GL2ES2 gl, boolean on) { + if(!programLinked) throw new GLException("Program is not linked"); + if(programInUse==on) return; + gl.glUseProgram(on?shaderProgram:0); + programInUse = on; + + //Throwable tX = new Throwable("Info: ShaderProgram.glUseProgram: "+on); + //tX.printStackTrace(); + + } + + protected boolean programLinked = false; + protected boolean programInUse = false; + protected int shaderProgram=-1; + protected HashMap shaderMap = new HashMap(); + protected Integer id = null; + + private static synchronized Integer getNextID() { + return new Integer(nextID++); + } + protected static int nextID = 1; +} + diff --git a/src/classes/javax/media/opengl/util/glsl/ShaderState.java b/src/classes/javax/media/opengl/util/glsl/ShaderState.java new file mode 100644 index 000000000..7f917cc07 --- /dev/null +++ b/src/classes/javax/media/opengl/util/glsl/ShaderState.java @@ -0,0 +1,583 @@ + +package javax.media.opengl.util.glsl; + +import javax.media.opengl.util.*; +import javax.media.opengl.*; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.nio.*; +import java.io.PrintStream; + +public class ShaderState { + + public ShaderState() { + } + + public boolean verbose() { return verbose; } + + public void setVerbose(boolean v) { verbose=v; } + + /** + * Fetches the current shader state + * + * @see javax.media.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean) + * @see javax.media.opengl.util.glsl.ShaderState#getCurrent() + */ + public static synchronized ShaderState getCurrent() { return currentShaderState; } + + /** + * Turns the shader program on + * and set this ShaderState to current if on equals true + * + * @see javax.media.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean) + * @see javax.media.opengl.util.glsl.ShaderState#getCurrent() + */ + public synchronized void glUseProgram(GL2ES2 gl, boolean on) { + if(on) { + if(null!=shaderProgram) { + shaderProgram.glUseProgram(gl, true); + } else { + throw new GLException("No program is attached"); + } + if(currentShaderState!=this) { + currentShaderState = this; + } + } else if(null!=shaderProgram) { + shaderProgram.glUseProgram(gl, false); + } + } + + public boolean linked() { + return (null!=shaderProgram)?shaderProgram.linked():false; + } + + public boolean inUse() { + return (null!=shaderProgram)?shaderProgram.inUse():false; + } + + /** + * Attach or switch a shader program + * + * Attaching a shader program the first time, + * as well as switching to another program on the fly, + * while managing all attribute and uniform data. + */ + public synchronized void attachShaderProgram(GL2ES2 gl, ShaderProgram prog) { + boolean prgInUse = false; // earmarked state + + if(null!=shaderProgram) { + if(shaderProgram.equals(prog)) { + // nothing to do .. + if(DEBUG) { + System.err.println("Info: attachShaderProgram: NOP: equal id: "+shaderProgram.id()); + } + return; + } + prgInUse = shaderProgram.inUse(); + } + if(DEBUG) { + Throwable tX = new Throwable("Info: attachShaderProgram: BEGIN "+shaderProgram+" -> "+prog); + tX.printStackTrace(); + } + + // register new one + shaderProgram = prog; + + if(null!=shaderProgram) { + // reinstall all data .. + shaderProgram.glUseProgram(gl, true); + glResetAllVertexAttributes(gl); + glResetAllUniforms(gl); + if(!prgInUse) { + shaderProgram.glUseProgram(gl, false); + } + } + if(DEBUG) { + System.err.println("Info: attachShaderProgram: END"); + } + } + + public ShaderProgram shaderProgram() { return shaderProgram; } + + /** + * @see #glReleaseAllVertexAttributes + * @see #glReleaseAllUniforms + */ + public synchronized void release(GL2ES2 gl) { + release(gl, false, false); + } + + public synchronized void release(GL2ES2 gl, boolean releaseProgramToo, boolean releaseShaderToo) { + boolean prgInUse = false; + if(null!=shaderProgram) { + prgInUse = shaderProgram.inUse(); + if(!prgInUse) { + shaderProgram.glUseProgram(gl, true); + } + } + glReleaseAllVertexAttributes(gl); + glReleaseAllUniforms(gl); + if(null!=shaderProgram) { + if(releaseProgramToo) { + shaderProgram.release(gl, releaseShaderToo); + } else if(!prgInUse) { + shaderProgram.glUseProgram(gl, false); + } + } + } + + // + // Shader attribute handling + // + + /** + * 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 + * + * @throws GLException is the program is already linked + * + * @see #glBindAttribLocation + * @see javax.media.opengl.GL2ES2#glBindAttribLocation + * @see #glGetAttribLocation + * @see javax.media.opengl.GL2ES2#glGetAttribLocation + * @see #getAttribLocation + * @see #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); + } + } + + /** + * Gets the index of a shader attribute. + * This must be done after the program is linked ! + * + * @return -1 if there is no such attribute available, + * otherwise >= 0 + * @throws GLException is the program is not linked + * + * @see #glBindAttribLocation + * @see javax.media.opengl.GL2ES2#glBindAttribLocation + * @see #glGetAttribLocation + * @see javax.media.opengl.GL2ES2#glGetAttribLocation + * @see #getAttribLocation + * @see #glReplaceShader + */ + 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); + } else if(verbose) { + Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", index: "+index); + tX.printStackTrace(); + } + } + return index; + } + + protected int getAttribLocation(String name) { + Integer idx = (Integer) attribMap2Idx.get(name); + return (null!=idx)?idx.intValue():-1; + } + + + // + // Enabled Vertex Arrays and its data + // + + /** + * Enable a vertex attribute array + * + * Even if the attribute is not found in the current shader, + * it is stored in this state. + * + * @returns false, if the name is not found, otherwise true + * + * @throws GLException if the program is not in use + * + * @see #glEnableVertexAttribArray + * @see #glDisableVertexAttribArray + * @see #glVertexAttribPointer + * @see #getVertexAttributePointer + * @see #glReleaseAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #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); + } + 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); + } + + /** + * Disables a vertex attribute array + * + * Even if the attribute is not found in the current shader, + * it is removed from this state. + * + * @returns false, if the name is not found, otherwise true + * + * @throws GLException if the program is not in use + * + * @see #glEnableVertexAttribArray + * @see #glDisableVertexAttribArray + * @see #glVertexAttribPointer + * @see #getVertexAttributePointer + * @see #glReleaseAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #glReplaceShader + */ + public boolean glDisableVertexAttribArray(GL2ES2 gl, String name) { + if(!shaderProgram.inUse()) throw new GLException("Program is not in use"); + 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(); + } + return false; + } + if(DEBUG) { + System.err.println("Info: glDisableVertexAttribArray: "+name); + } + gl.glDisableVertexAttribArray(index); + return true; + } + + /** + * Set the vertex attribute data. + * Enable the attribute, if it is not enabled yet. + * + * Even if the attribute is not found in the current shader, + * it is stored in this state. + * + * @arg data the GLArrayData's name must match the attributes one, + * it's index will be set with the attribute's location, + * if found. + * + * @returns false, if the name is not found, otherwise true + * + * @throws GLException if the program is not in use + * + * @see #glEnableVertexAttribArray + * @see #glDisableVertexAttribArray + * @see #glVertexAttribPointer + * @see #getVertexAttributePointer + * @see #glReleaseAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #glReplaceShader + */ + public boolean glVertexAttribPointer(GL2ES2 gl, GLArrayData data) { + if(!shaderProgram.inUse()) throw new GLException("Program is not in use"); + if(!enabledVertexAttribArraySet.contains(data.getName())) { + if(!glEnableVertexAttribArray(gl, data.getName())) { + 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) { + // only pass the data, if the attribute exists in the current shader + if(DEBUG) { + System.err.println("Info: glVertexAttribPointer: "+data); + } + gl.glVertexAttribPointer(data); + return true; + } + return false; + } + + /** + * Get the vertex attribute data, previously set. + * + * @returns the GLArrayData object, null if not previously set. + * + * @see #glEnableVertexAttribArray + * @see #glDisableVertexAttribArray + * @see #glVertexAttribPointer + * @see #getVertexAttributePointer + * @see #glReleaseAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #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 + * + * @throws GLException is the program is not in use but the shaderProgram is set + * + * @see #glEnableVertexAttribArray + * @see #glDisableVertexAttribArray + * @see #glVertexAttribPointer + * @see #getVertexAttributePointer + * @see #glReleaseAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #glReplaceShader + */ + 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())) { + throw new GLException("Internal Error: mapped vertex attribute couldn't be disabled"); + } + } + for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) { + if(!glDisableVertexAttribArray(gl, (String) iter.next())) { + throw new GLException("Internal Error: prev enabled vertex attribute couldn't be disabled"); + } + } + } + vertexAttribMap2Data.clear(); + enabledVertexAttribArraySet.clear(); + attribMap2Idx.clear(); + } + + /** + * Disables all vertex attribute arrays. + * + * Their enabled stated will be removed from this state only + * if 'removeFromState' is true. + * + * This method purpose is more for debugging. + * + * @throws GLException is the program is not in use but the shaderProgram is set + * + * @see #glEnableVertexAttribArray + * @see #glDisableVertexAttribArray + * @see #glVertexAttribPointer + * @see #getVertexAttributePointer + * @see #glReleaseAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #glReplaceShader + */ + public void glDisableAllVertexAttributeArrays(GL2ES2 gl, boolean removeFromState) { + if(!shaderProgram.inUse()) throw new GLException("Program is not in use"); + + for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) { + String name = (String) iter.next(); + if(removeFromState) { + enabledVertexAttribArraySet.remove(name); + } + int index = glGetAttribLocation(gl, name); + if(0<=index) { + gl.glDisableVertexAttribArray(index); + } + } + } + + /** + * Reset all previously mapped vertex attribute data, + * incl enabling them + * + * @throws GLException is the program is not in use + * + * @see #glEnableVertexAttribArray + * @see #glDisableVertexAttribArray + * @see #glVertexAttribPointer + * @see #getVertexAttributePointer + * @see #glReleaseAllVertexAttributes + * @see #glResetAllVertexAttributes + * @see #glReplaceShader + */ + 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(); ) { + glVertexAttribPointer(gl, (GLArrayData) iter.next()); + } + } + + // + // Shader Uniform handling + // + + /** + * Gets the index of a shader uniform. + * This must be done when the program is in use ! + * + * @return -1 if there is no such attribute available, + * otherwise >= 0 + + * @throws GLException is the program is not linked + * + * @see #glGetUniformLocation + * @see javax.media.opengl.GL2ES2#glGetUniformLocation + * @see #getUniformLocation + * @see #glReplaceShader + */ + 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); + } else if(verbose) { + Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+index); + tX.printStackTrace(); + } + } + return index; + } + + protected int getUniformLocation(String name) { + Integer idx = (Integer) uniformMap2Idx.get(name); + return (null!=idx)?idx.intValue():-1; + } + + /** + * Set the uniform data. + * + * Even if the uniform is not found in the current shader, + * it is stored in this state. + * + * @arg data the GLUniforms's name must match the uniform one, + * it's index will be set with the uniforms's location, + * if found. + * + * + * @returns false, if the name is not found, otherwise true + * + * @throws GLException if the program is not in use + * + * @see #glGetUniformLocation + * @see javax.media.opengl.GL2ES2#glGetUniformLocation + * @see #getUniformLocation + * @see #glReplaceShader + */ + public boolean glUniform(GL2ES2 gl, GLUniformData data) { + if(!shaderProgram.inUse()) throw new GLException("Program is not in use"); + int location = glGetUniformLocation(gl, data.getName()); + data.setLocation(location); + uniformMap2Data.put(data.getName(), data); + if(0<=location) { + // only pass the data, if the uniform exists in the current shader + if(DEBUG) { + System.err.println("Info: glUniform: "+data); + } + gl.glUniform(data); + } + return true; + } + + /** + * Get the uniform data, previously set. + * + * @returns the GLUniformData object, null if not previously set. + */ + public GLUniformData getUniform(String name) { + return (GLUniformData) uniformMap2Data.get(name); + } + + /** + * Releases all mapped uniform data + * and loses all indices + * + * @throws GLException is the program is not in use + */ + public void glReleaseAllUniforms(GL2ES2 gl) { + uniformMap2Data.clear(); + uniformMap2Idx.clear(); + } + + /** + * Reset all previously mapped uniform data + * + * @throws GLException is the program is not in use + */ + 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()); + } + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("ShaderState["); + buf.append(shaderProgram.toString()); + buf.append(",EnabledStates: ["); + for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) { + buf.append("\n "); + buf.append((String)iter.next()); + } + buf.append("], ["); + for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) { + buf.append("\n "); + buf.append((GLArrayData) iter.next()); + } + buf.append("], ["); + for(Iterator iter=uniformMap2Data.values().iterator(); iter.hasNext(); ) { + buf.append("\n "); + buf.append((GLUniformData) iter.next()); + } + buf.append("]"); + return buf.toString(); + } + + protected static final boolean DEBUG = false; + 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 static ShaderState currentShaderState = null; + +} + -- cgit v1.2.3