summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-10-10 16:36:46 +0200
committerSven Gothel <[email protected]>2012-10-10 16:36:46 +0200
commit34d7e1f13a107e63bd234e4b31782cfb46feb4c0 (patch)
tree43e454156a098b1d17ac9717b115dd12227b8d9d /src/jogl/classes/com/jogamp/opengl
parent13402255253dcfc64aa773f0756201ec805ec063 (diff)
ImmModeSink: Fix bugs (use glBufferUsage, vboUsage, GL_POLYGON, GL_QUADS) and add API docs. (API Change)
- Changed create*(..) factory methods (API Change) - Drop passing GL instance, not needed - allows creation of ImmModeSink as final field w/o GL context - Use 'glBufferUsage' to determine whether to use VBO or not ( 0 == glBufferUsage ) - Use glBufferUsage in glBufferData(..) call (oops) - Toggle vboUsage per object ( 0 == glBufferUsage ? nonVBO : VBO ) remove static VBO usage flag - Fix render mode - GL_POLYGON -> GL_TRIANGLE_FAN (not GL_LINES) - GL_QUADS -> Looped GL_TRIANGLE_FAN (is !GL2) in draw(..) w/ and w/o indices - Buffer usage - documented - allow creating sink w/ all components (vertices, color, normal and texCoords) bit render and grow only used parts. This allows proper usage of sink where it is not known which types are being used. - Added test case - Manually tested w/ Jake2 ES1 Jake2 uses the FFP immediate mode rendering, where we utilize this sink w/o rendering artifacts.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java641
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java2
2 files changed, 409 insertions, 234 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index cf0373044..238e402d1 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -13,52 +13,107 @@ import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLException;
import javax.media.opengl.fixedfunc.GLPointerFunc;
-import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.opengl.util.glsl.ShaderState;
+/**
+ * <p>
+ * Immediate mode sink, implementing OpenGL fixed function subset of immediate mode operations, i.e.
+ * <pre>
+ * glBegin();
+ * glVertex3f(1f, 1f, 1f);
+ * glColor4f(1f, 1f, 1f, 1f);
+ * ...
+ * glEnd();
+ * </pre>
+ * Implementation buffers all vertex, colors, normal and texture-coord elements in their respective buffers
+ * to be either rendered directly via {@link #glEnd(GL)} or to be added to an internal display list
+ * 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>
+ * <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.
+ * This implementation will only render buffers which are being filled.<br/>
+ * The buffer growing implementation will only grow the exceeded buffers, unused buffers are not resized.
+ * </p>
+ * <p>
+ * Note: Optional types, i.e. color, must be either not used or used w/ the same element count as vertex, etc.
+ * This is a semantic constraint, same as in the original OpenGL spec.
+ * </p>
+ */
public class ImmModeSink {
public static final boolean DEBUG_BEGIN_END = false;
public static final boolean DEBUG_DRAW = false;
+ public static final boolean DEBUG_BUFFER = false;
- // public static final int GL_QUADS = 0x0007; // Needs data manipulation
+ public static final int GL_QUADS = 0x0007; // Needs data manipulation on ES1/ES2
public static final int GL_QUAD_STRIP = 0x0008;
public static final int GL_POLYGON = 0x0009;
/**
* Uses a GL2ES1, or ES2 fixed function emulation immediate mode sink
+ * <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
*/
- public static ImmModeSink createFixed(GL gl, int glBufferUsage, int initialElementCount,
+ public static ImmModeSink createFixed(int initialElementCount,
int vComps, int vDataType,
- int cComps, int cDataType,
+ int cComps, int cDataType,
int nComps, int nDataType,
- int tComps, int tDataType) {
- return new ImmModeSink(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, false);
+ int tComps, int tDataType,
+ int glBufferUsage) {
+ return new ImmModeSink(initialElementCount, vComps,
+ vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, false, glBufferUsage);
}
/**
* Uses a GL2ES2 GLSL shader immediate mode sink.
* To issue the draw() command,
* a ShaderState must be current, using ShaderState.glUseProgram().
- *
+ * <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
+ *
* @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(GL gl, int glBufferUsage, int initialElementCount,
+ public static ImmModeSink createGLSL(int initialElementCount,
int vComps, int vDataType,
- int cComps, int cDataType,
+ int cComps, int cDataType,
int nComps, int nDataType,
- int tComps, int tDataType) {
- return new ImmModeSink(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, true);
+ int tComps, int tDataType,
+ int glBufferUsage) {
+ return new ImmModeSink(initialElementCount, vComps,
+ vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, true, glBufferUsage);
}
- public static boolean usesVBO() { return vboUsage; }
-
- public static void setVBOUsage(boolean v) { vboUsage = v; }
-
public void destroy(GL gl) {
destroyList(gl);
@@ -93,42 +148,35 @@ public class ImmModeSink {
public void draw(GL gl, boolean disableBufferAfterDraw) {
if(DEBUG_DRAW) {
- Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
}
int n=0;
- for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; n++) {
- i.next().draw(gl, null, disableBufferAfterDraw, n);
+ for(int i=0; i<vboSetList.size(); i++, n++) {
+ vboSetList.get(i).draw(gl, null, disableBufferAfterDraw, n);
}
}
public void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw) {
if(DEBUG_DRAW) {
- Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
}
int n=0;
- for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; n++) {
- i.next().draw(gl, indices, disableBufferAfterDraw, n);
+ for(int i=0; i<vboSetList.size(); i++, n++) {
+ vboSetList.get(i).draw(gl, indices, disableBufferAfterDraw, n);
}
}
public void glBegin(int mode) {
if(DEBUG_BEGIN_END) {
- Exception e = new Exception("Info: ImmModeSink.glBegin("+vboSet.mode+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink.glBegin("+vboSet.mode+"):\n\t"+this);
}
vboSet.modeOrig = mode;
switch(mode) {
- // Needs data manipulation ..
- //case GL_QUADS:
- // mode=GL.GL_LINES;
- // break;
case GL_QUAD_STRIP:
mode=GL.GL_TRIANGLE_STRIP;
break;
case GL_POLYGON:
- mode=GL.GL_LINES;
+ mode=GL.GL_TRIANGLE_FAN;
break;
}
vboSet.mode = mode;
@@ -149,8 +197,7 @@ public class ImmModeSink {
private void glEnd(GL gl, Buffer indices, boolean immediateDraw) {
if(DEBUG_BEGIN_END) {
- Exception e = new Exception("Info: ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this);
}
if(immediateDraw) {
vboSet.seal(gl, true);
@@ -160,7 +207,10 @@ public class ImmModeSink {
vboSet.seal(gl, true);
vboSet.enableBuffer(gl, false);
vboSetList.add(vboSet);
- vboSet = vboSet.regenerate();
+ vboSet = vboSet.regenerate(gl);
+ }
+ if(DEBUG_BEGIN_END) {
+ System.err.println("ImmModeSink END glEnd(immediate: "+immediateDraw+"):\n\t"+this);
}
}
@@ -261,37 +311,34 @@ public class ImmModeSink {
vboSet.glTexCoord3b(x,y,z);
}
- protected ImmModeSink(GL gl, int glBufferUsage, int initialElementCount,
- int vComps, int vDataType,
- int cComps, int cDataType,
- int nComps, int nDataType,
- int tComps, int tDataType, boolean useGLSL) {
- if(useGLSL && !gl.hasGLSL()) {
- throw new GLException("ImmModeSink GLSL usage not supported: "+gl);
- }
- vboSet = new VBOSet(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+ protected ImmModeSink(int initialElementCount, int vComps,
+ int vDataType, 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);
this.vboSetList = new ArrayList<VBOSet>();
}
-
+
+ public boolean getUseVBO() { return vboSet.getUseVBO(); }
+
private void destroyList(GL gl) {
- for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; ) {
- i.next().destroy(gl);
+ for(int i=0; i<vboSetList.size(); i++) {
+ vboSetList.get(i).destroy(gl);
}
vboSetList.clear();
}
private VBOSet vboSet;
- private ArrayList<VBOSet> vboSetList;
- private static boolean vboUsage = true;
+ private final ArrayList<VBOSet> vboSetList;
protected static class VBOSet {
- protected VBOSet (GL gl, int glBufferUsage, int initialElementCount,
- int vComps, int vDataType,
- int cComps, int cDataType,
- int nComps, int nDataType,
- int tComps, int tDataType, boolean useGLSL) {
- this.gl=gl;
+ protected VBOSet (int initialElementCount, int vComps,
+ int vDataType, int cComps,
+ int cDataType, int nComps,
+ int nDataType, int tComps,
+ int tDataType, boolean useGLSL, int glBufferUsage) {
this.glBufferUsage=glBufferUsage;
this.initialElementCount=initialElementCount;
this.vDataType=vDataType;
@@ -303,8 +350,19 @@ public class ImmModeSink {
this.tDataType=tDataType;
this.tComps=tComps;
this.useGLSL=useGLSL;
-
- allocateBuffer(initialElementCount);
+ this.useVBO = 0 != glBufferUsage;
+ this.vboName = 0;
+
+ this.vCount=0;
+ this.cCount=0;
+ this.nCount=0;
+ this.tCount=0;
+ this.vElems=0;
+ this.cElems=0;
+ this.nElems=0;
+ this.tElems=0;
+
+ reallocateBuffer(initialElementCount);
rewind();
this.sealed=false;
@@ -315,9 +373,11 @@ public class ImmModeSink {
this.bufferWritten=false;
}
- protected final VBOSet regenerate() {
- return new VBOSet(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+ protected boolean getUseVBO() { return useVBO; }
+
+ protected final VBOSet regenerate(GL gl) {
+ return new VBOSet(initialElementCount, vComps,
+ vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL, glBufferUsage);
}
protected void checkSeal(boolean test) throws GLException {
@@ -336,33 +396,55 @@ public class ImmModeSink {
protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i)
{
if(DEBUG_DRAW) {
- Exception e = new Exception("Info: ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink.draw["+i+"].0 (disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
}
enableBuffer(gl, true);
if (buffer!=null) {
if(null==indices) {
- gl.glDrawArrays(mode, 0, count);
+ if ( GL_QUADS == mode && !gl.isGL2() ) {
+ for (int j = 0; j < vElems - 3; j += 4) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, j, 4);
+ }
+ } else {
+ gl.glDrawArrays(mode, 0, vElems);
+ }
} else {
- Class<?> clazz = indices.getClass();
int type=-1;
- if(ReflectionUtil.instanceOf(clazz, ByteBuffer.class.getName())) {
+ if(indices instanceof ByteBuffer) {
type = GL.GL_UNSIGNED_BYTE;
- } else if(ReflectionUtil.instanceOf(clazz, ShortBuffer.class.getName())) {
+ } else if(indices instanceof ShortBuffer) {
type = GL.GL_UNSIGNED_SHORT;
+ } else {
+ throw new GLException("Given Buffer Class not supported: "+indices.getClass()+", should be ubyte or ushort:\n\t"+this);
}
- if(0>type) {
- throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this);
+
+ if ( GL_QUADS == mode && !gl.isGL2() ) {
+ if( GL.GL_UNSIGNED_BYTE == type ) {
+ final ByteBuffer b = (ByteBuffer) indices;
+ for (int j = 0; j < b.remaining(); j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x000000ff & b.get(j)), 4);
+ }
+ } else {
+ final ShortBuffer b = (ShortBuffer) indices;
+ for (int j = 0; j < b.remaining(); j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x0000ffff & b.get(j)), 4);
+ }
+ }
+ } else {
+ gl.glDrawElements(mode, indices.remaining(), type, indices);
+ // GL2: gl.glDrawRangeElements(mode, 0, indices.remaining()-1, indices.remaining(), type, indices);
}
- gl.glDrawElements(mode, indices.remaining(), type, indices);
- // GL2: gl.glDrawRangeElements(mode, 0, indices.remaining()-1, indices.remaining(), type, indices);
}
}
if(disableBufferAfterDraw) {
enableBuffer(gl, false);
}
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.draw["+i+"].X (disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
+ }
}
public void glVertexv(Buffer v) {
@@ -384,7 +466,7 @@ public class ImmModeSink {
public void glVertex2b(byte x, byte y) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 2);
+ growBuffer(VERTEX, 2);
if(vComps>0)
GLBuffers.putb(vertexArray, x);
if(vComps>1)
@@ -393,7 +475,7 @@ public class ImmModeSink {
}
public void glVertex3b(byte x, byte y, byte z) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 3);
+ growBuffer(VERTEX, 3);
if(vComps>0)
GLBuffers.putb(vertexArray, x);
if(vComps>1)
@@ -404,7 +486,7 @@ public class ImmModeSink {
}
public void glVertex2s(short x, short y) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 2);
+ growBuffer(VERTEX, 2);
if(vComps>0)
GLBuffers.puts(vertexArray, x);
if(vComps>1)
@@ -413,7 +495,7 @@ public class ImmModeSink {
}
public void glVertex3s(short x, short y, short z) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 3);
+ growBuffer(VERTEX, 3);
if(vComps>0)
GLBuffers.puts(vertexArray, x);
if(vComps>1)
@@ -424,7 +506,7 @@ public class ImmModeSink {
}
public void glVertex2f(float x, float y) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 2);
+ growBuffer(VERTEX, 2);
if(vComps>0)
GLBuffers.putf(vertexArray, x);
if(vComps>1)
@@ -433,7 +515,7 @@ public class ImmModeSink {
}
public void glVertex3f(float x, float y, float z) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 3);
+ growBuffer(VERTEX, 3);
if(vComps>0)
GLBuffers.putf(vertexArray, x);
if(vComps>1)
@@ -445,7 +527,7 @@ public class ImmModeSink {
public void glNormal3b(byte x, byte y, byte z) {
checkSeal(false);
- growBufferIfNecessary(NORMAL, 3);
+ growBuffer(NORMAL, 3);
if(nComps>0)
GLBuffers.putb(normalArray, x);
if(nComps>1)
@@ -456,7 +538,7 @@ public class ImmModeSink {
}
public void glNormal3s(short x, short y, short z) {
checkSeal(false);
- growBufferIfNecessary(NORMAL, 3);
+ growBuffer(NORMAL, 3);
if(nComps>0)
GLBuffers.puts(normalArray, x);
if(nComps>1)
@@ -467,7 +549,7 @@ public class ImmModeSink {
}
public void glNormal3f(float x, float y, float z) {
checkSeal(false);
- growBufferIfNecessary(NORMAL, 3);
+ growBuffer(NORMAL, 3);
if(nComps>0)
GLBuffers.putf(normalArray, x);
if(nComps>1)
@@ -479,7 +561,7 @@ public class ImmModeSink {
public void glColor3b(byte r, byte g, byte b) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 3);
+ growBuffer(COLOR, 3);
if(cComps>0)
GLBuffers.putb(colorArray, r);
if(cComps>1)
@@ -490,7 +572,7 @@ public class ImmModeSink {
}
public void glColor4b(byte r, byte g, byte b, byte a) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 4);
+ growBuffer(COLOR, 4);
if(cComps>0)
GLBuffers.putb(colorArray, r);
if(cComps>1)
@@ -503,7 +585,7 @@ public class ImmModeSink {
}
public void glColor3s(short r, short g, short b) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 3);
+ growBuffer(COLOR, 3);
if(cComps>0)
GLBuffers.puts(colorArray, r);
if(cComps>1)
@@ -514,7 +596,7 @@ public class ImmModeSink {
}
public void glColor4s(short r, short g, short b, short a) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 4);
+ growBuffer(COLOR, 4);
if(cComps>0)
GLBuffers.puts(colorArray, r);
if(cComps>1)
@@ -527,7 +609,7 @@ public class ImmModeSink {
}
public void glColor3f(float r, float g, float b) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 3);
+ growBuffer(COLOR, 3);
if(cComps>0)
GLBuffers.putf(colorArray, r);
if(cComps>1)
@@ -538,7 +620,7 @@ public class ImmModeSink {
}
public void glColor4f(float r, float g, float b, float a) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 4);
+ growBuffer(COLOR, 4);
if(cComps>0)
GLBuffers.putf(colorArray, r);
if(cComps>1)
@@ -552,7 +634,7 @@ public class ImmModeSink {
public void glTexCoord2b(byte x, byte y) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 2);
+ growBuffer(TEXTCOORD, 2);
if(tComps>0)
GLBuffers.putb(textCoordArray, x);
if(tComps>1)
@@ -561,7 +643,7 @@ public class ImmModeSink {
}
public void glTexCoord3b(byte x, byte y, byte z) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 3);
+ growBuffer(TEXTCOORD, 3);
if(tComps>0)
GLBuffers.putb(textCoordArray, x);
if(tComps>1)
@@ -572,7 +654,7 @@ public class ImmModeSink {
}
public void glTexCoord2s(short x, short y) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 2);
+ growBuffer(TEXTCOORD, 2);
if(tComps>0)
GLBuffers.puts(textCoordArray, x);
if(tComps>1)
@@ -581,7 +663,7 @@ public class ImmModeSink {
}
public void glTexCoord3s(short x, short y, short z) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 3);
+ growBuffer(TEXTCOORD, 3);
if(tComps>0)
GLBuffers.puts(textCoordArray, x);
if(tComps>1)
@@ -592,7 +674,7 @@ public class ImmModeSink {
}
public void glTexCoord2f(float x, float y) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 2);
+ growBuffer(TEXTCOORD, 2);
if(tComps>0)
GLBuffers.putf(textCoordArray, x);
if(tComps>1)
@@ -601,7 +683,7 @@ public class ImmModeSink {
}
public void glTexCoord3f(float x, float y, float z) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 3);
+ growBuffer(TEXTCOORD, 3);
if(tComps>0)
GLBuffers.putf(textCoordArray, x);
if(tComps>1)
@@ -629,10 +711,10 @@ public class ImmModeSink {
public void destroy(GL gl) {
reset(gl);
+ vCount=0; cCount=0; nCount=0; tCount=0;
vertexArray=null; colorArray=null; normalArray=null; textCoordArray=null;
vArrayData=null; cArrayData=null; nArrayData=null; tArrayData=null;
buffer=null;
- bSize=0; count=0;
}
public void reset(GL gl) {
@@ -649,8 +731,13 @@ public class ImmModeSink {
this.mode = 0;
this.modeOrig = 0;
this.sealed=false;
+ this.sealedGL=false;
this.bufferEnabled=false;
this.bufferWritten=false;
+ this.vElems=0;
+ this.cElems=0;
+ this.nElems=0;
+ this.tElems=0;
}
public void seal(GL glObj, boolean seal)
@@ -660,19 +747,25 @@ public class ImmModeSink {
sealedGL = seal;
GL gl = glObj.getGL();
if(seal) {
- if(vboUsage && vboName==0) {
- int[] tmp = new int[1];
- gl.glGenBuffers(1, tmp, 0);
- vboName = tmp[0];
+ if(useVBO) {
+ if(0 == vboName) {
+ int[] tmp = new int[1];
+ gl.glGenBuffers(1, tmp, 0);
+ vboName = tmp[0];
+ }
+ if(null!=vArrayData) {
+ vArrayData.setVBOName(vboName);
+ }
+ if(null!=cArrayData) {
+ cArrayData.setVBOName(vboName);
+ }
+ if(null!=nArrayData) {
+ nArrayData.setVBOName(vboName);
+ }
+ if(null!=tArrayData) {
+ tArrayData.setVBOName(vboName);
+ }
}
- if(null!=vArrayData)
- vArrayData.setVBOName(vboName);
- if(null!=cArrayData)
- cArrayData.setVBOName(vboName);
- if(null!=nArrayData)
- nArrayData.setVBOName(vboName);
- if(null!=tArrayData)
- tArrayData.setVBOName(vboName);
enableBuffer(gl, true);
} else {
enableBuffer(gl, false);
@@ -685,68 +778,89 @@ public class ImmModeSink {
sealed = seal;
if(seal) {
bufferWritten=false;
+ rewind();
}
}
public void enableBuffer(GL gl, boolean enable) {
- /* if(enableBufferAlways && enable) {
- bufferEnabled = false;
- } */
- if( bufferEnabled != enable && count>0 ) {
+ if( bufferEnabled != enable && vElems>0 ) {
if(enable) {
checkSeal(true);
}
+ bufferEnabled = enable;
if(useGLSL) {
enableBufferGLSL(gl, enable);
} else {
enableBufferFixed(gl, enable);
}
- bufferEnabled = enable;
}
}
public void enableBufferFixed(GL gl, boolean enable) {
GL2ES1 glf = gl.getGL2ES1();
+
+ 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.enableFixed.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"]");
+ }
if(enable) {
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
-
- if(!bufferWritten) {
- gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
- bufferWritten=true;
+ if(useVBO) {
+ if(0 == vboName) {
+ throw new InternalError("Using VBO but no vboName");
+ }
+ glf.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+
+ if(!bufferWritten) {
+ glf.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, glBufferUsage);
+ }
}
+ bufferWritten=true;
+ }
- if(vComps>0) {
+ if(useV) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
glf.glVertexPointer(vArrayData);
- }
- if(cComps>0) {
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+ }
+ }
+ if(useC) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
glf.glColorPointer(cArrayData);
- }
- if(nComps>0) {
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+ }
+ }
+ if(useN) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
glf.glNormalPointer(nArrayData);
- }
- if(tComps>0) {
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
+ }
+ }
+ if(useT) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
glf.glTexCoordPointer(tArrayData);
- }
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ if(enable && useVBO) {
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
- } else {
- if(vComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
- }
- if(cComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
- }
- if(nComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
- }
- if(tComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
- }
+ }
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableFixed.X "+this);
}
}
@@ -757,54 +871,79 @@ public class ImmModeSink {
}
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.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"]");
+ }
+
if(enable) {
- glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
-
- if(!bufferWritten) {
- glsl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
- bufferWritten=true;
+ if(useVBO) {
+ if(0 == vboName) {
+ throw new InternalError("Using VBO but no vboName");
+ }
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+ if(!bufferWritten) {
+ glsl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
+ }
}
+ bufferWritten=true;
+ }
- if(vComps>0) {
+ if(useV) {
+ if(enable) {
st.enableVertexAttribArray(glsl, vArrayData);
st.vertexAttribPointer(glsl, vArrayData);
- }
- if(cComps>0) {
+ } else {
+ st.disableVertexAttribArray(glsl, vArrayData);
+ }
+ }
+ if(useC) {
+ if(enable) {
st.enableVertexAttribArray(glsl, cArrayData);
st.vertexAttribPointer(glsl, cArrayData);
- }
- if(nComps>0) {
+ } else {
+ st.disableVertexAttribArray(glsl, cArrayData);
+ }
+ }
+ if(useN) {
+ if(enable) {
st.enableVertexAttribArray(glsl, nArrayData);
st.vertexAttribPointer(glsl, nArrayData);
- }
- if(tComps>0) {
+ } else {
+ st.disableVertexAttribArray(glsl, nArrayData);
+ }
+ }
+ if(useT) {
+ if(enable) {
st.enableVertexAttribArray(glsl, tArrayData);
st.vertexAttribPointer(glsl, tArrayData);
- }
-
- glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
- } else {
- if(vComps>0) {
- st.disableVertexAttribArray(glsl, vArrayData);
- }
- if(cComps>0) {
- st.disableVertexAttribArray(glsl, cArrayData);
- }
- if(nComps>0) {
- st.disableVertexAttribArray(glsl, nArrayData);
- }
- if(tComps>0) {
+ } else {
st.disableVertexAttribArray(glsl, tArrayData);
- }
+ }
+ }
+
+ if(enable && useVBO) {
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableGLSL.X "+this);
}
}
public String toString() {
return "VBOSet[mode "+mode+
", modeOrig "+modeOrig+
+ ", use/count "+getElemUseCountStr()+
", sealed "+sealed+
+ ", sealedGL "+sealedGL+
", bufferEnabled "+bufferEnabled+
- ", bufferWritten "+bufferWritten+
+ ", bufferWritten "+bufferWritten+
+ ", useVBO "+useVBO+", vboName "+vboName+
",\n\t"+vArrayData+
",\n\t"+cArrayData+
",\n\t"+nArrayData+
@@ -814,55 +953,84 @@ public class ImmModeSink {
// non public matters
- protected void allocateBuffer(int elementCount) {
- int vWidth = vComps * GLBuffers.sizeOfGLType(vDataType);
- int cWidth = cComps * GLBuffers.sizeOfGLType(cDataType);
- int nWidth = nComps * GLBuffers.sizeOfGLType(nDataType);
- int tWidth = tComps * GLBuffers.sizeOfGLType(tDataType);
-
- count = elementCount;
- bSize = count * ( vWidth + cWidth + nWidth + tWidth ) ;
-
- buffer = GLBuffers.newDirectByteBuffer(bSize);
-
- int pos = 0;
- int size= count * vWidth ;
- if(size>0) {
- vertexArray = GLBuffers.sliceGLBuffer(buffer, pos, size, vDataType);
+ protected String getElemUseCountStr() {
+ return "[v "+vElems+"/"+vCount+", c "+cElems+"/"+cCount+", n "+nElems+"/"+nCount+", t "+tElems+"/"+tCount+"]";
+ }
+
+ protected boolean fitElemsInBuffers(int addElems) {
+ final int vAdd = addElems - ( vCount - vElems );
+ final int cAdd = addElems - ( cCount - cElems );
+ final int nAdd = addElems - ( nCount - nElems );
+ final int tAdd = addElems - ( tCount - tElems );
+ final boolean res = 0>=vAdd && 0>=cAdd && 0>=nAdd && 0>=tAdd;
+ /* if(DEBUG_BUFFER) {
+ System.err.println("ImmModeSink.fitElemsInBuffer: "+getElemUseCountStr()+" + "+addElems+" -> "+res);
+ } */
+ return res;
+ }
+
+ protected boolean reallocateBuffer(int addElems) {
+ final int vAdd = addElems - ( vCount - vElems );
+ final int cAdd = addElems - ( cCount - cElems );
+ final int nAdd = addElems - ( nCount - nElems );
+ final int tAdd = addElems - ( tCount - tElems );
+
+ if( 0>=vAdd && 0>=cAdd && 0>=nAdd && 0>=tAdd) {
+ if(DEBUG_BUFFER) {
+ System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems+" -> NOP");
+ }
+ return false;
+ }
+
+ if(DEBUG_BUFFER) {
+ System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems);
+ }
+ vCount += vAdd;
+ cCount += cAdd;
+ nCount += nAdd;
+ tCount += tAdd;
+
+ final int vWidth = vComps * GLBuffers.sizeOfGLType(vDataType);
+ final int cWidth = cComps * GLBuffers.sizeOfGLType(cDataType);
+ final int nWidth = nComps * GLBuffers.sizeOfGLType(nDataType);
+ final int tWidth = tComps * GLBuffers.sizeOfGLType(tDataType);
+
+ final int bSizeV = vCount * vWidth;
+ final int bSizeC = cCount * cWidth;
+ final int bSizeN = nCount * nWidth;
+ final int bSizeT = tCount * tWidth;
+
+ buffer = GLBuffers.newDirectByteBuffer( bSizeV + bSizeC + bSizeN + bSizeT );
+ vOffset = 0;
+
+ if(bSizeV>0) {
+ vertexArray = GLBuffers.sliceGLBuffer(buffer, vOffset, bSizeV, vDataType);
} else {
vertexArray = null;
- }
- vOffset = pos;
- pos+=size;
+ }
+ cOffset=vOffset+bSizeV;
- size= count * cWidth ;
- if(size>0) {
- colorArray = GLBuffers.sliceGLBuffer(buffer, pos, size, cDataType);
+ if(bSizeC>0) {
+ colorArray = GLBuffers.sliceGLBuffer(buffer, cOffset, bSizeC, cDataType);
} else {
colorArray = null;
}
- cOffset = pos;
- pos+=size;
+ nOffset=cOffset+bSizeC;
- size= count * nWidth ;
- if(size>0) {
- normalArray = GLBuffers.sliceGLBuffer(buffer, pos, size, nDataType);
+ if(bSizeN>0) {
+ normalArray = GLBuffers.sliceGLBuffer(buffer, nOffset, bSizeN, nDataType);
} else {
normalArray = null;
}
- nOffset = pos;
- pos+=size;
+ tOffset=nOffset+bSizeN;
- size= count * tWidth ;
- if(size>0) {
- textCoordArray = GLBuffers.sliceGLBuffer(buffer, pos, size, tDataType);
+ if(bSizeT>0) {
+ textCoordArray = GLBuffers.sliceGLBuffer(buffer, tOffset, bSizeT, tDataType);
} else {
textCoordArray = null;
}
- tOffset = pos;
- pos+=size;
- buffer.position(pos);
+ buffer.position(tOffset+bSizeT);
buffer.flip();
if(vComps>0) {
@@ -889,41 +1057,42 @@ public class ImmModeSink {
} else {
tArrayData = null;
}
-
- }
-
- protected final boolean growBufferIfNecessary(int type, int spare) {
- if(buffer==null || count < spare) {
- growBuffer(type, initialElementCount);
- return true;
+
+ if(DEBUG_BUFFER) {
+ System.err.println("ImmModeSink.realloc.X: "+this.toString());
+ Thread.dumpStack();
}
- return false;
+ return true;
}
- protected final void growBuffer(int type, int additional) {
- if(sealed || 0==additional) return;
-
- // save olde values ..
- Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
-
- allocateBuffer(count+additional);
-
- if(null!=_vertexArray) {
- _vertexArray.flip();
- GLBuffers.put(vertexArray, _vertexArray);
- }
- if(null!=_colorArray) {
- _colorArray.flip();
- GLBuffers.put(colorArray, _colorArray);
- }
- if(null!=_normalArray) {
- _normalArray.flip();
- GLBuffers.put(normalArray, _normalArray);
- }
- if(null!=_textCoordArray) {
- _textCoordArray.flip();
- GLBuffers.put(textCoordArray, _textCoordArray);
+ protected final boolean growBuffer(int type, int additional) {
+ if( null !=buffer && !sealed && 0<additional) {
+ if( !fitElemsInBuffers(additional) ) {
+ // save olde values ..
+ final Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
+
+ if ( reallocateBuffer(initialElementCount) ) {
+ if(null!=_vertexArray) {
+ _vertexArray.flip();
+ GLBuffers.put(vertexArray, _vertexArray);
+ }
+ if(null!=_colorArray) {
+ _colorArray.flip();
+ GLBuffers.put(colorArray, _colorArray);
+ }
+ if(null!=_normalArray) {
+ _normalArray.flip();
+ GLBuffers.put(normalArray, _normalArray);
+ }
+ if(null!=_textCoordArray) {
+ _textCoordArray.flip();
+ GLBuffers.put(textCoordArray, _textCoordArray);
+ }
+ return true;
+ }
+ }
}
+ return false;
}
protected void padding(int type, int fill) {
@@ -934,15 +1103,19 @@ public class ImmModeSink {
switch (type) {
case VERTEX:
dest = vertexArray;
+ vElems++;
break;
case COLOR:
dest = colorArray;
+ cElems++;
break;
case NORMAL:
dest = normalArray;
+ nElems++;
break;
case TEXTCOORD:
dest = textCoordArray;
+ tElems++;
break;
}
@@ -953,26 +1126,28 @@ public class ImmModeSink {
}
}
+ final protected int glBufferUsage, initialElementCount;
+ final protected boolean useVBO;
protected int mode, modeOrig;
- protected int glBufferUsage, initialElementCount;
protected ByteBuffer buffer;
- protected int bSize, count, vboName;
+ protected int vboName;
public static final int VERTEX = 0;
public static final int COLOR = 1;
public static final int NORMAL = 2;
public static final int TEXTCOORD = 3;
- protected int vOffset, cOffset, nOffset, tOffset;
+ protected int vCount, cCount, nCount, tCount;
+ protected int vOffset, cOffset, nOffset, tOffset;
protected int vComps, cComps, nComps, tComps;
+ protected int vElems, cElems, nElems, tElems;
protected int vDataType, cDataType, nDataType, tDataType;
protected Buffer vertexArray, colorArray, normalArray, textCoordArray;
protected GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
protected boolean sealed, sealedGL, useGLSL;
protected boolean bufferEnabled, bufferWritten;
- protected GL gl;
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index 70c4d1e1b..80df9cd94 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -69,7 +69,7 @@ import com.jogamp.common.os.Platform;
* PMVMatrix can supplement {@link GL2ES2} applications w/ the
* lack of the described matrix functionality.
* </p>
- * <a name="storageDetails"><h3>Matrix storage details</h3></a>
+ * <a name="storageDetails"><h5>Matrix storage details</h5></a>
* <p>
* All matrices use a common FloatBuffer storage
* and are a {@link Buffers#slice2Float(Buffer, float[], int, int) sliced} representation of it.