JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
ImmModeSink.java
Go to the documentation of this file.
1
2package com.jogamp.opengl.util;
3
4import java.nio.Buffer;
5import java.nio.ByteBuffer;
6import java.nio.IntBuffer;
7import java.nio.ShortBuffer;
8import java.util.ArrayList;
9import java.util.Iterator;
10
11import com.jogamp.opengl.GL;
12import com.jogamp.opengl.GL2ES1;
13import com.jogamp.opengl.GL2ES2;
14import com.jogamp.opengl.GLException;
15import com.jogamp.opengl.fixedfunc.GLPointerFunc;
16
17import jogamp.opengl.Debug;
18
19import com.jogamp.common.ExceptionUtils;
20import com.jogamp.common.nio.Buffers;
21import com.jogamp.common.os.Platform;
22import com.jogamp.common.util.PropertyAccess;
23import com.jogamp.opengl.util.glsl.ShaderState;
24
25/**
26 * <p>
27 * Immediate mode sink, implementing OpenGL fixed function subset of immediate mode operations, i.e.
28 * <pre>
29 * glBegin();
30 * glVertex3f(1f, 1f, 1f);
31 * glColor4f(1f, 1f, 1f, 1f);
32 * ...
33 * glEnd();
34 * </pre>
35 * Implementation buffers all vertex, colors, normal and texture-coord elements in their respective buffers
36 * to be either rendered directly via {@link #glEnd(GL)} or to be added to an internal display list
37 * via {@link #glEnd(GL, boolean) glEnd(gl, false)} for deferred rendering via {@link #draw(GL, boolean)}.
38 * </p>
39 * <a name="storageDetails"><h5>Buffer storage and it's creation via {@link #createFixed(int, int, int, int, int, int, int, int, int, int) createFixed(..)}
40 * and {@link #createGLSL(int, int, int, int, int, int, int, int, int, int, ShaderState) createGLSL(..)}</h5></a>
41 * <p>
42 * If unsure whether <i>colors</i>, <i>normals</i> and <i>textures</i> will be used,
43 * simply add them with an expected component count.
44 * This implementation will only render buffers which are being filled.<br/>
45 * The buffer growing implementation will only grow the exceeded buffers, unused buffers are not resized.
46 * </p>
47 * <p>
48 * Note: Optional types, i.e. color, must be either not used or used w/ the same element count as vertex, etc.
49 * This is a semantic constraint, same as in the original OpenGL spec.
50 * </p>
51 */
52public class ImmModeSink {
53 protected static final boolean DEBUG_BEGIN_END;
54 protected static final boolean DEBUG_DRAW;
55 protected static final boolean DEBUG_BUFFER;
56
57 static {
58 Debug.initSingleton();
59 DEBUG_BEGIN_END = PropertyAccess.isPropertyDefined("jogl.debug.ImmModeSink.BeginEnd", true);
60 DEBUG_DRAW = PropertyAccess.isPropertyDefined("jogl.debug.ImmModeSink.Draw", true);
61 DEBUG_BUFFER = PropertyAccess.isPropertyDefined("jogl.debug.ImmModeSink.Buffer", true);
62 }
63
64 public static final int GL_QUADS = 0x0007; // Needs data manipulation on ES1/ES2
65 public static final int GL_QUAD_STRIP = 0x0008;
66 public static final int GL_POLYGON = 0x0009;
67
68 /**
69 * Uses a GL2ES1, or ES2 fixed function emulation immediate mode sink
70 * <p>
71 * See <a href="#storageDetails"> buffer storage details</a>.
72 * </p>
73 *
74 * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
75 * @param vComps mandatory vertex component count, should be 2, 3 or 4.
76 * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
77 * @param cComps optional color component count, may be 0, 3 or 4
78 * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
79 * @param nComps optional normal component count, may be 0, 3 or 4
80 * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
81 * @param tComps optional texture-coordinate component count, may be 0, 2 or 3
82 * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
83 * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
84 * set to <code>0</code> for no VBO usage
85 */
86 public static ImmModeSink createFixed(final int initialElementCount,
87 final int vComps, final int vDataType,
88 final int cComps, final int cDataType,
89 final int nComps, final int nDataType,
90 final int tComps, final int tDataType,
91 final int glBufferUsage) {
92 return new ImmModeSink(initialElementCount,
93 vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
94 false, glBufferUsage, null, 0);
95 }
96
97 /**
98 * Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given ShaderState.
99 * <p>
100 * See <a href="#storageDetails"> buffer storage details</a>.
101 * </p>
102 *
103 * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
104 * @param vComps mandatory vertex component count, should be 2, 3 or 4.
105 * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
106 * @param cComps optional color component count, may be 0, 3 or 4
107 * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
108 * @param nComps optional normal component count, may be 0, 3 or 4
109 * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
110 * @param tComps optional texture-coordinate component count, may be 0, 2 or 3
111 * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
112 * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
113 * set to <code>0</code> for no VBO usage
114 * @param st ShaderState to locate the vertex attributes
115 * @see #draw(GL, boolean)
116 * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
117 * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
118 */
119 public static ImmModeSink createGLSL(final int initialElementCount,
120 final int vComps, final int vDataType,
121 final int cComps, final int cDataType,
122 final int nComps, final int nDataType,
123 final int tComps, final int tDataType,
124 final int glBufferUsage, final ShaderState st) {
125 return new ImmModeSink(initialElementCount,
126 vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
127 true, glBufferUsage, st, 0);
128 }
129
130 /**
131 * Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given shader-program.
132 * <p>
133 * See <a href="#storageDetails"> buffer storage details</a>.
134 * </p>
135 *
136 * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
137 * @param vComps mandatory vertex component count, should be 2, 3 or 4.
138 * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
139 * @param cComps optional color component count, may be 0, 3 or 4
140 * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
141 * @param nComps optional normal component count, may be 0, 3 or 4
142 * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
143 * @param tComps optional texture-coordinate component count, may be 0, 2 or 3
144 * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
145 * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
146 * set to <code>0</code> for no VBO usage
147 * @param shaderProgram shader-program name to locate the vertex attributes
148 * @see #draw(GL, boolean)
149 * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
150 * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
151 */
152 public static ImmModeSink createGLSL(final int initialElementCount,
153 final int vComps, final int vDataType,
154 final int cComps, final int cDataType,
155 final int nComps, final int nDataType,
156 final int tComps, final int tDataType,
157 final int glBufferUsage, final int shaderProgram) {
158 return new ImmModeSink(initialElementCount,
159 vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
160 true, glBufferUsage, null, shaderProgram);
161 }
162
163 public void destroy(final GL gl) {
164 destroyList(gl);
165
166 vboSet.destroy(gl);
167 }
168
169 public void reset() {
170 reset(null);
171 }
172
173 public void reset(final GL gl) {
174 destroyList(gl);
175 vboSet.reset(gl);
176 }
177
178 @Override
179 public String toString() {
180 final StringBuilder sb = new StringBuilder("ImmModeSink[");
181 sb.append(",\n\tVBO list: "+vboSetList.size()+" [");
182 for(final Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; ) {
183 sb.append("\n\t");
184 sb.append( i.next() );
185 }
186 if(vboSetList.size()>0) {
187 sb.append("\n\t],\nVBO current: NOP]");
188 } else {
189 sb.append("\n\t],\nVBO current: \n");
190 sb.append(vboSet);
191 sb.append("\n]");
192 }
193 return sb.toString();
194 }
195
196 public void draw(final GL gl, final boolean disableBufferAfterDraw) {
197 if(DEBUG_DRAW) {
198 System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
199 }
200 int n=0;
201 for(int i=0; i<vboSetList.size(); i++, n++) {
202 vboSetList.get(i).draw(gl, null, disableBufferAfterDraw, n);
203 }
204 }
205
206 public void draw(final GL gl, final Buffer indices, final boolean disableBufferAfterDraw) {
207 if(DEBUG_DRAW) {
208 System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
209 }
210 int n=0;
211 for(int i=0; i<vboSetList.size(); i++, n++) {
212 vboSetList.get(i).draw(gl, indices, disableBufferAfterDraw, n);
213 }
214 }
215
216 public void glBegin(int mode) {
217 vboSet.modeOrig = mode;
218 switch(mode) {
219 case GL_QUAD_STRIP:
221 break;
222 case GL_POLYGON:
223 mode=GL.GL_TRIANGLE_FAN;
224 break;
225 }
226 vboSet.mode = mode;
227 if(DEBUG_BEGIN_END) {
228 System.err.println("ImmModeSink.glBegin("+vboSet.modeOrig+" -> "+vboSet.mode+")");
229 }
230 vboSet.checkSeal(false);
231 }
232
233 public final void glEnd(final GL gl) {
234 glEnd(gl, null, true);
235 }
236
237 public void glEnd(final GL gl, final boolean immediateDraw) {
238 glEnd(gl, null, immediateDraw);
239 }
240
241 public final void glEnd(final GL gl, final Buffer indices) {
242 glEnd(gl, indices, true);
243 }
244
245 private void glEnd(final GL gl, final Buffer indices, final boolean immediateDraw) {
246 if(DEBUG_BEGIN_END) {
247 System.err.println("ImmModeSink START glEnd(immediate: "+immediateDraw+")");
248 }
249 if(immediateDraw) {
250 vboSet.seal(gl, true);
251 vboSet.draw(gl, indices, true, -1);
252 reset(gl);
253 } else {
254 vboSet.seal(gl, true);
255 vboSet.enableBuffer(gl, false);
256 vboSetList.add(vboSet);
257 vboSet = vboSet.regenerate(gl);
258 }
259 if(DEBUG_BEGIN_END) {
260 System.err.println("ImmModeSink END glEnd(immediate: "+immediateDraw+")");
261 }
262 }
263
264 public void glVertexv(final Buffer v) {
265 vboSet.glVertexv(v);
266 }
267 public void glNormalv(final Buffer v) {
268 vboSet.glNormalv(v);
269 }
270 public void glColorv(final Buffer v) {
271 vboSet.glColorv(v);
272 }
273 public void glTexCoordv(final Buffer v) {
274 vboSet.glTexCoordv(v);
275 }
276
277 public final void glVertex2f(final float x, final float y) {
278 vboSet.glVertex2f(x,y);
279 }
280
281 public final void glVertex3f(final float x, final float y, final float z) {
282 vboSet.glVertex3f(x,y,z);
283 }
284
285 public final void glNormal3f(final float x, final float y, final float z) {
286 vboSet.glNormal3f(x,y,z);
287 }
288
289 public final void glColor3f(final float x, final float y, final float z) {
290 vboSet.glColor3f(x,y,z);
291 }
292
293 public final void glColor4f(final float x, final float y, final float z, final float a) {
294 vboSet.glColor4f(x,y,z, a);
295 }
296
297 public final void glTexCoord2f(final float x, final float y) {
298 vboSet.glTexCoord2f(x,y);
299 }
300
301 public final void glTexCoord3f(final float x, final float y, final float z) {
302 vboSet.glTexCoord3f(x,y,z);
303 }
304
305 public final void glVertex2s(final short x, final short y) {
306 vboSet.glVertex2s(x,y);
307 }
308
309 public final void glVertex3s(final short x, final short y, final short z) {
310 vboSet.glVertex3s(x,y,z);
311 }
312
313 public final void glNormal3s(final short x, final short y, final short z) {
314 vboSet.glNormal3s(x,y,z);
315 }
316
317 public final void glColor3s(final short x, final short y, final short z) {
318 vboSet.glColor3s(x,y,z);
319 }
320
321 public final void glColor4s(final short x, final short y, final short z, final short a) {
322 vboSet.glColor4s(x,y,z,a);
323 }
324
325 public final void glTexCoord2s(final short x, final short y) {
326 vboSet.glTexCoord2s(x,y);
327 }
328
329 public final void glTexCoord3s(final short x, final short y, final short z) {
330 vboSet.glTexCoord3s(x,y,z);
331 }
332
333 public final void glVertex2b(final byte x, final byte y) {
334 vboSet.glVertex2b(x,y);
335 }
336
337 public final void glVertex3b(final byte x, final byte y, final byte z) {
338 vboSet.glVertex3b(x,y,z);
339 }
340
341 public final void glNormal3b(final byte x, final byte y, final byte z) {
342 vboSet.glNormal3b(x,y,z);
343 }
344
345 public final void glColor3b(final byte x, final byte y, final byte z) {
346 vboSet.glColor3b(x,y,z);
347 }
348
349 public final void glColor3ub(final byte x, final byte y, final byte z) {
350 vboSet.glColor3ub(x,y,z);
351 }
352
353 public final void glColor4b(final byte x, final byte y, final byte z, final byte a) {
354 vboSet.glColor4b(x,y,z,a);
355 }
356
357 public final void glColor4ub(final byte x, final byte y, final byte z, final byte a) {
358 vboSet.glColor4ub(x,y,z,a);
359 }
360
361 public final void glTexCoord2b(final byte x, final byte y) {
362 vboSet.glTexCoord2b(x,y);
363 }
364
365 public final void glTexCoord3b(final byte x, final byte y, final byte z) {
366 vboSet.glTexCoord3b(x,y,z);
367 }
368
369 protected ImmModeSink(final int initialElementCount,
370 final int vComps, final int vDataType,
371 final int cComps, final int cDataType,
372 final int nComps, final int nDataType,
373 final int tComps, final int tDataType,
374 final boolean useGLSL, final int glBufferUsage, final ShaderState st, final int shaderProgram) {
375 vboSet = new VBOSet(initialElementCount,
376 vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
377 useGLSL, glBufferUsage, st, shaderProgram);
378 this.vboSetList = new ArrayList<VBOSet>();
379 }
380
381 public boolean getUseVBO() { return vboSet.getUseVBO(); }
382
383 /**
384 * Returns the additional element count if buffer resize is required.
385 * @see #setResizeElementCount(int)
386 */
387 public int getResizeElementCount() { return vboSet.getResizeElementCount(); }
388
389 /**
390 * Sets the additional element count if buffer resize is required,
391 * defaults to <code>initialElementCount</code> of factory method.
392 * @see #createFixed(int, int, int, int, int, int, int, int, int, int)
393 * @see #createGLSL(int, int, int, int, int, int, int, int, int, int, ShaderState)
394 */
395 public void setResizeElementCount(final int v) { vboSet.setResizeElementCount(v); }
396
397 private void destroyList(final GL gl) {
398 for(int i=0; i<vboSetList.size(); i++) {
399 vboSetList.get(i).destroy(gl);
400 }
401 vboSetList.clear();
402 }
403
404 private VBOSet vboSet;
405 private final ArrayList<VBOSet> vboSetList;
406
407 protected static class VBOSet {
408 protected VBOSet (final int initialElementCount,
409 final int vComps, final int vDataType,
410 final int cComps, final int cDataType,
411 final int nComps, final int nDataType,
412 final int tComps, final int tDataType,
413 final boolean useGLSL, final int glBufferUsage, final ShaderState st, final int shaderProgram) {
414 // final ..
415 this.glBufferUsage=glBufferUsage;
416 this.initialElementCount=initialElementCount;
417 this.useVBO = 0 != glBufferUsage;
418 this.useGLSL=useGLSL;
419 this.shaderState = st;
420 this.shaderProgram = shaderProgram;
421
422 if(useGLSL && null == shaderState && 0 == shaderProgram) {
423 throw new IllegalArgumentException("Using GLSL but neither a valid shader-program nor ShaderState has been passed!");
424 }
425 // variable ..
426 this.resizeElementCount=initialElementCount;
427 this.vDataType=vDataType;
428 this.vDataTypeSigned=GLBuffers.isSignedGLType(vDataType);
429 this.vComps=vComps;
430 this.vCompsBytes=vComps * GLBuffers.sizeOfGLType(vDataType);
431 this.cDataType=cDataType;
432 this.cDataTypeSigned=GLBuffers.isSignedGLType(cDataType);
433 this.cComps=cComps;
434 this.cCompsBytes=cComps * GLBuffers.sizeOfGLType(cDataType);
435 this.nDataType=nDataType;
436 this.nDataTypeSigned=GLBuffers.isSignedGLType(nDataType);
437 this.nComps=nComps;
438 this.nCompsBytes=nComps * GLBuffers.sizeOfGLType(nDataType);
439 this.tDataType=tDataType;
440 this.tDataTypeSigned=GLBuffers.isSignedGLType(tDataType);
441 this.tComps=tComps;
442 this.tCompsBytes=tComps * GLBuffers.sizeOfGLType(tDataType);
443 this.vboName = 0;
444
445 this.vCount=0;
446 this.cCount=0;
447 this.nCount=0;
448 this.tCount=0;
449 this.vElems=0;
450 this.cElems=0;
451 this.nElems=0;
452 this.tElems=0;
453
454 this.pageSize = Platform.getMachineDataInfo().pageSizeInBytes();
455
456 reallocateBuffer(initialElementCount);
457 rewind();
458
459 this.sealed=false;
460 this.sealedGL=false;
461 this.mode = 0;
462 this.modeOrig = 0;
463 this.bufferEnabled=false;
464 this.bufferWritten=false;
465 this.bufferWrittenOnce=false;
466 this.glslLocationSet = false;
467 }
468
469 protected int getResizeElementCount() { return resizeElementCount; }
470 protected void setResizeElementCount(final int v) { resizeElementCount=v; }
471
472 protected boolean getUseVBO() { return useVBO; }
473
474 protected final VBOSet regenerate(final GL gl) {
475 return new VBOSet(initialElementCount, vComps,
476 vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
477 useGLSL, glBufferUsage, shaderState, shaderProgram);
478 }
479
480 protected void checkSeal(final boolean test) throws GLException {
481 if(0==mode) {
482 throw new GLException("No mode set yet, call glBegin(mode) first:\n\t"+this);
483 }
484 if(sealed!=test) {
485 if(test) {
486 throw new GLException("Not Sealed yet, call glEnd() first:\n\t"+this);
487 } else {
488 throw new GLException("Already Sealed, can't modify VBO after glEnd():\n\t"+this);
489 }
490 }
491 }
492
493 private boolean usingShaderProgram = false;
494
495 protected void useShaderProgram(final GL2ES2 gl, final boolean force) {
496 if( force || !usingShaderProgram ) {
497 if(null != shaderState) {
498 shaderState.useProgram(gl, true);
499 } else /* if( 0 != shaderProgram) */ {
500 gl.glUseProgram(shaderProgram);
501 }
502 usingShaderProgram = true;
503 }
504 }
505
506 protected void draw(final GL gl, final Buffer indices, final boolean disableBufferAfterDraw, final int i)
507 {
508 enableBuffer(gl, true);
509
510 if(null != shaderState || 0 != shaderProgram) {
511 useShaderProgram(gl.getGL2ES2(), false);
512 }
513
514 if(DEBUG_DRAW) {
515 System.err.println("ImmModeSink.draw["+i+"].0 (disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
516 }
517
518 if (buffer!=null) {
519 if(null==indices) {
520 if ( GL_QUADS == mode && !gl.isGL2() ) {
521 for (int j = 0; j < vElems - 3; j += 4) {
523 }
524 } else {
525 gl.glDrawArrays(mode, 0, vElems);
526 }
527 } else {
528 // FIXME: Impl. VBO usage .. or unroll.
529 if( !gl.getContext().isCPUDataSourcingAvail() ) {
530 throw new GLException("CPU data sourcing n/a w/ "+gl.getContext());
531 }
532 final int type;
533 if(indices instanceof ByteBuffer) {
534 type = GL.GL_UNSIGNED_BYTE;
535 } else if(indices instanceof ShortBuffer) {
536 type = GL.GL_UNSIGNED_SHORT;
537 } else if(indices instanceof IntBuffer) {
538 type = GL.GL_UNSIGNED_INT;
539 } else {
540 throw new GLException("Given Buffer Class not supported: "+indices.getClass()+", should be ubyte, ushort or uint:\n\t"+this);
541 }
542 final int idxLen = indices.remaining();
543 final int idx0 = indices.position();
544
545 if ( GL_QUADS == mode && !gl.isGL2() ) {
546 if( GL.GL_UNSIGNED_BYTE == type ) {
547 final ByteBuffer b = (ByteBuffer) indices;
548 for (int j = 0; j < idxLen; j++) {
549 gl.glDrawArrays(GL.GL_TRIANGLE_FAN, 0x000000ff & b.get(idx0+j), 4);
550 }
551 } else if( GL.GL_UNSIGNED_SHORT == type ){
552 final ShortBuffer b = (ShortBuffer) indices;
553 for (int j = 0; j < idxLen; j++) {
554 gl.glDrawArrays(GL.GL_TRIANGLE_FAN, 0x0000ffff & b.get(idx0+j), 4);
555 }
556 } else {
557 final IntBuffer b = (IntBuffer) indices;
558 for (int j = 0; j < idxLen; j++) {
559 gl.glDrawArrays(GL.GL_TRIANGLE_FAN, 0xffffffff & b.get(idx0+j), 4);
560 }
561 }
562 } else {
563 ((GL2ES1)gl).glDrawElements(mode, idxLen, type, indices);
564 // GL2: gl.glDrawRangeElements(mode, 0, idxLen-1, idxLen, type, indices);
565 }
566 }
567 }
568
569 if(disableBufferAfterDraw) {
570 enableBuffer(gl, false);
571 }
572
573 if(DEBUG_DRAW) {
574 System.err.println("ImmModeSink.draw["+i+"].X (disableBufferAfterDraw: "+disableBufferAfterDraw+")");
575 }
576 }
577
578 public void glVertexv(final Buffer v) {
579 checkSeal(false);
580 Buffers.put(vertexArray, v);
581 }
582 public void glNormalv(final Buffer v) {
583 checkSeal(false);
584 Buffers.put(normalArray, v);
585 }
586 public void glColorv(final Buffer v) {
587 checkSeal(false);
588 Buffers.put(colorArray, v);
589 }
590 public void glTexCoordv(final Buffer v) {
591 checkSeal(false);
592 Buffers.put(textCoordArray, v);
593 }
594
595 public void glVertex2b(final byte x, final byte y) {
596 checkSeal(false);
597 growBuffer(VERTEX);
598 if(vComps>0)
599 Buffers.putNb(vertexArray, vDataTypeSigned, x, true);
600 if(vComps>1)
601 Buffers.putNb(vertexArray, vDataTypeSigned, y, true);
602 countAndPadding(VERTEX, vComps-2);
603 }
604 public void glVertex3b(final byte x, final byte y, final byte z) {
605 checkSeal(false);
606 growBuffer(VERTEX);
607 if(vComps>0)
608 Buffers.putNb(vertexArray, vDataTypeSigned, x, true);
609 if(vComps>1)
610 Buffers.putNb(vertexArray, vDataTypeSigned, y, true);
611 if(vComps>2)
612 Buffers.putNb(vertexArray, vDataTypeSigned, z, true);
613 countAndPadding(VERTEX, vComps-3);
614 }
615 public void glVertex2s(final short x, final short y) {
616 checkSeal(false);
617 growBuffer(VERTEX);
618 if(vComps>0)
619 Buffers.putNs(vertexArray, vDataTypeSigned, x, true);
620 if(vComps>1)
621 Buffers.putNs(vertexArray, vDataTypeSigned, y, true);
622 countAndPadding(VERTEX, vComps-2);
623 }
624 public void glVertex3s(final short x, final short y, final short z) {
625 checkSeal(false);
626 growBuffer(VERTEX);
627 if(vComps>0)
628 Buffers.putNs(vertexArray, vDataTypeSigned, x, true);
629 if(vComps>1)
630 Buffers.putNs(vertexArray, vDataTypeSigned, y, true);
631 if(vComps>2)
632 Buffers.putNs(vertexArray, vDataTypeSigned, z, true);
633 countAndPadding(VERTEX, vComps-3);
634 }
635 public void glVertex2f(final float x, final float y) {
636 checkSeal(false);
637 growBuffer(VERTEX);
638 if(vComps>0)
639 Buffers.putNf(vertexArray, vDataTypeSigned, x);
640 if(vComps>1)
641 Buffers.putNf(vertexArray, vDataTypeSigned, y);
642 countAndPadding(VERTEX, vComps-2);
643 }
644 public void glVertex3f(final float x, final float y, final float z) {
645 checkSeal(false);
646 growBuffer(VERTEX);
647 if(vComps>0)
648 Buffers.putNf(vertexArray, vDataTypeSigned, x);
649 if(vComps>1)
650 Buffers.putNf(vertexArray, vDataTypeSigned, y);
651 if(vComps>2)
652 Buffers.putNf(vertexArray, vDataTypeSigned, z);
653 countAndPadding(VERTEX, vComps-3);
654 }
655
656 public void glNormal3b(final byte x, final byte y, final byte z) {
657 checkSeal(false);
658 growBuffer(NORMAL);
659 if(nComps>0)
660 Buffers.putNb(normalArray, nDataTypeSigned, x, true);
661 if(nComps>1)
662 Buffers.putNb(normalArray, nDataTypeSigned, y, true);
663 if(nComps>2)
664 Buffers.putNb(normalArray, nDataTypeSigned, z, true);
665 countAndPadding(NORMAL, nComps-3);
666 }
667 public void glNormal3s(final short x, final short y, final short z) {
668 checkSeal(false);
669 growBuffer(NORMAL);
670 if(nComps>0)
671 Buffers.putNs(normalArray, nDataTypeSigned, x, true);
672 if(nComps>1)
673 Buffers.putNs(normalArray, nDataTypeSigned, y, true);
674 if(nComps>2)
675 Buffers.putNs(normalArray, nDataTypeSigned, z, true);
676 countAndPadding(NORMAL, nComps-3);
677 }
678 public void glNormal3f(final float x, final float y, final float z) {
679 checkSeal(false);
680 growBuffer(NORMAL);
681 if(nComps>0)
682 Buffers.putNf(normalArray, nDataTypeSigned, x);
683 if(nComps>1)
684 Buffers.putNf(normalArray, nDataTypeSigned, y);
685 if(nComps>2)
686 Buffers.putNf(normalArray, nDataTypeSigned, z);
687 countAndPadding(NORMAL, nComps-3);
688 }
689
690 public void glColor3b(final byte r, final byte g, final byte b) {
691 checkSeal(false);
692 growBuffer(COLOR);
693 if(cComps>0)
694 Buffers.putNb(colorArray, cDataTypeSigned, r, true);
695 if(cComps>1)
696 Buffers.putNb(colorArray, cDataTypeSigned, g, true);
697 if(cComps>2)
698 Buffers.putNb(colorArray, cDataTypeSigned, b, true);
699 countAndPadding(COLOR, cComps-3);
700 }
701 public void glColor3ub(final byte r, final byte g, final byte b) {
702 checkSeal(false);
703 growBuffer(COLOR);
704 if(cComps>0)
705 Buffers.putNb(colorArray, cDataTypeSigned, r, false);
706 if(cComps>1)
707 Buffers.putNb(colorArray, cDataTypeSigned, g, false);
708 if(cComps>2)
709 Buffers.putNb(colorArray, cDataTypeSigned, b, false);
710 countAndPadding(COLOR, cComps-3);
711 }
712 public void glColor4b(final byte r, final byte g, final byte b, final byte a) {
713 checkSeal(false);
714 growBuffer(COLOR);
715 if(cComps>0)
716 Buffers.putNb(colorArray, cDataTypeSigned, r, true);
717 if(cComps>1)
718 Buffers.putNb(colorArray, cDataTypeSigned, g, true);
719 if(cComps>2)
720 Buffers.putNb(colorArray, cDataTypeSigned, b, true);
721 if(cComps>3)
722 Buffers.putNb(colorArray, cDataTypeSigned, a, true);
723 countAndPadding(COLOR, cComps-4);
724 }
725 public void glColor4ub(final byte r, final byte g, final byte b, final byte a) {
726 checkSeal(false);
727 growBuffer(COLOR);
728 if(cComps>0)
729 Buffers.putNb(colorArray, cDataTypeSigned, r, false);
730 if(cComps>1)
731 Buffers.putNb(colorArray, cDataTypeSigned, g, false);
732 if(cComps>2)
733 Buffers.putNb(colorArray, cDataTypeSigned, b, false);
734 if(cComps>3)
735 Buffers.putNb(colorArray, cDataTypeSigned, a, false);
736 countAndPadding(COLOR, cComps-4);
737 }
738 public void glColor3s(final short r, final short g, final short b) {
739 checkSeal(false);
740 growBuffer(COLOR);
741 if(cComps>0)
742 Buffers.putNs(colorArray, cDataTypeSigned, r, true);
743 if(cComps>1)
744 Buffers.putNs(colorArray, cDataTypeSigned, g, true);
745 if(cComps>2)
746 Buffers.putNs(colorArray, cDataTypeSigned, b, true);
747 countAndPadding(COLOR, cComps-3);
748 }
749 public void glColor4s(final short r, final short g, final short b, final short a) {
750 checkSeal(false);
751 growBuffer(COLOR);
752 if(cComps>0)
753 Buffers.putNs(colorArray, cDataTypeSigned, r, true);
754 if(cComps>1)
755 Buffers.putNs(colorArray, cDataTypeSigned, g, true);
756 if(cComps>2)
757 Buffers.putNs(colorArray, cDataTypeSigned, b, true);
758 if(cComps>3)
759 Buffers.putNs(colorArray, cDataTypeSigned, a, true);
760 countAndPadding(COLOR, cComps-4);
761 }
762 public void glColor3f(final float r, final float g, final float b) {
763 checkSeal(false);
764 growBuffer(COLOR);
765 if(cComps>0)
766 Buffers.putNf(colorArray, cDataTypeSigned, r);
767 if(cComps>1)
768 Buffers.putNf(colorArray, cDataTypeSigned, g);
769 if(cComps>2)
770 Buffers.putNf(colorArray, cDataTypeSigned, b);
771 countAndPadding(COLOR, cComps-3);
772 }
773 public void glColor4f(final float r, final float g, final float b, final float a) {
774 checkSeal(false);
775 growBuffer(COLOR);
776 if(cComps>0)
777 Buffers.putNf(colorArray, cDataTypeSigned, r);
778 if(cComps>1)
779 Buffers.putNf(colorArray, cDataTypeSigned, g);
780 if(cComps>2)
781 Buffers.putNf(colorArray, cDataTypeSigned, b);
782 if(cComps>3)
783 Buffers.putNf(colorArray, cDataTypeSigned, a);
784 countAndPadding(COLOR, cComps-4);
785 }
786
787 public void glTexCoord2b(final byte x, final byte y) {
788 checkSeal(false);
789 growBuffer(TEXTCOORD);
790 if(tComps>0)
791 Buffers.putNb(textCoordArray, tDataTypeSigned, x, true);
792 if(tComps>1)
793 Buffers.putNb(textCoordArray, tDataTypeSigned, y, true);
794 countAndPadding(TEXTCOORD, tComps-2);
795 }
796 public void glTexCoord3b(final byte x, final byte y, final byte z) {
797 checkSeal(false);
798 growBuffer(TEXTCOORD);
799 if(tComps>0)
800 Buffers.putNb(textCoordArray, tDataTypeSigned, x, true);
801 if(tComps>1)
802 Buffers.putNb(textCoordArray, tDataTypeSigned, y, true);
803 if(tComps>2)
804 Buffers.putNb(textCoordArray, tDataTypeSigned, z, true);
805 countAndPadding(TEXTCOORD, tComps-3);
806 }
807 public void glTexCoord2s(final short x, final short y) {
808 checkSeal(false);
809 growBuffer(TEXTCOORD);
810 if(tComps>0)
811 Buffers.putNs(textCoordArray, tDataTypeSigned, x, true);
812 if(tComps>1)
813 Buffers.putNs(textCoordArray, tDataTypeSigned, y, true);
814 countAndPadding(TEXTCOORD, tComps-2);
815 }
816 public void glTexCoord3s(final short x, final short y, final short z) {
817 checkSeal(false);
818 growBuffer(TEXTCOORD);
819 if(tComps>0)
820 Buffers.putNs(textCoordArray, tDataTypeSigned, x, true);
821 if(tComps>1)
822 Buffers.putNs(textCoordArray, tDataTypeSigned, y, true);
823 if(tComps>2)
824 Buffers.putNs(textCoordArray, tDataTypeSigned, z, true);
825 countAndPadding(TEXTCOORD, tComps-3);
826 }
827 public void glTexCoord2f(final float x, final float y) {
828 checkSeal(false);
829 growBuffer(TEXTCOORD);
830 if(tComps>0)
831 Buffers.putNf(textCoordArray, tDataTypeSigned, x);
832 if(tComps>1)
833 Buffers.putNf(textCoordArray, tDataTypeSigned, y);
834 countAndPadding(TEXTCOORD, tComps-2);
835 }
836 public void glTexCoord3f(final float x, final float y, final float z) {
837 checkSeal(false);
838 growBuffer(TEXTCOORD);
839 if(tComps>0)
840 Buffers.putNf(textCoordArray, tDataTypeSigned, x);
841 if(tComps>1)
842 Buffers.putNf(textCoordArray, tDataTypeSigned, y);
843 if(tComps>2)
844 Buffers.putNf(textCoordArray, tDataTypeSigned, z);
845 countAndPadding(TEXTCOORD, tComps-3);
846 }
847
848 public void rewind() {
849 if(null!=vertexArray) {
850 vertexArray.rewind();
851 }
852 if(null!=colorArray) {
853 colorArray.rewind();
854 }
855 if(null!=normalArray) {
856 normalArray.rewind();
857 }
858 if(null!=textCoordArray) {
859 textCoordArray.rewind();
860 }
861 }
862
863 public void setShaderProgram(final int program) {
864 if(null == shaderState && 0 == program) {
865 throw new IllegalArgumentException("Not allowed to zero shader program if no ShaderState is set");
866 }
867 shaderProgram = program;
868 glslLocationSet = false; // enforce location reset!
869 }
870
871 /**
872 * @param gl
873 * @return true if all locations for all used arrays are found (min 1 array), otherwise false.
874 * Also sets 'glslLocationSet' to the return value!
875 */
876 private boolean resetGLSLArrayLocation(final GL2ES2 gl) {
877 int iA = 0;
878 int iL = 0;
879
880 if(null != vArrayData) {
881 iA++;
882 if( vArrayData.setLocation(gl, shaderProgram) >= 0 ) {
883 iL++;
884 }
885 }
886 if(null != cArrayData) {
887 iA++;
888 if( cArrayData.setLocation(gl, shaderProgram) >= 0 ) {
889 iL++;
890 }
891 }
892 if(null != nArrayData) {
893 iA++;
894 if( nArrayData.setLocation(gl, shaderProgram) >= 0 ) {
895 iL++;
896 }
897 }
898 if(null != tArrayData) {
899 iA++;
900 if( tArrayData.setLocation(gl, shaderProgram) >= 0 ) {
901 iL++;
902 }
903 }
904 glslLocationSet = iA == iL;
905 return glslLocationSet;
906 }
907
908 public void destroy(final GL gl) {
909 reset(gl);
910
911 vCount=0; cCount=0; nCount=0; tCount=0;
912 vertexArray=null; colorArray=null; normalArray=null; textCoordArray=null;
913 vArrayData=null; cArrayData=null; nArrayData=null; tArrayData=null;
914 buffer=null;
915 }
916
917 public void reset(final GL gl) {
918 enableBuffer(gl, false);
919 reset();
920 }
921
922 public void reset() {
923 if(buffer!=null) {
924 buffer.clear();
925 }
926 rewind();
927
928 this.mode = 0;
929 this.modeOrig = 0;
930 this.sealed=false;
931 this.sealedGL=false;
932 this.bufferEnabled=false;
933 this.bufferWritten=false;
934 this.vElems=0;
935 this.cElems=0;
936 this.nElems=0;
937 this.tElems=0;
938 }
939
940 public void seal(final GL glObj, final boolean seal)
941 {
942 seal(seal);
943 if(sealedGL==seal) return;
944 sealedGL = seal;
945 final GL gl = glObj.getGL();
946 if(seal) {
947 if(useVBO) {
948 if(0 == vboName) {
949 final int[] tmp = new int[1];
950 gl.glGenBuffers(1, tmp, 0);
951 vboName = tmp[0];
952 }
953 if(null!=vArrayData) {
954 vArrayData.setVBOName(vboName);
955 }
956 if(null!=cArrayData) {
957 cArrayData.setVBOName(vboName);
958 }
959 if(null!=nArrayData) {
960 nArrayData.setVBOName(vboName);
961 }
962 if(null!=tArrayData) {
963 tArrayData.setVBOName(vboName);
964 }
965 }
966 enableBuffer(gl, true);
967 } else {
968 enableBuffer(gl, false);
969 }
970 }
971
972 public void seal(final boolean seal)
973 {
974 if(sealed==seal) return;
975 sealed = seal;
976 if(seal) {
977 bufferWritten=false;
978 rewind();
979 }
980 }
981
982 public void enableBuffer(final GL gl, final boolean enable) {
983 if( bufferEnabled != enable && vElems>0 ) {
984 if(enable) {
985 checkSeal(true);
986 }
987 bufferEnabled = enable;
988 if(useGLSL) {
989 useShaderProgram(gl.getGL2ES2(), true);
990 if(null != shaderState) {
991 enableBufferGLSLShaderState(gl, enable);
992 } else {
993 enableBufferGLSLSimple(gl, enable);
994 }
995 } else {
996 enableBufferFixed(gl, enable);
997 }
998 }
999 }
1000
1001 private final void writeBuffer(final GL gl) {
1002 final int vBytes = vElems * vCompsBytes;
1003 final int cBytes = cElems * cCompsBytes;
1004 final int nBytes = nElems * nCompsBytes;
1005 final int tBytes = tElems * tCompsBytes;
1006 final int delta = buffer.limit() - (vBytes+cBytes+nBytes+tBytes);
1007 if( bufferWrittenOnce && delta > pageSize ) {
1008 if(0 < vBytes) {
1009 gl.glBufferSubData(GL.GL_ARRAY_BUFFER, vOffset, vBytes, vertexArray);
1010 }
1011 if(0 < cBytes) {
1012 gl.glBufferSubData(GL.GL_ARRAY_BUFFER, cOffset, cBytes, colorArray);
1013 }
1014 if(0 < nBytes) {
1015 gl.glBufferSubData(GL.GL_ARRAY_BUFFER, nOffset, nBytes, normalArray);
1016 }
1017 if(0 < tBytes) {
1018 gl.glBufferSubData(GL.GL_ARRAY_BUFFER, tOffset, tBytes, textCoordArray);
1019 }
1020 } else {
1021 gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, glBufferUsage);
1022 bufferWrittenOnce = true;
1023 }
1024 }
1025
1026 private void enableBufferFixed(final GL gl, final boolean enable) {
1027 final GL2ES1 glf = gl.getGL2ES1();
1028
1029 final boolean useV = vComps>0 && vElems>0 ;
1030 final boolean useC = cComps>0 && cElems>0 ;
1031 final boolean useN = nComps>0 && nElems>0 ;
1032 final boolean useT = tComps>0 && tElems>0 ;
1033
1034 if(DEBUG_DRAW) {
1035 System.err.println("ImmModeSink.enableFixed.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
1036 }
1037
1038 if(enable) {
1039 if(useVBO) {
1040 if(0 == vboName) {
1041 throw new InternalError("Using VBO but no vboName");
1042 }
1043 glf.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
1044
1045 if(!bufferWritten) {
1046 writeBuffer(gl);
1047 }
1048 }
1049 bufferWritten=true;
1050 }
1051
1052 if(useV) {
1053 if(enable) {
1054 glf.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
1055 glf.glVertexPointer(vArrayData);
1056 } else {
1057 glf.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
1058 }
1059 }
1060 if(useC) {
1061 if(enable) {
1062 glf.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
1063 glf.glColorPointer(cArrayData);
1064 } else {
1065 glf.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
1066 }
1067 }
1068 if(useN) {
1069 if(enable) {
1070 glf.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
1071 glf.glNormalPointer(nArrayData);
1072 } else {
1073 glf.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
1074 }
1075 }
1076 if(useT) {
1077 if(enable) {
1078 glf.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
1079 glf.glTexCoordPointer(tArrayData);
1080 } else {
1081 glf.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
1082 }
1083 }
1084
1085 if(enable && useVBO) {
1086 gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
1087 }
1088
1089 if(DEBUG_DRAW) {
1090 System.err.println("ImmModeSink.enableFixed.X ");
1091 }
1092 }
1093
1094 private void enableBufferGLSLShaderState(final GL gl, final boolean enable) {
1095 final GL2ES2 glsl = gl.getGL2ES2();
1096
1097 final boolean useV = vComps>0 && vElems>0 ;
1098 final boolean useC = cComps>0 && cElems>0 ;
1099 final boolean useN = nComps>0 && nElems>0 ;
1100 final boolean useT = tComps>0 && tElems>0 ;
1101
1102 if(DEBUG_DRAW) {
1103 System.err.println("ImmModeSink.enableGLSL.A.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
1104 }
1105
1106 if(enable) {
1107 if(useVBO) {
1108 if(0 == vboName) {
1109 throw new InternalError("Using VBO but no vboName");
1110 }
1111 glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
1112 if(!bufferWritten) {
1113 writeBuffer(gl);
1114 }
1115 }
1116 bufferWritten=true;
1117 }
1118
1119 if(useV) {
1120 if(enable) {
1121 shaderState.enableVertexAttribArray(glsl, vArrayData);
1122 shaderState.vertexAttribPointer(glsl, vArrayData);
1123 } else {
1124 shaderState.disableVertexAttribArray(glsl, vArrayData);
1125 }
1126 }
1127 if(useC) {
1128 if(enable) {
1129 shaderState.enableVertexAttribArray(glsl, cArrayData);
1130 shaderState.vertexAttribPointer(glsl, cArrayData);
1131 } else {
1132 shaderState.disableVertexAttribArray(glsl, cArrayData);
1133 }
1134 }
1135 if(useN) {
1136 if(enable) {
1137 shaderState.enableVertexAttribArray(glsl, nArrayData);
1138 shaderState.vertexAttribPointer(glsl, nArrayData);
1139 } else {
1140 shaderState.disableVertexAttribArray(glsl, nArrayData);
1141 }
1142 }
1143 if(useT) {
1144 if(enable) {
1145 shaderState.enableVertexAttribArray(glsl, tArrayData);
1146 shaderState.vertexAttribPointer(glsl, tArrayData);
1147 } else {
1148 shaderState.disableVertexAttribArray(glsl, tArrayData);
1149 }
1150 }
1151 glslLocationSet = true; // ShaderState does set the location implicit
1152
1153 if(enable && useVBO) {
1154 glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
1155 }
1156
1157 if(DEBUG_DRAW) {
1158 System.err.println("ImmModeSink.enableGLSL.A.X ");
1159 }
1160 }
1161
1162 private void enableBufferGLSLSimple(final GL gl, final boolean enable) {
1163 final GL2ES2 glsl = gl.getGL2ES2();
1164
1165 final boolean useV = vComps>0 && vElems>0 ;
1166 final boolean useC = cComps>0 && cElems>0 ;
1167 final boolean useN = nComps>0 && nElems>0 ;
1168 final boolean useT = tComps>0 && tElems>0 ;
1169
1170 if(DEBUG_DRAW) {
1171 System.err.println("ImmModeSink.enableGLSL.B.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
1172 }
1173
1174 if(!glslLocationSet) {
1175 if( !resetGLSLArrayLocation(glsl) ) {
1176 if(DEBUG_DRAW) {
1177 final int vLoc = null != vArrayData ? vArrayData.getLocation() : -1;
1178 final int cLoc = null != cArrayData ? cArrayData.getLocation() : -1;
1179 final int nLoc = null != nArrayData ? nArrayData.getLocation() : -1;
1180 final int tLoc = null != tArrayData ? tArrayData.getLocation() : -1;
1181 System.err.println("ImmModeSink.enableGLSL.B.X attribute locations in shader program "+shaderProgram+", incomplete ["+vLoc+", "+cLoc+", "+nLoc+", "+tLoc+"] - glslLocationSet "+glslLocationSet);
1182 }
1183 return;
1184 }
1185 }
1186
1187 if(enable) {
1188 if(useVBO) {
1189 if(0 == vboName) {
1190 throw new InternalError("Using VBO but no vboName");
1191 }
1192 glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
1193 if(!bufferWritten) {
1194 writeBuffer(gl);
1195 }
1196 }
1197 bufferWritten=true;
1198 }
1199
1200 if(useV) {
1201 if(enable) {
1202 glsl.glEnableVertexAttribArray(vArrayData.getLocation());
1203 glsl.glVertexAttribPointer(vArrayData);
1204 } else {
1205 glsl.glDisableVertexAttribArray(vArrayData.getLocation());
1206 }
1207 }
1208 if(useC) {
1209 if(enable) {
1210 glsl.glEnableVertexAttribArray(cArrayData.getLocation());
1211 glsl.glVertexAttribPointer(cArrayData);
1212 } else {
1213 glsl.glDisableVertexAttribArray(cArrayData.getLocation());
1214 }
1215 }
1216 if(useN) {
1217 if(enable) {
1218 glsl.glEnableVertexAttribArray(nArrayData.getLocation());
1219 glsl.glVertexAttribPointer(nArrayData);
1220 } else {
1221 glsl.glDisableVertexAttribArray(nArrayData.getLocation());
1222 }
1223 }
1224 if(useT) {
1225 if(enable) {
1226 glsl.glEnableVertexAttribArray(tArrayData.getLocation());
1227 glsl.glVertexAttribPointer(tArrayData);
1228 } else {
1229 glsl.glDisableVertexAttribArray(tArrayData.getLocation());
1230 }
1231 }
1232
1233 if(enable && useVBO) {
1234 glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
1235 }
1236
1237 if(DEBUG_DRAW) {
1238 System.err.println("ImmModeSink.enableGLSL.B.X ");
1239 }
1240 }
1241
1242 @Override
1243 public String toString() {
1244 final String glslS = useGLSL ?
1245 ", useShaderState "+(null!=shaderState)+
1246 ", shaderProgram "+shaderProgram+
1247 ", glslLocationSet "+glslLocationSet : "";
1248
1249 return "VBOSet[mode "+mode+
1250 ", modeOrig "+modeOrig+
1251 ", use/count "+getElemUseCountStr()+
1252 ", sealed "+sealed+
1253 ", sealedGL "+sealedGL+
1254 ", bufferEnabled "+bufferEnabled+
1255 ", bufferWritten "+bufferWritten+" (once "+bufferWrittenOnce+")"+
1256 ", useVBO "+useVBO+", vboName "+vboName+
1257 ", useGLSL "+useGLSL+
1258 glslS+
1259 ",\n\t"+vArrayData+
1260 ",\n\t"+cArrayData+
1261 ",\n\t"+nArrayData+
1262 ",\n\t"+tArrayData+
1263 "]";
1264 }
1265
1266 // non public matters
1267
1268 protected String getElemUseCountStr() {
1269 return "[v "+vElems+"/"+vCount+", c "+cElems+"/"+cCount+", n "+nElems+"/"+nCount+", t "+tElems+"/"+tCount+"]";
1270 }
1271
1272 protected boolean fitElementInBuffer(final int type) {
1273 final int addElems = 1;
1274 switch (type) {
1275 case VERTEX:
1276 return ( vCount - vElems ) >= addElems ;
1277 case COLOR:
1278 return ( cCount - cElems ) >= addElems ;
1279 case NORMAL:
1280 return ( nCount - nElems ) >= addElems ;
1281 case TEXTCOORD:
1282 return ( tCount - tElems ) >= addElems ;
1283 default:
1284 throw new InternalError("XXX");
1285 }
1286 }
1287
1288 protected boolean reallocateBuffer(final int addElems) {
1289 final int vAdd = addElems - ( vCount - vElems );
1290 final int cAdd = addElems - ( cCount - cElems );
1291 final int nAdd = addElems - ( nCount - nElems );
1292 final int tAdd = addElems - ( tCount - tElems );
1293
1294 if( 0>=vAdd && 0>=cAdd && 0>=nAdd && 0>=tAdd) {
1295 if(DEBUG_BUFFER) {
1296 System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems+" -> NOP");
1297 }
1298 return false;
1299 }
1300
1301 if(DEBUG_BUFFER) {
1302 System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems);
1303 }
1304 vCount += vAdd;
1305 cCount += cAdd;
1306 nCount += nAdd;
1307 tCount += tAdd;
1308
1309 final int vBytes = vCount * vCompsBytes;
1310 final int cBytes = cCount * cCompsBytes;
1311 final int nBytes = nCount * nCompsBytes;
1312 final int tBytes = tCount * tCompsBytes;
1313
1314 buffer = Buffers.newDirectByteBuffer( vBytes + cBytes + nBytes + tBytes );
1315 vOffset = 0;
1316
1317 if(vBytes>0) {
1318 vertexArray = GLBuffers.sliceGLBuffer(buffer, vOffset, vBytes, vDataType);
1319 } else {
1320 vertexArray = null;
1321 }
1322 cOffset=vOffset+vBytes;
1323
1324 if(cBytes>0) {
1325 colorArray = GLBuffers.sliceGLBuffer(buffer, cOffset, cBytes, cDataType);
1326 } else {
1327 colorArray = null;
1328 }
1329 nOffset=cOffset+cBytes;
1330
1331 if(nBytes>0) {
1332 normalArray = GLBuffers.sliceGLBuffer(buffer, nOffset, nBytes, nDataType);
1333 } else {
1334 normalArray = null;
1335 }
1336 tOffset=nOffset+nBytes;
1337
1338 if(tBytes>0) {
1339 textCoordArray = GLBuffers.sliceGLBuffer(buffer, tOffset, tBytes, tDataType);
1340 } else {
1341 textCoordArray = null;
1342 }
1343
1344 buffer.position(tOffset+tBytes);
1345 buffer.flip();
1346
1347 if(vComps>0) {
1349 vDataType, GLBuffers.isGLTypeFixedPoint(vDataType), 0,
1350 vertexArray, 0, vOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
1351 } else {
1352 vArrayData = null;
1353 }
1354 if(cComps>0) {
1356 cDataType, GLBuffers.isGLTypeFixedPoint(cDataType), 0,
1357 colorArray, 0, cOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
1358 } else {
1359 cArrayData = null;
1360 }
1361 if(nComps>0) {
1363 nDataType, GLBuffers.isGLTypeFixedPoint(nDataType), 0,
1364 normalArray, 0, nOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
1365 } else {
1366 nArrayData = null;
1367 }
1368 if(tComps>0) {
1370 tDataType, GLBuffers.isGLTypeFixedPoint(tDataType), 0,
1371 textCoordArray, 0, tOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
1372 } else {
1373 tArrayData = null;
1374 }
1375
1376 bufferWrittenOnce = false; // new buffer data storage size!
1377
1378 if(DEBUG_BUFFER) {
1379 System.err.println("ImmModeSink.realloc.X: "+this.toString());
1380 ExceptionUtils.dumpStack(System.err);
1381 }
1382 return true;
1383 }
1384
1385 /** grow buffer by initialElementCount if there is no space for one more element in the designated buffer */
1386 protected final boolean growBuffer(final int type) {
1387 if( null !=buffer && !sealed ) {
1388 if( !fitElementInBuffer(type) ) {
1389 // save olde values ..
1390 final Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
1391
1392 if ( reallocateBuffer(resizeElementCount) ) {
1393 if(null!=_vertexArray) {
1394 _vertexArray.flip();
1395 Buffers.put(vertexArray, _vertexArray);
1396 }
1397 if(null!=_colorArray) {
1398 _colorArray.flip();
1399 Buffers.put(colorArray, _colorArray);
1400 }
1401 if(null!=_normalArray) {
1402 _normalArray.flip();
1403 Buffers.put(normalArray, _normalArray);
1404 }
1405 if(null!=_textCoordArray) {
1406 _textCoordArray.flip();
1407 Buffers.put(textCoordArray, _textCoordArray);
1408 }
1409 return true;
1410 }
1411 }
1412 }
1413 return false;
1414 }
1415
1416 /**
1417 * Fourth element default value for color (alpha), vertex (w) is '1',
1418 * as specified w/ VertexAttributes (ES2/GL3).
1419 * <p>
1420 * vec4 v = vec4(0, 0, 0, 1);
1421 * vec4 c = vec4(0, 0, 0, 1);
1422 * </p>
1423 *
1424 * @param type
1425 * @param fill
1426 */
1427 private void countAndPadding(final int type, int fill) {
1428 if ( sealed ) return;
1429
1430 final Buffer dest;
1431 final boolean dSigned;
1432 final int e; // either 0 or 1
1433
1434 switch (type) {
1435 case VERTEX:
1436 dest = vertexArray;
1437 dSigned = vDataTypeSigned;
1438 e = 4 == vComps ? 1 : 0;
1439 vElems++;
1440 break;
1441 case COLOR:
1442 dest = colorArray;
1443 dSigned = cDataTypeSigned;
1444 e = 4 == cComps ? 1 : 0;
1445 cElems++;
1446 break;
1447 case NORMAL:
1448 dest = normalArray;
1449 dSigned = nDataTypeSigned;
1450 e = 0;
1451 nElems++;
1452 break;
1453 case TEXTCOORD:
1454 dest = textCoordArray;
1455 dSigned = tDataTypeSigned;
1456 e = 0;
1457 tElems++;
1458 break;
1459 default: throw new InternalError("Invalid type "+type);
1460 }
1461
1462 if ( null==dest ) return;
1463
1464 while( fill > e ) {
1465 fill--;
1466 Buffers.putNf(dest, dSigned, 0f);
1467 }
1468 if( fill > 0 ) { // e == 1, add missing '1f end component'
1469 Buffers.putNf(dest, dSigned, 1f);
1470 }
1471 }
1472
1473 final private int glBufferUsage, initialElementCount;
1474 final private boolean useVBO, useGLSL;
1475 final private ShaderState shaderState;
1476 private int shaderProgram;
1477 private int mode, modeOrig, resizeElementCount;
1478
1479 private ByteBuffer buffer;
1480 private int vboName;
1481
1482 private static final int VERTEX = 0;
1483 private static final int COLOR = 1;
1484 private static final int NORMAL = 2;
1485 private static final int TEXTCOORD = 3;
1486
1487 private int vCount, cCount, nCount, tCount; // number of elements fit in each buffer
1488 private int vOffset, cOffset, nOffset, tOffset; // offset of specific array in common buffer
1489 private int vElems, cElems, nElems, tElems; // number of used elements in each buffer
1490 private final int vComps, cComps, nComps, tComps; // number of components for each elements [2, 3, 4]
1491 private final int vCompsBytes, cCompsBytes, nCompsBytes, tCompsBytes; // byte size of all components
1492 private final int vDataType, cDataType, nDataType, tDataType;
1493 private final boolean vDataTypeSigned, cDataTypeSigned, nDataTypeSigned, tDataTypeSigned;
1494 private final int pageSize;
1495 private Buffer vertexArray, colorArray, normalArray, textCoordArray;
1496 private GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
1497
1498 private boolean sealed, sealedGL;
1499 private boolean bufferEnabled, bufferWritten, bufferWrittenOnce;
1500 private boolean glslLocationSet;
1501 }
1502
1503}
1504
final boolean isCPUDataSourcingAvail()
Indicates whether this GLContext allows CPU data sourcing (indices, vertices ..) as opposed to using ...
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
static GLArrayDataWrapper createFixed(final int index, final int comps, final int dataType, final boolean normalized, final int stride, final Buffer buffer, final int vboName, final long vboOffset, final int vboUsage, final int vboTarget)
Create a VBO, using a predefined fixed function array index, wrapping the given data.
void setVBOName(final int vboName)
Set the VBO buffer name, if valid (!= 0) enable use of VBO, otherwise (==0) disable VBO usage.
final int setLocation(final int v)
Sets the given location of the shader attribute.
final int getLocation()
Returns the shader attribute location for this name, -1 if not yet determined.
Utility routines for dealing with direct buffers.
Definition: GLBuffers.java:60
static final Buffer sliceGLBuffer(final ByteBuffer parent, final int bytePos, final int byteLen, final int glType)
Definition: GLBuffers.java:274
static final boolean isSignedGLType(final int glType)
Definition: GLBuffers.java:70
static final boolean isGLTypeFixedPoint(final int glType)
Definition: GLBuffers.java:90
static final int sizeOfGLType(final int glType)
Definition: GLBuffers.java:128
void glColor4f(final float r, final float g, final float b, final float a)
void glColor4ub(final byte r, final byte g, final byte b, final byte a)
void draw(final GL gl, final Buffer indices, final boolean disableBufferAfterDraw, final int i)
VBOSet(final int initialElementCount, final int vComps, final int vDataType, final int cComps, final int cDataType, final int nComps, final int nDataType, final int tComps, final int tDataType, final boolean useGLSL, final int glBufferUsage, final ShaderState st, final int shaderProgram)
void glTexCoord3b(final byte x, final byte y, final byte z)
void glTexCoord2f(final float x, final float y)
void glTexCoord3s(final short x, final short y, final short z)
final VBOSet regenerate(final GL gl)
void glVertex2f(final float x, final float y)
final boolean growBuffer(final int type)
grow buffer by initialElementCount if there is no space for one more element in the designated buffer
void glTexCoord2b(final byte x, final byte y)
void glVertex3b(final byte x, final byte y, final byte z)
void glColor4b(final byte r, final byte g, final byte b, final byte a)
void glColor3b(final byte r, final byte g, final byte b)
void glTexCoord3f(final float x, final float y, final float z)
void glColor4s(final short r, final short g, final short b, final short a)
void glColor3s(final short r, final short g, final short b)
void seal(final GL glObj, final boolean seal)
boolean reallocateBuffer(final int addElems)
boolean fitElementInBuffer(final int type)
void glColor3ub(final byte r, final byte g, final byte b)
void glVertex2s(final short x, final short y)
void enableBuffer(final GL gl, final boolean enable)
void useShaderProgram(final GL2ES2 gl, final boolean force)
void glVertex3f(final float x, final float y, final float z)
void glNormal3b(final byte x, final byte y, final byte z)
void glNormal3s(final short x, final short y, final short z)
void glTexCoord2s(final short x, final short y)
void setShaderProgram(final int program)
void glColor3f(final float r, final float g, final float b)
void glVertex2b(final byte x, final byte y)
void glVertex3s(final short x, final short y, final short z)
void glNormal3f(final float x, final float y, final float z)
final void glVertex2f(final float x, final float y)
final void glVertex3f(final float x, final float y, final float z)
final void glTexCoord3b(final byte x, final byte y, final byte z)
final void glVertex2b(final byte x, final byte y)
final void glColor4s(final short x, final short y, final short z, final short a)
final void glColor4b(final byte x, final byte y, final byte z, final byte a)
final void glColor3s(final short x, final short y, final short z)
ImmModeSink(final int initialElementCount, final int vComps, final int vDataType, final int cComps, final int cDataType, final int nComps, final int nDataType, final int tComps, final int tDataType, final boolean useGLSL, final int glBufferUsage, final ShaderState st, final int shaderProgram)
void glTexCoordv(final Buffer v)
final void glNormal3f(final float x, final float y, final float z)
final void glColor3ub(final byte x, final byte y, final byte z)
final void glVertex3s(final short x, final short y, final short z)
final void glEnd(final GL gl, final Buffer indices)
final void glColor4ub(final byte x, final byte y, final byte z, final byte a)
void glEnd(final GL gl, final boolean immediateDraw)
static ImmModeSink createFixed(final int initialElementCount, final int vComps, final int vDataType, final int cComps, final int cDataType, final int nComps, final int nDataType, final int tComps, final int tDataType, final int glBufferUsage)
Uses a GL2ES1, or ES2 fixed function emulation immediate mode sink.
static ImmModeSink createGLSL(final int initialElementCount, final int vComps, final int vDataType, final int cComps, final int cDataType, final int nComps, final int nDataType, final int tComps, final int tDataType, final int glBufferUsage, final ShaderState st)
Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given ShaderState.
final void glColor3b(final byte x, final byte y, final byte z)
final void glTexCoord2f(final float x, final float y)
void setResizeElementCount(final int v)
Sets the additional element count if buffer resize is required, defaults to initialElementCount of fa...
int getResizeElementCount()
Returns the additional element count if buffer resize is required.
void draw(final GL gl, final boolean disableBufferAfterDraw)
final void glTexCoord3s(final short x, final short y, final short z)
static final boolean DEBUG_BEGIN_END
final void glTexCoord2s(final short x, final short y)
void draw(final GL gl, final Buffer indices, final boolean disableBufferAfterDraw)
static final boolean DEBUG_DRAW
static ImmModeSink createGLSL(final int initialElementCount, final int vComps, final int vDataType, final int cComps, final int cDataType, final int nComps, final int nDataType, final int tComps, final int tDataType, final int glBufferUsage, final int shaderProgram)
Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given shader-program.
final void glNormal3s(final short x, final short y, final short z)
final void glTexCoord2b(final byte x, final byte y)
final void glColor4f(final float x, final float y, final float z, final float a)
final void glColor3f(final float x, final float y, final float z)
static final boolean DEBUG_BUFFER
final void glVertex2s(final short x, final short y)
final void glNormal3b(final byte x, final byte y, final byte z)
final void glEnd(final GL gl)
final void glTexCoord3f(final float x, final float y, final float z)
final void glVertex3b(final byte x, final byte y, final byte z)
ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...
boolean vertexAttribPointer(final GL2ES2 gl, final GLArrayData data)
Set the GLArrayData vertex attribute data, if it's location is valid, i.e.
synchronized void useProgram(final GL2ES2 gl, final boolean on)
Turns the shader program on or off.
void glUseProgram(int program)
Entry point to C language function: void {@native glUseProgram}(GLuint program) Part of GL_ES_VERS...
GL getGL()
Casts this object to the GL interface.
GL2ES2 getGL2ES2()
Casts this object to the GL2ES2 interface.
boolean isGL2()
Indicates whether this GL object conforms to the OpenGL ≤ 3.0 profile.
GLContext getContext()
Returns the GLContext associated which this GL object.
void glGenBuffers(int n, IntBuffer buffers)
Entry point to C language function: void {@native glGenBuffers}(GLsizei n, GLuint * buffers) Part ...
void glDrawArrays(int mode, int first, int count)
Entry point to C language function: void {@native glDrawArrays}(GLenum mode, GLint first,...
static final int GL_STATIC_DRAW
GL_VERSION_1_5, GL_ES_VERSION_2_0, GL_VERSION_ES_1_0, GL_ARB_vertex_buffer_object Alias for: GL_STATI...
Definition: GL.java:673
static final int GL_UNSIGNED_INT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_OES_element_index_uint Define "GL_UNSIGNED_INT"...
Definition: GL.java:294
void glBufferSubData(int target, long offset, long size, Buffer data)
Entry point to C language function: void {@native glBufferSubData}(GLenum target,...
static final int GL_UNSIGNED_SHORT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNSIGNED_SHORT" with ...
Definition: GL.java:346
static final int GL_TRIANGLE_FAN
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TRIANGLE_FAN" with ex...
Definition: GL.java:513
static final int GL_TRIANGLE_STRIP
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TRIANGLE_STRIP" with ...
Definition: GL.java:760
static final int GL_UNSIGNED_BYTE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNSIGNED_BYTE" with e...
Definition: GL.java:284
void glBufferData(int target, long size, Buffer data, int usage)
Entry point to C language function: void {@native glBufferData}(GLenum target, GLsizeiptr size,...
static final int GL_ARRAY_BUFFER
GL_VERSION_1_5, GL_ES_VERSION_2_0, GL_VERSION_ES_1_0, GL_ARB_vertex_buffer_object Alias for: GL_ARRAY...
Definition: GL.java:633