aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java641
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java42
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java11
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java11
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java352
7 files changed, 799 insertions, 267 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.
diff --git a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
index 3f8a76535..62ff3aa09 100644
--- a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
+++ b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
@@ -115,10 +115,11 @@
package jogamp.opengl.glu;
-import javax.media.opengl.*;
-import javax.media.opengl.glu.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.GLUquadric;
+
import com.jogamp.opengl.util.ImmModeSink;
-import java.nio.*;
/**
* GLUquadricImpl.java
@@ -190,17 +191,19 @@ public class GLUquadricImpl implements GLUquadric {
ImmModeSink res = immModeSink;
if(useGLSL) {
- immModeSink = ImmModeSink.createGLSL (gl, GL.GL_STATIC_DRAW, 32,
- 3, GL.GL_FLOAT, // vertex
- 0, GL.GL_FLOAT, // color
- USE_NORM?3:0, normalType,// normal
- USE_TEXT?2:0, GL.GL_FLOAT); // texture
+ immModeSink = ImmModeSink.createGLSL (32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
} else {
- immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 32,
- 3, GL.GL_FLOAT, // vertex
- 0, GL.GL_FLOAT, // color
- USE_NORM?3:0, normalType,// normal
- USE_TEXT?2:0, GL.GL_FLOAT); // texture
+ immModeSink = ImmModeSink.createFixed(32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
}
return res;
}
@@ -430,7 +433,7 @@ public class GLUquadricImpl implements GLUquadric {
r = baseRadius;
for (j = 0; j < stacks; j++) {
float s = 0.0f;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (i = 0; i <= slices; i++) {
if (i == slices) {
x = sin(0.0f);
@@ -514,7 +517,7 @@ public class GLUquadricImpl implements GLUquadric {
float r2 = r1 + dr;
if (orientation == GLU.GLU_OUTSIDE) {
int s;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (s = 0; s <= slices; s++) {
float a;
if (s == slices)
@@ -532,7 +535,7 @@ public class GLUquadricImpl implements GLUquadric {
}
else {
int s;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (s = slices; s >= 0; s--) {
float a;
if (s == slices)
@@ -655,11 +658,10 @@ public class GLUquadricImpl implements GLUquadric {
int loops,
float startAngle,
float sweepAngle) {
- int i, j, max;
+ int i, j;
float[] sinCache = new float[CACHE_SIZE];
float[] cosCache = new float[CACHE_SIZE];
float angle;
- float x, y;
float sintemp, costemp;
float deltaRadius;
float radiusLow, radiusHigh;
@@ -770,7 +772,7 @@ public class GLUquadricImpl implements GLUquadric {
texHigh = radiusHigh / outerRadius / 2;
}
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (i = 0; i <= slices; i++) {
if (orientation == GLU.GLU_OUTSIDE) {
if (textureFlag) {
@@ -984,7 +986,7 @@ public class GLUquadricImpl implements GLUquadric {
// draw intermediate stacks as quad strips
for (i = imin; i < imax; i++) {
rho = i * drho;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
s = 0.0f;
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0f : j * dtheta;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
index aad56581b..4b4c7f2d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
@@ -77,11 +77,12 @@ public class MultisampleDemoES1 implements GLEventListener {
if (multisample) {
gl.glDisable(GL.GL_MULTISAMPLE);
}
- immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 40,
- 3, GL.GL_FLOAT, // vertex
- 0, GL.GL_FLOAT, // color
- 0, GL.GL_FLOAT,// normal
- 0, GL.GL_FLOAT); // texture
+ immModeSink = ImmModeSink.createFixed(40,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
final int numSteps = 20;
final double increment = Math.PI / numSteps;
final double radius = 1;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
index 8c9f53b82..4b05f1a42 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
@@ -61,11 +61,12 @@ public class OneTriangle {
// draw a triangle filling the window
gl.glLoadIdentity();
- ImmModeSink immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 3,
- 3, GL.GL_FLOAT, // vertex
- 3, GL.GL_FLOAT, // color
- 0, GL.GL_FLOAT,// normal
- 0, GL.GL_FLOAT); // texture
+ ImmModeSink immModeSink = ImmModeSink.createFixed(3*3,
+ 3, GL.GL_FLOAT, // vertex
+ 3, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
immModeSink.glBegin(GL.GL_TRIANGLES);
immModeSink.glColor3f( 1, 0, 0 );
immModeSink.glVertex2f( 0, 0 );
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
index c80455314..691e08ed2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
@@ -112,11 +112,12 @@ public class MultisampleDemoES2 implements GLEventListener {
// Using predef array names, see
// GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex);
- immModeSink = ImmModeSink.createGLSL(gl, GL.GL_STATIC_DRAW, 40,
+ immModeSink = ImmModeSink.createGLSL(40,
3, GL.GL_FLOAT, // vertex
4, GL.GL_FLOAT, // color
- 0, GL.GL_FLOAT,// normal
- 0, GL.GL_FLOAT); // texture
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
final int numSteps = 20;
final double increment = Math.PI / numSteps;
final double radius = 1;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java
new file mode 100644
index 000000000..05f78bc60
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java
@@ -0,0 +1,352 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.util;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2es1.GLUgl2es1;
+
+import org.junit.Test;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLArrayDataWrapper;
+import com.jogamp.opengl.util.GLBuffers;
+import com.jogamp.opengl.util.ImmModeSink;
+
+/**
+ * Testing the ImmModeSink w/ GL2ES1 context
+ */
+public class TestImmModeSinkES1NEWT extends UITestCase {
+ static int duration = 100;
+ static final int iWidth = 400;
+ static final int iHeight = 400;
+
+ static GLCapabilities getCaps(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return new GLCapabilities(GLProfile.get(profile));
+ }
+
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final GLWindow glad = GLWindow.create(reqGLCaps);
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+ glad.setSize(iWidth, iHeight);
+ glad.setVisible(true);
+
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display(); // initial resize/display
+
+ Thread.sleep(duration);
+
+ glad.destroy();
+ }
+
+ static class DemoGL2ES1Plain implements GLEventListener {
+ final boolean useArrayData;
+ final boolean useVBO;
+ final GLU glu;
+
+ final float[] vertices = new float[] { 0, 0, 0,
+ iWidth, 0, 0,
+ iWidth / 2, iHeight, 0 };
+
+ final float[] colors = new float[] { 1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1 };
+
+ final ByteBuffer bufferAll;
+ final int bufferVOffset, bufferCOffset;
+ final int bufferVSize, bufferCSize;
+ final FloatBuffer bufferC, bufferV;
+ final int[] vboName = new int[] { 0 };
+ final GLArrayDataWrapper arrayC, arrayV;
+
+ DemoGL2ES1Plain(boolean useArrayData, boolean useVBO) {
+ this.useArrayData = useArrayData;
+ this.useVBO = useVBO;
+ this.glu = new GLUgl2es1();
+
+ bufferAll = Buffers.newDirectByteBuffer( ( colors.length + vertices.length ) * Buffers.SIZEOF_FLOAT );
+
+ bufferVOffset = 0;
+ bufferVSize = 3*3*GLBuffers.sizeOfGLType(GL.GL_FLOAT);
+ bufferCOffset = bufferVSize;
+ bufferCSize = 3*3*GLBuffers.sizeOfGLType(GL.GL_FLOAT);
+
+ bufferV = (FloatBuffer) GLBuffers.sliceGLBuffer(bufferAll, bufferVOffset, bufferVSize, GL.GL_FLOAT);
+ bufferV.put(vertices, 0, vertices.length).rewind();
+ bufferC = (FloatBuffer) GLBuffers.sliceGLBuffer(bufferAll, bufferCOffset, bufferCSize, GL.GL_FLOAT);
+ bufferC.put(colors, 0, colors.length).rewind();
+
+ System.err.println("bufferAll: "+bufferAll+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferAll));
+ System.err.println("bufferV: off "+bufferVOffset+", size "+bufferVSize+": "+bufferV+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferV));
+ System.err.println("bufferC: off "+bufferCOffset+", size "+bufferCSize+": "+bufferC+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferC));
+
+ if(useArrayData) {
+ arrayV = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, 3, GL.GL_FLOAT, false, 0,
+ bufferV, 0, bufferVOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
+
+ arrayC = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, 3, GL.GL_FLOAT, false, 0,
+ bufferC, 0, bufferCOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
+ } else {
+ arrayV = null;
+ arrayC = null;
+ }
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ System.err.println("GL_VENDOR "+gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER "+gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION "+gl.glGetString(GL.GL_VERSION));
+ if(useVBO) {
+ gl.glGenBuffers(1, vboName, 0);
+ if(0 == vboName[0]) {
+ throw new GLException("glGenBuffers didn't return valid VBO name");
+ }
+ }
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glMatrixMode( GL2ES1.GL_PROJECTION );
+ gl.glLoadIdentity();
+
+ // coordinate system origin at lower left with width and height same as the window
+ glu.gluOrtho2D( 0.0f, width, 0.0f, height );
+
+ gl.glMatrixMode( GL2ES1.GL_MODELVIEW );
+ gl.glLoadIdentity();
+
+ gl.glViewport( 0, 0, width, height );
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glClear( GL.GL_COLOR_BUFFER_BIT );
+
+ // draw a triangle filling the window
+ gl.glLoadIdentity();
+
+ if(useVBO) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName[0]);
+ gl.glBufferData(GL.GL_ARRAY_BUFFER, bufferAll.limit(), bufferAll, GL.GL_STATIC_DRAW);
+ if(useArrayData) {
+ arrayV.setVBOName(vboName[0]);
+ arrayC.setVBOName(vboName[0]);
+ }
+ }
+
+ gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+ if(useArrayData) {
+ gl.glVertexPointer(arrayV);
+ } else {
+ if(useVBO) {
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, bufferVOffset);
+ } else {
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, bufferV);
+ }
+ }
+
+ gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+ if(useArrayData) {
+ gl.glColorPointer(arrayC);
+ } else {
+ if(useVBO) {
+ gl.glColorPointer(3, GL.GL_FLOAT, 0, bufferCOffset);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, 0, bufferC);
+ }
+ }
+
+ if(useVBO) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+
+ gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
+ gl.glFlush();
+
+ gl.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+ gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ if(0 != vboName[0]) {
+ gl.glDeleteBuffers(1, vboName, 0);
+ vboName[0] = 0;
+ }
+ }
+ }
+
+ static class DemoGL2ES1ImmModeSink implements GLEventListener {
+ final ImmModeSink ims;
+ final GLU glu;
+
+ DemoGL2ES1ImmModeSink(boolean useVBO) {
+ ims = ImmModeSink.createFixed(3*3,
+ 3, GL.GL_FLOAT, // vertex
+ 3, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ useVBO ? GL.GL_STATIC_DRAW : 0);
+ glu = new GLUgl2es1();
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ System.err.println("GL_VENDOR "+gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER "+gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION "+gl.glGetString(GL.GL_VERSION));
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glMatrixMode( GL2ES1.GL_PROJECTION );
+ gl.glLoadIdentity();
+
+ // coordinate system origin at lower left with width and height same as the window
+ glu.gluOrtho2D( 0.0f, width, 0.0f, height );
+
+ gl.glMatrixMode( GL2ES1.GL_MODELVIEW );
+ gl.glLoadIdentity();
+
+ gl.glViewport( 0, 0, width, height );
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glClear( GL.GL_COLOR_BUFFER_BIT );
+
+ // draw a triangle filling the window
+ gl.glLoadIdentity();
+
+ ims.glBegin(GL.GL_TRIANGLES);
+ ims.glColor3f( 1, 0, 0 );
+ ims.glVertex2f( 0, 0 );
+ ims.glColor3f( 0, 1, 0 );
+ ims.glVertex2f( iWidth, 0 );
+ ims.glColor3f( 0, 0, 1 );
+ ims.glVertex2f( iWidth / 2, iHeight );
+ ims.glEnd(gl, true);
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ }
+ }
+
+ @Test
+ public void test01Plain__GL2ES1_VBOOffUsePlain() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(false, false));
+ }
+
+ @Test
+ public void test02Plain__GL2ES1_VBOOffUseArrayData() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(true, false));
+ }
+
+ @Test
+ public void test03Plain__GL2ES1_VBOOnUsePlain() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(false, true));
+ }
+
+ @Test
+ public void test04Plain__GL2ES1_VBOOnUseArrayData() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(true, true));
+ }
+
+ @Test
+ public void test05ImmSinkGL2ES1_VBOOff() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1ImmModeSink(false));
+ }
+
+ @Test
+ public void test06ImmSinkGL2ES1_VBOOn() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1ImmModeSink(true));
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ duration = MiscUtils.atoi(args[++i], duration);
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestImmModeSinkES1NEWT.class.getName());
+ }
+
+}