diff options
Diffstat (limited to 'src/jogl/classes')
18 files changed, 358 insertions, 108 deletions
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java index 7fdb93e9b..a00b19abc 100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java @@ -67,6 +67,7 @@ public class GLConfiguration extends ProcAddressConfiguration { // Maps function names to the kind of buffer object it deals with private Map<String, GLEmitter.BufferObjectKind> bufferObjectKinds = new HashMap<String, GLEmitter.BufferObjectKind>(); + private Set<String> bufferObjectOnly = new HashSet<String>(); private GLEmitter emitter; private Set<String> dropUniqVendorExtensions = new HashSet<String>(); @@ -106,6 +107,9 @@ public class GLConfiguration extends ProcAddressConfiguration { glHeaders.add(sym); } else if (cmd.equalsIgnoreCase("BufferObjectKind")) { readBufferObjectKind(tok, filename, lineNo); + } else if (cmd.equalsIgnoreCase("BufferObjectOnly")) { + String sym = readString("BufferObjectOnly", tok, filename, lineNo); + bufferObjectOnly.add(sym); } else if (cmd.equalsIgnoreCase("DropUniqVendorExtensions")) { String sym = readString("DropUniqVendorExtensions", tok, filename, lineNo); dropUniqVendorExtensions.add(sym); @@ -127,10 +131,12 @@ public class GLConfiguration extends ProcAddressConfiguration { kind = GLEmitter.BufferObjectKind.ARRAY; } else if (kindString.equalsIgnoreCase("Element")) { kind = GLEmitter.BufferObjectKind.ELEMENT; + } else if (kindString.equalsIgnoreCase("Indirect")) { + kind = GLEmitter.BufferObjectKind.INDIRECT; } else { throw new RuntimeException("Error parsing \"BufferObjectKind\" command at line " + lineNo + " in file \"" + filename + "\": illegal BufferObjectKind \"" - + kindString + "\", expected one of UnpackPixel, PackPixel, Array, or Element"); + + kindString + "\", expected one of UnpackPixel, PackPixel, Array, Element or Indirect"); } bufferObjectKinds.put(target, kind); @@ -171,6 +177,8 @@ public class GLConfiguration extends ProcAddressConfiguration { prologue = prologue + "ArrayVBO"; } else if (kind == GLEmitter.BufferObjectKind.ELEMENT) { prologue = prologue + "ElementVBO"; + } else if (kind == GLEmitter.BufferObjectKind.INDIRECT) { + prologue = prologue + "IndirectVBO"; } else { throw new RuntimeException("Unknown BufferObjectKind " + kind); } @@ -335,6 +343,10 @@ public class GLConfiguration extends ProcAddressConfiguration { public boolean isBufferObjectFunction(String name) { return (getBufferObjectKind(name) != null); } + + public boolean isBufferObjectOnly(String name) { + return bufferObjectOnly.contains(name); + } /** Parses any GL headers specified in the configuration file for the purpose of being able to ignore an extension at a time. */ diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java index 075c8bfd8..fa95049cc 100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java @@ -74,7 +74,7 @@ public class GLEmitter extends ProcAddressEmitter { // Buffer Object variants. Used as a Set rather than a Map. private Map<MethodBinding, MethodBinding> bufferObjectMethodBindings = new IdentityHashMap<MethodBinding, MethodBinding>(); - enum BufferObjectKind { UNPACK_PIXEL, PACK_PIXEL, ARRAY, ELEMENT} + enum BufferObjectKind { UNPACK_PIXEL, PACK_PIXEL, ARRAY, ELEMENT, INDIRECT} @Override public void beginEmission(GlueEmitterControls controls) throws IOException { @@ -262,25 +262,31 @@ public class GLEmitter extends ProcAddressEmitter { case (though we default to true currently). */ @Override protected List<MethodBinding> expandMethodBinding(MethodBinding binding) { - List<MethodBinding> bindings = super.expandMethodBinding(binding); + final GLConfiguration glConfig = getGLConfig(); + final List<MethodBinding> bindings = super.expandMethodBinding(binding); - if (!getGLConfig().isBufferObjectFunction(binding.getName())) { + if ( !glConfig.isBufferObjectFunction(binding.getName()) ) { return bindings; } + final boolean bufferObjectOnly = glConfig.isBufferObjectOnly(binding.getName()); - List<MethodBinding> newBindings = new ArrayList<MethodBinding>(bindings); + final List<MethodBinding> newBindings = new ArrayList<MethodBinding>(); // Need to expand each one of the generated bindings to take a // Java long instead of a Buffer for each void* argument - for (MethodBinding cur : bindings) { - + // for (MethodBinding cur : bindings) { + int j=0; + while( j < bindings.size() ) { + final MethodBinding cur = bindings.get(j); + // Some of these routines (glBitmap) take strongly-typed // primitive pointers as arguments which are expanded into // non-void* arguments // This test (rather than !signatureUsesNIO) is used to catch // more unexpected situations if (cur.signatureUsesJavaPrimitiveArrays()) { + j++; continue; } @@ -300,9 +306,16 @@ public class GLEmitter extends ProcAddressEmitter { // Now need to flag this MethodBinding so that we generate the // correct flags in the emitters later bufferObjectMethodBindings.put(result, result); + + if( bufferObjectOnly ) { + bindings.remove(j); + } else { + j++; + } } + bindings.addAll(newBindings); - return newBindings; + return bindings; } @Override diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java index 023a8a1aa..6ef1e0805 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java +++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java @@ -181,15 +181,22 @@ public class GLRendererQuirks { */ public static final int NoFullFBOSupport = 11; - + /** + * GLSL is not compliant or even not stable (crash) + * <ul> + * <li>OSX < 10.7.0 (?) - NVidia Driver. Bug 818 @ https://jogamp.org/bugzilla/.</li> + * </ul> + */ + public static final int GLSLNonCompliant = 12; + /** Number of quirks known. */ - public static final int COUNT = 12; + public static final int COUNT = 13; private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval", "NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard", "GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11Display", "NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext", - "NoFullFBOSupport" + "NoFullFBOSupport", "GLSLNonCompliant" }; private final int _bitmask; diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java index dc96cb5f2..111e2509e 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java +++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java @@ -522,6 +522,10 @@ public class ImmModeSink { gl.glDrawArrays(mode, 0, vElems); } } else { + // FIXME: Impl. VBO usage .. or unroll. + if( !gl.getContext().isCPUDataSourcingAvail() ) { + throw new GLException("CPU data sourcing n/a w/ "+gl.getContext()); + } final int type; if(indices instanceof ByteBuffer) { type = GL.GL_UNSIGNED_BYTE; @@ -553,7 +557,7 @@ public class ImmModeSink { } } } else { - gl.glDrawElements(mode, idxLen, type, indices); + ((GL2ES1)gl).glDrawElements(mode, idxLen, type, indices); // GL2: gl.glDrawRangeElements(mode, 0, idxLen-1, idxLen, type, indices); } } diff --git a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java index 8fc7916c7..a2b7ba343 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java @@ -96,7 +96,28 @@ public class RandomTileRenderer extends TileRendererBase { /** * {@inheritDoc} - * @throws IllegalStateException if image-size or tileRect has not been set + * + * <p> + * <i>end of tiling</i> is never reached w/ {@link RandomRileRenderer}, + * i.e. method always returns false. + * </p> + */ + @Override + public final boolean eot() { return false; } + + /** + * {@inheritDoc} + * + * Reset internal states of {@link RandomTileRenderer} are: <i>none</i>. + */ + @Override + public final void reset() { } + + /** + * {@inheritDoc} + * + * @throws IllegalStateException if {@link #setImageSize(int, int) image-size} has not been set or + * {@link #setTileRect(int, int, int, int) tile-rect} has not been set. */ @Override public final void beginTile(GL gl) throws IllegalStateException, GLException { diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java index f126eb7f5..deab8bc3e 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java @@ -101,7 +101,7 @@ public class TileRenderer extends TileRendererBase { */ public static final int TR_COLUMNS = 15; /** - * The current tile number. See {@link #getParam(int)}. + * The current tile number. Has value -1 if {@link #eot()}. See {@link #getParam(int)}. */ public static final int TR_CURRENT_TILE_NUM = 16; /** @@ -132,12 +132,13 @@ public class TileRenderer extends TileRendererBase { private final Dimension tileSize = new Dimension(DEFAULT_TILE_WIDTH, DEFAULT_TILE_HEIGHT); private final Dimension tileSizeNB = new Dimension(DEFAULT_TILE_WIDTH - 2 * DEFAULT_TILE_BORDER, DEFAULT_TILE_HEIGHT - 2 * DEFAULT_TILE_BORDER); - protected Dimension imageClippingDim = null; // not set - default + private boolean isInit = false; + private Dimension imageClippingDim = null; // not set - default private int tileBorder = DEFAULT_TILE_BORDER; private int rowOrder = TR_BOTTOM_TO_TOP; private int rows; private int columns; - private int currentTile = -1; + private int currentTile = 0; private int currentRow; private int currentColumn; private int offsetX; @@ -158,13 +159,25 @@ public class TileRenderer extends TileRendererBase { } /** + * {@inheritDoc} + * <p> + * Implementation {@link #reset()} internal states. + * </p> + */ + @Override + public final void setImageSize(int width, int height) { + super.setImageSize(width, height); + reset(); + } + + /** * Clips the image-size this tile-renderer iterates through, * which can be retrieved via {@link #getClippedImageSize()}. * <p> * Original image-size stored in this tile-renderer is unmodified. * </p> * <p> - * Method resets internal state and {@link #TR_ROWS} {@link #TR_COLUMNS} count. + * Implementation {@link #reset()} internal states. * </p> * * @param width The image-clipping.width @@ -178,7 +191,7 @@ public class TileRenderer extends TileRendererBase { imageClippingDim.setWidth(width); imageClippingDim.setHeight(height); } - setup(); + reset(); } /** @@ -210,7 +223,7 @@ public class TileRenderer extends TileRendererBase { * effective size of the tile depends on the border size, ie ( * width - 2*border ) * ( height - 2 * border ) * <p> - * Method resets internal state and {@link #TR_ROWS} {@link #TR_COLUMNS} count. + * Implementation {@link #reset()} internal states. * </p> * * @param width @@ -236,7 +249,7 @@ public class TileRenderer extends TileRendererBase { tileSize.setHeight( height ); tileSizeNB.setWidth( width - 2 * border ); tileSizeNB.setHeight( height - 2 * border ); - setup(); + reset(); } /** @@ -251,32 +264,43 @@ public class TileRenderer extends TileRendererBase { } /** - * Sets up the number of rows and columns needed + * {@inheritDoc} + * + * Reset internal states of {@link TileRenderer} are: + * <ul> + * <li>{@link #TR_ROWS}</li> + * <li>{@link #TR_COLUMNS}</li> + * <li>{@link #TR_CURRENT_COLUMN}</li> + * <li>{@link #TR_CURRENT_ROW}</li> + * <li>{@link #TR_CURRENT_TILE_NUM}</li> + * <li>{@link #TR_CURRENT_TILE_X_POS}</li> + * <li>{@link #TR_CURRENT_TILE_Y_POS}</li> + * <li>{@link #TR_CURRENT_TILE_WIDTH}</li> + * <li>{@link #TR_CURRENT_TILE_HEIGHT}</li> + *</ul> */ - private final void setup() throws IllegalStateException { + @Override + public final void reset() { final DimensionImmutable clippedImageSize = getClippedImageSize(); columns = ( clippedImageSize.getWidth() + tileSizeNB.getWidth() - 1 ) / tileSizeNB.getWidth(); rows = ( clippedImageSize.getHeight() + tileSizeNB.getHeight() - 1 ) / tileSizeNB.getHeight(); + currentRow = 0; + currentColumn = 0; currentTile = 0; currentTileXPos = 0; currentTileYPos = 0; currentTileWidth = 0; currentTileHeight = 0; - currentRow = 0; - currentColumn = 0; assert columns >= 0; assert rows >= 0; + + beginCalled = false; + isInit = true; } /* pp */ final int getCurrentTile() { return currentTile; } - /** - * Returns <code>true</code> if all tiles have been rendered or {@link #setup()} - * has not been called, otherwise <code>false</code>. - */ - public final boolean eot() { return 0 > currentTile; } - @Override public final int getParam(int pname) { switch (pname) { @@ -341,16 +365,41 @@ public class TileRenderer extends TileRendererBase { return 0 < imageSize.getWidth() && 0 < imageSize.getHeight(); } + /** + * {@inheritDoc} + * + * <p> + * <i>end of tiling</i> is reached w/ {@link TileRenderer}, if at least one of the following is true: + * <ul> + * <li>all tiles have been rendered, i.e. {@link #TR_CURRENT_TILE_NUM} is -1</li> + * <li>no tiles to render, i.e. {@link #TR_COLUMNS} or {@link #TR_ROWS} is 0</li> + * </ul> + * </p> + */ + @Override + public final boolean eot() { + if ( !isInit ) { // ensure at least one reset-call + reset(); + } + return 0 > currentTile || 0 >= columns*rows; + } + + /** + * {@inheritDoc} + * + * @throws IllegalStateException if {@link #setImageSize(int, int) image-size} has not been set or + * {@link #eot() end-of-tiling} has been reached. + */ @Override public final void beginTile( GL gl ) throws IllegalStateException, GLException { if( !isSetup() ) { - throw new IllegalStateException("Image size has not been set"); + throw new IllegalStateException("Image size has not been set: "+this); } - validateGL(gl); - if (currentTile <= 0) { - setup(); + if ( eot() ) { + throw new IllegalStateException("EOT reached: "+this); } - + validateGL(gl); + /* which tile (by row and column) we're about to render */ if (rowOrder == TR_BOTTOM_TO_TOP) { currentRow = currentTile / columns; @@ -390,7 +439,7 @@ public class TileRenderer extends TileRendererBase { gl.glViewport( 0, 0, tW, tH ); if( DEBUG ) { - System.err.println("TileRenderer.begin.X: "+this.toString()); + System.err.println("TileRenderer.begin: "+this.toString()); } // Do not forget to issue: diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java index f15c79f68..d6c36aa14 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java @@ -241,6 +241,7 @@ public abstract class TileRendererBase { tileDetails(sb); sb.append("], image[size "+imageSize+", buffer "+hashStr(imageBuffer)+"], glad["+ gladListenerCount+" listener, pre "+(null!=glEventListenerPre)+", post "+(null!=glEventListenerPost)+", preSwap "+gladRequiresPreSwap+"]"); + sb.append(", isSetup "+isSetup()); return sb; } public String toString() { @@ -284,7 +285,7 @@ public abstract class TileRendererBase { * @param width The width of the final image * @param height The height of the final image */ - public final void setImageSize(int width, int height) { + public void setImageSize(int width, int height) { imageSize.setWidth(width); imageSize.setHeight(height); } @@ -321,6 +322,27 @@ public abstract class TileRendererBase { public abstract boolean isSetup(); /** + * Returns true if <i>end of tiling</i> has been reached, otherwise false. + * <p> + * <i>end of tiling</i> criteria is implementation specific and may never be reached. + * </p> + * <p> + * User needs to {@link #reset()} tiling after reaching <i>end of tiling</i> + * before calling {@link #beginTile(GL)} again. + * </p> + */ + public abstract boolean eot(); + + /** + * Method resets implementation's internal state to <i>start of tiling</i> + * as required for {@link #beginTile(GL)} if {@link #eot() end of tiling} has been reached. + * <p> + * Implementation is a <i>nop</i> where {@link #eot() end of tiling} is never reached. + * </p> + */ + public abstract void reset(); + + /** * Begins rendering a tile. * <p> * This method modifies the viewport, see below. @@ -351,10 +373,19 @@ public abstract class TileRendererBase { * <p> * User has to comply with the <a href="#glprequirement">GL profile requirement</a>. * </p> + * <p> + * If {@link #eot() end of tiling} has been reached, + * user needs to {@link #reset()} tiling before calling this method. + * </p> * * @param gl The gl context - * @throws IllegalStateException if image-size has not been set + * @throws IllegalStateException if {@link #setImageSize(int, int) image-size} is undefined, + * an {@link #isSetup() implementation related setup} has not be performed + * or {@ link #eot()} has been reached. See implementing classes. * @throws GLException if {@link #setImageBuffer(GLPixelBuffer) image buffer} is used but <code>gl</code> instance is < {@link GL2ES3} + * @see #isSetup() + * @see #eot() + * @see #reset() */ public abstract void beginTile(GL gl) throws IllegalStateException, GLException; @@ -594,6 +625,12 @@ public abstract class TileRendererBase { } return; } + if( eot() ) { + if( DEBUG ) { + System.err.println("TileRenderer.glel.display: EOT: "+TileRendererBase.this); + } + return; + } final GL gl = drawable.getGL(); beginTile(gl); diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java index 1f5bb6acc..9d2ef6572 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java @@ -28,7 +28,11 @@ package com.jogamp.opengl.util.awt; import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.WritableRaster; import java.nio.Buffer; import java.nio.IntBuffer; @@ -36,7 +40,6 @@ import javax.media.opengl.GL; import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.util.GLPixelBuffer; -import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; /** * AWT {@link GLPixelBuffer} backed by an {@link BufferedImage} of type @@ -51,6 +54,10 @@ import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; * <p> * See {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)} for {@link #allowRowStride} details. * </p> + * <p> + * If using <code>allowRowStride == true</code>, user may needs to get the {@link #getAlignedImage(int, int) aligned image} + * since {@link #requiresNewBuffer(GL, int, int, int)} will allow different width in this case. + * </p> */ public class AWTGLPixelBuffer extends GLPixelBuffer { public static final GLPixelAttributes awtPixelAttributesIntRGBA4 = new GLPixelAttributes(4, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); @@ -60,6 +67,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { public final BufferedImage image; /** + * * @param pixelAttributes the desired {@link GLPixelAttributes} * @param width in pixels * @param height in pixels @@ -68,6 +76,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { * @param image the AWT image * @param buffer the backing array * @param allowRowStride If <code>true</code>, allow row-stride, otherwise not. See {@link #requiresNewBuffer(GL, int, int, int)}. + * If <code>true</code>, user shall decide whether to use a {@link #getAlignedImage(int, int) width-aligned image}. */ public AWTGLPixelBuffer(GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, BufferedImage image, Buffer buffer, boolean allowRowStride) { @@ -81,6 +90,33 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { super.dispose(); } + /** + * Returns a width- and height-aligned image representation sharing data w/ {@link #image}. + * @param width + * @param height + * @return + * @throws IllegalArgumentException if requested size exceeds image size + */ + public BufferedImage getAlignedImage(int width, int height) throws IllegalArgumentException { + if( width * height > image.getWidth() * image.getHeight() ) { + throw new IllegalArgumentException("Requested size exceeds image size: "+width+"x"+height+" > "+image.getWidth()+"x"+image.getHeight()); + } + if( width == image.getWidth() ) { + if( height == image.getHeight() ) { + return image; + } + return image.getSubimage(0, 0, width, height); + } + final ColorModel cm = image.getColorModel(); + final WritableRaster raster = image.getRaster(); + final DataBuffer dataBuffer = raster.getDataBuffer(); + final SinglePixelPackedSampleModel sppsm0 = (SinglePixelPackedSampleModel) raster.getSampleModel(); + final SinglePixelPackedSampleModel sppsm1 = new SinglePixelPackedSampleModel(dataBuffer.getDataType(), + width, height, width /* scanLineStride */, sppsm0.getBitMasks()); + final WritableRaster raster1 = WritableRaster.createWritableRaster(sppsm1, dataBuffer, null); + return new BufferedImage (cm, raster1, cm.isAlphaPremultiplied(), null); + } + public StringBuilder toString(StringBuilder sb) { sb = super.toString(sb); sb.append(", allowRowStride ").append(allowRowStride).append(", image [").append(image.getWidth()).append("x").append(image.getHeight()).append(", ").append(image.toString()).append("]"); @@ -99,6 +135,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { /** * @param allowRowStride If <code>true</code>, allow row-stride, otherwise not. * See {@link #getAllowRowStride()} and {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)}. + * If <code>true</code>, user shall decide whether to use a {@link AWTGLPixelBuffer#getAlignedImage(int, int) width-aligned image}. */ public AWTGLPixelBufferProvider(boolean allowRowStride) { this.allowRowStride = allowRowStride; diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 2dca2a685..f4dbde6b2 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -1009,6 +1009,16 @@ public abstract class GLContext { ) ; } + /** + * Indicates whether this GLContext allows CPU data sourcing (indices, vertices ..) as opposed to using a GPU buffer source (VBO), + * e.g. {@link GL2#glDrawElements(int, int, int, java.nio.Buffer)}. + * <p>Includes [GL2ES1, GLES2] == [ GL4bc, GL3bc, GL2, GLES1, GL2ES1, GLES2 ].</p> + * <p>See Bug 852 - https://jogamp.org/bugzilla/show_bug.cgi?id=852 </p> + */ + public final boolean isCPUDataSourcingAvail() { + return isGL2ES1() || isGLES2(); + } + /** * Indicates whether this GLContext's native profile does not implement a default <i>vertex array object</i> (VAO), * starting w/ OpenGL 3.1 core and GLES3. @@ -1078,11 +1088,11 @@ public abstract class GLContext { } /** - * Indicates whether this GLContext is capable of GLES2. <p>Includes [ GLES3, GLES2 ].</p> + * Indicates whether this GLContext is capable of GLES2. <p>Includes [ GLES2 ].</p> * @see GLProfile#isGLES2() */ public final boolean isGLES2() { - return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 2 ; + return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 2 ; } /** diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 1dde2cbb6..4a2edc56b 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -1098,9 +1098,9 @@ public class GLProfile { return GLES1 == profile; } - /** Indicates whether this profile is capable of GLES2. <p>Includes [ GLES3, GLES2 ].</p> */ + /** Indicates whether this profile is capable of GLES2. <p>Includes [ GLES2 ].</p> */ public final boolean isGLES2() { - return GLES3 == profile || GLES2 == profile; + return GLES2 == profile; } /** Indicates whether this profile is capable of GLES3. <p>Includes [ GLES3 ].</p> */ diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index f86a6a347..20dd802fb 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -837,20 +837,26 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing final Graphics2D g2d = (Graphics2D)graphics; try { printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight()); - try { - final TileRenderer tileRenderer = printAWTTiles.renderer; - if( DEBUG ) { - System.err.println("AWT print.0: "+tileRenderer); - } - do { - if( printGLAD != GLCanvas.this ) { - tileRenderer.display(); - } else { - Threading.invoke(true, displayOnEDTAction, getTreeLock()); + final TileRenderer tileRenderer = printAWTTiles.renderer; + if( DEBUG ) { + System.err.println("AWT print.0: "+tileRenderer); + } + if( !tileRenderer.eot() ) { + try { + do { + if( printGLAD != GLCanvas.this ) { + tileRenderer.display(); + } else { + Threading.invoke(true, displayOnEDTAction, getTreeLock()); + } + } while ( !tileRenderer.eot() ); + if( DEBUG ) { + System.err.println("AWT print.1: "+printAWTTiles); } - } while ( !tileRenderer.eot() ); - } finally { - printAWTTiles.resetGraphics2D(); + } finally { + tileRenderer.reset(); + printAWTTiles.resetGraphics2D(); + } } } catch (NoninvertibleTransformException nte) { System.err.println("Catched: Inversion failed of: "+g2d.getTransform()); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 84d085f76..673f22aff 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -93,6 +93,7 @@ import com.jogamp.common.util.awt.AWTEDTExecutor; import com.jogamp.nativewindow.awt.AWTPrintLifecycle; import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol; import com.jogamp.opengl.FBObject; +import com.jogamp.opengl.GLRendererQuirks; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; import com.jogamp.opengl.util.GLPixelBuffer.SingletonGLPixelBufferProvider; import com.jogamp.opengl.util.GLDrawableUtil; @@ -142,8 +143,19 @@ import com.jogamp.opengl.util.texture.TextureState; <a name="fboGLSLVerticalFlip"><h5>FBO / GLSL Vertical Flip</h5></a> The FBO / GLSL code path uses one texture-unit and binds the FBO texture to it's active texture-target, see {@link #setTextureUnit(int)} and {@link #getTextureUnit()}. - If the application uses the same texture-unit, ensure it setup their texture properly, i.e. texture-unit bind, enable and then it's parameters, - see {@link Texture#textureCallOrder Order of Texture Commands}. + <p> + The active and dedicated texture-unit's {@link GL#GL_TEXTURE_2D} state is preserved via {@link TextureState}. + See also {@link Texture#textureCallOrder Order of Texture Commands}. + </p> + <p> + The current gl-viewport is preserved. + </p> + <p> + <i>Warning (Bug 842)</i>: Certain GL states other than viewport and texture (see above) + influencing rendering, will also influence the GLSL vertical flip, e.g. {@link GL#glFrontFace(int) glFrontFace}({@link GL#GL_CCW}). + It is recommended to reset those states to default when leaving the {@link GLEventListener#display(GLAutoDrawable)} method! + We may change this behavior in the future, i.e. preserve all influencing states. + </p> */ @SuppressWarnings("serial") @@ -167,12 +179,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing DEBUG_VIEWPORT = Debug.isPropertyDefined("jogl.debug.GLJPanel.Viewport", true); USE_GLSL_TEXTURE_RASTERIZER = !Debug.isPropertyDefined("jogl.gljpanel.noglsl", true); - boolean enabled = false; - final String sVal = System.getProperty("sun.java2d.opengl"); - if( null != sVal ) { - enabled = Boolean.valueOf(sVal); - } - Debug.initSingleton(); + boolean enabled = Debug.getBooleanProperty("sun.java2d.opengl", false); java2dOGLEnabledByProp = enabled && !Debug.isPropertyDefined("jogl.gljpanel.noogl", true); enabled = false; @@ -639,17 +646,26 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing final Graphics2D g2d = (Graphics2D)graphics; try { printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight()); - try { - final TileRenderer tileRenderer = printAWTTiles.renderer; - do { - if( printGLAD != GLJPanel.this ) { - tileRenderer.display(); - } else { - backend.doPlainPaint(); + final TileRenderer tileRenderer = printAWTTiles.renderer; + if( DEBUG ) { + System.err.println("AWT print.0: "+tileRenderer); + } + if( !tileRenderer.eot() ) { + try { + do { + if( printGLAD != GLJPanel.this ) { + tileRenderer.display(); + } else { + backend.doPlainPaint(); + } + } while ( !tileRenderer.eot() ); + if( DEBUG ) { + System.err.println("AWT print.1: "+printAWTTiles); } - } while ( !tileRenderer.eot() ); - } finally { - printAWTTiles.resetGraphics2D(); + } finally { + tileRenderer.reset(); + printAWTTiles.resetGraphics2D(); + } } } catch (NoninvertibleTransformException nte) { System.err.println("Catched: Inversion failed of: "+g2d.getTransform()); @@ -1236,6 +1252,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing private final AWTGLPixelBufferProvider pixelBufferProvider; private final boolean useSingletonBuffer; private AWTGLPixelBuffer pixelBuffer; + private BufferedImage alignedImage; // One of these is used to store the read back pixels before storing // in the BufferedImage @@ -1255,8 +1272,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing OffscreenBackend(GLProfile glp, AWTGLPixelBufferProvider custom) { if(null == custom) { - pixelBufferProvider = glp.isGL2ES3() ? getSingleAWTGLPixelBufferProvider() : - new AWTGLPixelBufferProvider( false /* allowRowStride */ ) ; + pixelBufferProvider = getSingleAWTGLPixelBufferProvider(); } else { pixelBufferProvider = custom; } @@ -1290,7 +1306,15 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing flipVertical = offscreenDrawable.isGLOriented(); final GLCapabilitiesImmutable chosenCaps = offscreenDrawable.getChosenGLCapabilities(); offscreenIsFBO = chosenCaps.isFBO(); - if( USE_GLSL_TEXTURE_RASTERIZER && offscreenIsFBO && flipVertical && gl.isGL2ES2() ) { + final boolean glslCompliant = !offscreenContext.hasRendererQuirk(GLRendererQuirks.GLSLNonCompliant); + final boolean useGLSLFlip = flipVertical && offscreenIsFBO && gl.isGL2ES2() && USE_GLSL_TEXTURE_RASTERIZER && glslCompliant; + if( DEBUG ) { + System.err.println(getThreadName()+": OffscreenBackend.initialize: useGLSLFlip "+useGLSLFlip+ + " [flip "+flipVertical+", isFBO "+offscreenIsFBO+", isGL2ES2 "+gl.isGL2ES2()+ + ", noglsl "+!USE_GLSL_TEXTURE_RASTERIZER+", glslNonCompliant "+!glslCompliant+ + ", isGL2ES2 " + gl.isGL2ES2()+"]"); + } + if( useGLSLFlip ) { final boolean _autoSwapBufferMode = helper.getAutoSwapBufferMode(); helper.setAutoSwapBufferMode(false); final GLFBODrawable fboDrawable = (GLFBODrawable) offscreenDrawable; @@ -1382,6 +1406,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } pixelBuffer = null; } + alignedImage = null; } @Override @@ -1389,6 +1414,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if ( opaque != isOpaque() && !useSingletonBuffer ) { pixelBuffer.dispose(); pixelBuffer = null; + alignedImage = null; } } @@ -1423,6 +1449,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if( null != pixelBuffer && pixelBuffer.requiresNewBuffer(gl, panelWidth, panelHeight, 0) ) { pixelBuffer.dispose(); pixelBuffer = null; + alignedImage = null; } if ( null == pixelBuffer ) { if (0 >= panelWidth || 0 >= panelHeight ) { @@ -1439,6 +1466,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if( offscreenDrawable.getWidth() != panelWidth || offscreenDrawable.getHeight() != panelHeight ) { throw new InternalError("OffscreenDrawable panelSize mismatch (reshape missed): panelSize "+panelWidth+"x"+panelHeight+" != drawable "+offscreenDrawable.getWidth()+"x"+offscreenDrawable.getHeight()+", on thread "+getThreadName()); } + if( null == alignedImage || panelWidth != alignedImage.getWidth() || panelHeight != alignedImage.getHeight() ) { + alignedImage = pixelBuffer.getAlignedImage(panelWidth, panelHeight); + if(DEBUG) { + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0: alignedImage "+alignedImage.getWidth()+"x"+alignedImage.getHeight()+", pixelBuffer "+pixelBuffer.width+"x"+pixelBuffer.height); + } + } final IntBuffer readBackInts; if( !flipVertical || null != glslTextureRaster ) { @@ -1475,7 +1508,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing psm.setAlignment(gl, alignment, alignment); if(gl.isGL2ES3()) { final GL2ES3 gl2es3 = gl.getGL2ES3(); - gl2es3.glPixelStorei(GL2ES3.GL_PACK_ROW_LENGTH, pixelBuffer.width); + gl2es3.glPixelStorei(GL2ES3.GL_PACK_ROW_LENGTH, panelWidth); gl2es3.glReadBuffer(gl2es3.getDefaultReadBuffer()); } @@ -1522,12 +1555,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing // blitting Note that we could avoid this copy in the cases // where !offscreenDrawable.isGLOriented(), // but that's the software rendering path which is very slow anyway. - final BufferedImage image = pixelBuffer.image; + final BufferedImage image = alignedImage; final int[] src = readBackInts.array(); final int[] dest = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); - final int incr = pixelBuffer.width; + final int incr = panelWidth; int srcPos = 0; - int destPos = (panelHeight - 1) * pixelBuffer.width; + int destPos = (panelHeight - 1) * panelWidth; for (; destPos >= 0; srcPos += incr, destPos -= incr) { System.arraycopy(src, srcPos, dest, destPos, incr); } @@ -1557,10 +1590,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing public void doPaintComponent(Graphics g) { helper.invokeGL(offscreenDrawable, offscreenContext, updaterDisplayAction, updaterInitAction); - if ( null != pixelBuffer ) { - final BufferedImage image = pixelBuffer.image; + if ( null != alignedImage ) { // Draw resulting image in one shot - g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); // Null ImageObserver since image data is ready. + g.drawImage(alignedImage, 0, 0, alignedImage.getWidth(), alignedImage.getHeight(), null); // Null ImageObserver since image data is ready. } } diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java index 890c82c90..f14d16ec4 100644 --- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java +++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java @@ -102,6 +102,7 @@ public class GLBufferStateTracker { setBoundBufferObject(GL.GL_ELEMENT_ARRAY_BUFFER, 0); setBoundBufferObject(GL2.GL_PIXEL_PACK_BUFFER, 0); setBoundBufferObject(GL2.GL_PIXEL_UNPACK_BUFFER, 0); + setBoundBufferObject(GL4.GL_DRAW_INDIRECT_BUFFER, 0); } public final void setBoundBufferObject(int target, int value) { @@ -132,6 +133,7 @@ public class GLBufferStateTracker { case GL.GL_ELEMENT_ARRAY_BUFFER: queryTarget = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; break; case GL2.GL_PIXEL_PACK_BUFFER: queryTarget = GL2.GL_PIXEL_PACK_BUFFER_BINDING; break; case GL2.GL_PIXEL_UNPACK_BUFFER: queryTarget = GL2.GL_PIXEL_UNPACK_BUFFER_BINDING; break; + case GL4.GL_DRAW_INDIRECT_BUFFER: queryTarget = GL4.GL_DRAW_INDIRECT_BUFFER_BINDING; break; default: gotQueryTarget = false; break; } if (gotQueryTarget) { diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 77cbd0ed9..7f9f20a21 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -1604,13 +1604,23 @@ public abstract class GLContextImpl extends GLContext { quirks[i++] = quirk; } - final VersionNumber OSXVersion173 = new VersionNumber(1,7,3); - if( Platform.getOSVersionNumber().compareTo(OSXVersion173) < 0 && isDriverNVIDIAGeForce ) { - final int quirk = GLRendererQuirks.GLFlushBeforeRelease; - if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()+", Renderer "+glRenderer); + if( isDriverNVIDIAGeForce ) { + final VersionNumber osxVersionNVFlushClean = new VersionNumber(10,7,3); // < OSX 10.7.3 w/ NV needs glFlush + if( Platform.getOSVersionNumber().compareTo(osxVersionNVFlushClean) < 0 ) { + final int quirk = GLRendererQuirks.GLFlushBeforeRelease; + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()+", Renderer "+glRenderer); + } + quirks[i++] = quirk; + } + final VersionNumber osxVersionNVGLSLGood = new VersionNumber(10,7,0); // < OSX 10.7.0 w/ NV has instable GLSL + if( Platform.getOSVersionNumber().compareTo(osxVersionNVGLSLGood) < 0 ) { + final int quirk = GLRendererQuirks.GLSLNonCompliant; + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()+", Renderer "+glRenderer); + } + quirks[i++] = quirk; } - quirks[i++] = quirk; } } else if( Platform.getOSType() == Platform.OSType.WINDOWS ) { // diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java index 2b921f799..0600d99f5 100644 --- a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java +++ b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java @@ -88,10 +88,14 @@ public class AWTTilePainter { System.err.println("Hint["+count+"]: "+rEntry.getKey()+" -> "+rEntry.getValue()); } final AffineTransform aTrans = g2d.getTransform(); - System.err.println(" type "+aTrans.getType()); - System.err.println(" scale "+aTrans.getScaleX()+" x "+aTrans.getScaleY()); - System.err.println(" move "+aTrans.getTranslateX()+" x "+aTrans.getTranslateY()); - System.err.println(" mat "+aTrans); + if( null != aTrans ) { + System.err.println(" type "+aTrans.getType()); + System.err.println(" scale "+aTrans.getScaleX()+" x "+aTrans.getScaleY()); + System.err.println(" move "+aTrans.getTranslateX()+" x "+aTrans.getTranslateY()); + System.err.println(" mat "+aTrans); + } else { + System.err.println(" null transform"); + } } /** @@ -144,11 +148,6 @@ public class AWTTilePainter { flipVertical = v; } - private static Rectangle getRoundedRect(Rectangle2D r) { - if( null == r ) { return null; } - return new Rectangle((int)Math.round(r.getX()), (int)Math.round(r.getY()), - (int)Math.round(r.getWidth()), (int)Math.round(r.getHeight())); - } private static Rectangle2D getClipBounds2D(Graphics2D g) { final Shape shape = g.getClip(); return null != shape ? shape.getBounds2D() : null; @@ -188,6 +187,9 @@ public class AWTTilePainter { public void setupGraphics2DAndClipBounds(Graphics2D g2d, int width, int height) throws NoninvertibleTransformException { this.g2d = g2d; saveAT = g2d.getTransform(); + if( null == saveAT ) { + saveAT = new AffineTransform(); // use identity + } // We use double precision for scaling // // Setup original rectangles @@ -201,7 +203,7 @@ public class AWTTilePainter { { final AffineTransform scaledATI; { - final AffineTransform scaledAT = g2d.getTransform(); + final AffineTransform scaledAT = new AffineTransform(saveAT); scaledAT.scale(scaleMatX, scaleMatY); scaledATI = scaledAT.createInverse(); // -> NoninvertibleTransformException } @@ -214,8 +216,8 @@ public class AWTTilePainter { dClipScaled = scaledATI.createTransformedShape(s0).getBounds2D(); // scaled out } } - final Rectangle iClipScaled = getRoundedRect(dClipScaled); - final Rectangle iImageSizeScaled = getRoundedRect(dImageSizeScaled); + final Rectangle iClipScaled = dClipScaled.getBounds(); + final Rectangle iImageSizeScaled = dImageSizeScaled.getBounds(); renderer.setImageSize(iImageSizeScaled.width, iImageSizeScaled.height); renderer.clipImageSize(iClipScaled.width, iClipScaled.height); final int clipH = Math.min(iImageSizeScaled.height, iClipScaled.height); diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index e6334150b..0828d1dc3 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -745,7 +745,7 @@ public class MacOSXCGLContext extends GLContextImpl if (DEBUG) { System.err.println("NSOpenGLLayer.Attach: Re-Queue, drawableHandle "+toHexString(drawable.getHandle())+" - "+getThreadName()); } - OSXUtil.RunLater(this, 1); + OSXUtil.RunLater(true /* onMain */, this, 1); } } } diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java index f028d7f9c..f196ebef1 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java @@ -38,6 +38,7 @@ import javax.media.opengl.GL2ES2; import javax.media.opengl.GLException; import com.jogamp.common.os.Platform; +import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.VersionNumber; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.opengl.util.TimeFrameI; @@ -279,7 +280,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { System.err.println("initStream: p1 "+this); } - final String streamLocS=streamLoc.toString().replaceAll("%20", " "); + final String streamLocS=IOUtil.decodeFromURI(streamLoc.toString()); destroyAudioSink(); if( GLMediaPlayer.STREAM_ID_NONE == aid ) { audioSink = AudioSinkFactory.createNull(); diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java index 2e924cbfb..5349745ea 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java @@ -40,6 +40,7 @@ import javax.media.opengl.GL2ES1; import javax.media.opengl.GL2ES2; import javax.media.opengl.GL2GL3; import javax.media.opengl.GLArrayData; +import javax.media.opengl.GLES2; import javax.media.opengl.GLException; import javax.media.opengl.GLRunnable2; import javax.media.opengl.GLUniformData; @@ -741,11 +742,17 @@ public class FixedFuncPipeline { gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0xffffffff & b.get(idx0+j)), 4); } } - } else if( GL2ES1.GL_POINTS != mode ) { - gl.glDrawElements(mode, count, type, indices); } else { - // FIXME GL_POINTS ! - gl.glDrawElements(mode, count, type, indices); + // FIXME: Impl. VBO usage .. or unroll (see above)! + if( !gl.getContext().isCPUDataSourcingAvail() ) { + throw new GLException("CPU data sourcing n/a w/ "+gl.getContext()); + } + if( GL2ES1.GL_POINTS != mode ) { + ((GLES2)gl).glDrawElements(mode, count, type, indices); + } else { + // FIXME GL_POINTS ! + ((GLES2)gl).glDrawElements(mode, count, type, indices); + } } } public void glDrawElements(GL2ES2 gl, int mode, int count, int type, long indices_buffer_offset) { |