aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/FBObject.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java55
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java29
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java76
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java281
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java111
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLArrayData.java57
-rw-r--r--src/jogl/classes/javax/media/opengl/GLBase.java15
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java26
-rw-r--r--src/jogl/classes/javax/media/opengl/GLFBODrawable.java22
-rw-r--r--src/jogl/classes/javax/media/opengl/GLUniformData.java20
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java8
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java681
-rw-r--r--src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java169
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableImpl.java60
-rw-r--r--src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java14
-rw-r--r--src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java42
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java14
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java66
-rw-r--r--src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java31
-rw-r--r--src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java195
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java18
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java17
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java4
46 files changed, 1360 insertions, 784 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 40b45ead2..17589aa0e 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -31,6 +31,7 @@ package com.jogamp.opengl;
import java.util.Arrays;
import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GL3;
import javax.media.opengl.GLBase;
@@ -812,7 +813,7 @@ public class FBObject {
maxColorAttachments = 1;
if( fullFBOSupport || NV_fbo_color_attachments ) {
try {
- gl.glGetIntegerv(GL2GL3.GL_MAX_COLOR_ATTACHMENTS, val, 0);
+ gl.glGetIntegerv(GL2ES2.GL_MAX_COLOR_ATTACHMENTS, val, 0);
realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
} catch (GLException gle) { gle.printStackTrace(); }
}
@@ -2283,7 +2284,8 @@ public class FBObject {
/** Returns the framebuffer name to render to. */
public final int getWriteFramebuffer() { return fbName; }
/** Returns the framebuffer name to read from. Depending on multisampling, this may be a different framebuffer. */
- public final int getReadFramebuffer() { return ( samples > 0 ) ? samplingSink.getReadFramebuffer() : fbName; }
+ public final int getReadFramebuffer() { return ( samples > 0 ) ? samplingSink.getReadFramebuffer() : fbName; }
+ public final int getDefaultReadBuffer() { return GL.GL_COLOR_ATTACHMENT0; }
/** Return the number of color/texture attachments */
public final int getColorAttachmentCount() { return colorAttachmentCount; }
/** Return the stencil {@link RenderAttachment} attachment, if exist. Maybe share the same {@link Attachment#getName()} as {@link #getDepthAttachment()}, if packed depth-stencil is being used. */
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 0320c63ae..4ba4def9a 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -207,7 +207,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
// so we can continue with the destruction.
try {
if( !GLCanvas.this.isDisposed() ) {
- helper.disposeGL(GLCanvas.this, context);
+ helper.disposeGL(GLCanvas.this, context, true);
} else {
context.destroy();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index 88cb3303f..e0bbbc33c 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.opengl.util;
@@ -120,6 +147,17 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
return adc;
}
+ @Override
+ public void associate(Object obj, boolean enable) {
+ if(obj instanceof ShaderState) {
+ if(enable) {
+ shaderState = (ShaderState)obj;
+ } else {
+ shaderState = null;
+ }
+ }
+ }
+
//
// Data read access
//
@@ -157,7 +195,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
seal(seal);
enableBuffer(gl, seal);
}
-
+
@Override
public void enableBuffer(GL gl, boolean enable) {
if( enableBufferAlways || bufferEnabled != enable ) {
@@ -166,16 +204,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
// init/generate VBO name if not done yet
init_vbo(gl);
}
- final Object ext;
- if(usesGLSL) {
- ext = ShaderState.getShaderState(gl);
- if(null == ext) {
- throw new GLException("A ShaderState must be bound to the GL context, use 'ShaderState.setShaderState(gl)'");
- }
- } else {
- ext = null;
- }
- glArrayHandler.enableState(gl, enable, ext);
+ glArrayHandler.enableState(gl, enable, usesGLSL ? shaderState : null);
bufferEnabled = enable;
}
}
@@ -297,6 +326,8 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
", index "+index+
", location "+location+
", isVertexAttribute "+isVertexAttribute+
+ ", usesGLSL "+usesGLSL+
+ ", usesShaderState "+(null!=shaderState)+
", dataType 0x"+Integer.toHexString(componentType)+
", bufferClazz "+componentClazz+
", elements "+getElementCount()+
@@ -421,5 +452,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
protected GLArrayHandler glArrayHandler;
protected boolean usesGLSL;
+ protected ShaderState shaderState;
+
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
index c9dd98751..7e7d27b36 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.opengl.util;
@@ -332,6 +359,8 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
", index "+index+
", location "+location+
", isVertexAttribute "+isVertexAttribute+
+ ", usesGLSL "+usesGLSL+
+ ", usesShaderState "+(null!=shaderState)+
", dataType 0x"+Integer.toHexString(componentType)+
", bufferClazz "+componentClazz+
", elements "+getElementCount()+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index f4a197be1..7d08ad08f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.opengl.util;
@@ -97,53 +124,91 @@ public class GLArrayDataWrapper implements GLArrayData {
return glp.isValidArrayDataType(getIndex(), getComponentCount(), getComponentType(), isVertexAttribute(), throwException);
}
+ @Override
+ public void associate(Object obj, boolean enable) {
+ // nop
+ }
+
//
// Data read access
//
+ @Override
public final boolean isVertexAttribute() { return isVertexAttribute; }
+ @Override
public final int getIndex() { return index; }
+ @Override
public final int getLocation() { return location; }
- public final void setLocation(int v) { location = v; }
+ @Override
+ public final int setLocation(int v) { location = v; return location; }
+ @Override
+ public final int setLocation(GL2ES2 gl, int program) {
+ location = gl.glGetAttribLocation(program, name);
+ return location;
+ }
+
+ @Override
+ public final int setLocation(GL2ES2 gl, int program, int location) {
+ this.location = location;
+ gl.glBindAttribLocation(program, location, name);
+ return location;
+ }
+
+ @Override
public final String getName() { return name; }
+ @Override
public final long getVBOOffset() { return vboEnabled?vboOffset:0; }
+ @Override
public final int getVBOName() { return vboEnabled?vboName:0; }
+ @Override
public final boolean isVBO() { return vboEnabled; }
+ @Override
public final int getVBOUsage() { return vboEnabled?vboUsage:0; }
+ @Override
public final int getVBOTarget() { return vboEnabled?vboTarget:0; }
+ @Override
public final Buffer getBuffer() { return buffer; }
+ @Override
public final int getComponentCount() { return components; }
+ @Override
public final int getComponentType() { return componentType; }
+ @Override
public final int getComponentSizeInBytes() { return componentByteSize; }
+ @Override
public final int getElementCount() {
if(null==buffer) return 0;
return ( buffer.position()==0 ) ? ( buffer.limit() / components ) : ( buffer.position() / components ) ;
}
+
+ @Override
public final int getSizeInBytes() {
if(null==buffer) return 0;
return ( buffer.position()==0 ) ? ( buffer.limit() * componentByteSize ) : ( buffer.position() * componentByteSize ) ;
}
+ @Override
public final boolean getNormalized() { return normalized; }
+ @Override
public final int getStride() { return strideB; }
- public final Class getBufferClass() { return componentClazz; }
+ public final Class<?> getBufferClass() { return componentClazz; }
+ @Override
public void destroy(GL gl) {
buffer = null;
vboName=0;
@@ -152,6 +217,7 @@ public class GLArrayDataWrapper implements GLArrayData {
alive = false;
}
+ @Override
public String toString() {
return "GLArrayDataWrapper["+name+
", index "+index+
@@ -172,7 +238,7 @@ public class GLArrayDataWrapper implements GLArrayData {
"]";
}
- public static final Class getBufferClass(int dataType) {
+ public static final Class<?> getBufferClass(int dataType) {
switch(dataType) {
case GL.GL_BYTE:
case GL.GL_UNSIGNED_BYTE:
@@ -189,6 +255,7 @@ public class GLArrayDataWrapper implements GLArrayData {
}
}
+ @Override
public void setName(String newName) {
location = -1;
name = newName;
@@ -310,14 +377,13 @@ public class GLArrayDataWrapper implements GLArrayData {
protected String name;
protected int components;
protected int componentType;
- protected Class componentClazz;
+ protected Class<?> componentClazz;
protected int componentByteSize;
protected boolean normalized;
protected int strideB; // stride in bytes
protected int strideL; // stride in logical components
protected Buffer buffer;
protected boolean isVertexAttribute;
-
protected long vboOffset;
protected int vboName;
protected boolean vboEnabled;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index f01896b96..27ce7d8ec 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -35,7 +35,7 @@ import com.jogamp.opengl.util.glsl.ShaderState;
* via {@link #glEnd(GL, boolean) glEnd(gl, false)} for deferred rendering via {@link #draw(GL, boolean)}.
* </p>
* <a name="storageDetails"><h5>Buffer storage and it's creation via {@link #createFixed(int, int, int, int, int, int, int, int, int, int) createFixed(..)}
- * and {@link #createGLSL(int, int, int, int, int, int, int, int, int, int) createGLSL(..)}</h5></a>
+ * and {@link #createGLSL(int, int, int, int, int, int, int, int, int, int, ShaderState) createGLSL(..)}</h5></a>
* <p>
* If unsure whether <i>colors</i>, <i>normals</i> and <i>textures</i> will be used,
* simply add them with an expected component count.
@@ -82,13 +82,11 @@ public class ImmModeSink {
int glBufferUsage) {
return new ImmModeSink(initialElementCount,
vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
- false, glBufferUsage);
+ false, glBufferUsage, null, 0);
}
/**
- * Uses a GL2ES2 GLSL shader immediate mode sink.
- * To issue the draw() command,
- * a ShaderState must be current, using ShaderState.glUseProgram().
+ * Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given ShaderState.
* <p>
* See <a href="#storageDetails"> buffer storage details</a>.
* </p>
@@ -104,7 +102,7 @@ public class ImmModeSink {
* @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
* @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
* set to <code>0</code> for no VBO usage
- *
+ * @param st ShaderState to locate the vertex attributes
* @see #draw(GL, boolean)
* @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
* @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
@@ -114,12 +112,45 @@ public class ImmModeSink {
int cComps, int cDataType,
int nComps, int nDataType,
int tComps, int tDataType,
- int glBufferUsage) {
+ int glBufferUsage, ShaderState st) {
return new ImmModeSink(initialElementCount,
vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
- true, glBufferUsage);
+ true, glBufferUsage, st, 0);
}
+ /**
+ * Uses a GL2ES2 GLSL shader immediate mode sink, utilizing the given shader-program.
+ * <p>
+ * See <a href="#storageDetails"> buffer storage details</a>.
+ * </p>
+ *
+ * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
+ * @param vComps mandatory vertex component count, should be 2, 3 or 4.
+ * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
+ * @param cComps optional color component count, may be 0, 3 or 4
+ * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
+ * @param nComps optional normal component count, may be 0, 3 or 4
+ * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
+ * @param tComps optional texture-coordinate component count, may be 0, 2 or 3
+ * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
+ * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
+ * set to <code>0</code> for no VBO usage
+ * @param shaderProgram shader-program name to locate the vertex attributes
+ * @see #draw(GL, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
+ */
+ public static ImmModeSink createGLSL(int initialElementCount,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType,
+ int glBufferUsage, int shaderProgram) {
+ return new ImmModeSink(initialElementCount,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ true, glBufferUsage, null, shaderProgram);
+ }
+
public void destroy(GL gl) {
destroyList(gl);
@@ -330,10 +361,10 @@ public class ImmModeSink {
int cComps, int cDataType,
int nComps, int nDataType,
int tComps, int tDataType,
- boolean useGLSL, int glBufferUsage) {
- vboSet = new VBOSet(initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
- useGLSL, glBufferUsage);
+ boolean useGLSL, int glBufferUsage, ShaderState st, int shaderProgram) {
+ vboSet = new VBOSet(initialElementCount,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ useGLSL, glBufferUsage, st, shaderProgram);
this.vboSetList = new ArrayList<VBOSet>();
}
@@ -349,7 +380,7 @@ public class ImmModeSink {
* Sets the additional element count if buffer resize is required,
* defaults to <code>initialElementCount</code> of factory method.
* @see #createFixed(int, int, int, int, int, int, int, int, int, int)
- * @see #createGLSL(int, int, int, int, int, int, int, int, int, int)
+ * @see #createGLSL(int, int, int, int, int, int, int, int, int, int, ShaderState)
*/
public void setResizeElementCount(int v) { vboSet.setResizeElementCount(v); }
@@ -369,9 +400,19 @@ public class ImmModeSink {
int cComps, int cDataType,
int nComps, int nDataType,
int tComps, int tDataType,
- boolean useGLSL, int glBufferUsage) {
+ boolean useGLSL, int glBufferUsage, ShaderState st, int shaderProgram) {
+ // final ..
this.glBufferUsage=glBufferUsage;
this.initialElementCount=initialElementCount;
+ this.useVBO = 0 != glBufferUsage;
+ this.useGLSL=useGLSL;
+ this.shaderState = st;
+ this.shaderProgram = shaderProgram;
+
+ if(useGLSL && null == shaderState && 0 == shaderProgram) {
+ throw new IllegalArgumentException("Using GLSL but neither a valid shader-program nor ShaderState has been passed!");
+ }
+ // variable ..
this.resizeElementCount=initialElementCount;
this.vDataType=vDataType;
this.vDataTypeSigned=GLBuffers.isSignedGLType(vDataType);
@@ -389,8 +430,6 @@ public class ImmModeSink {
this.tDataTypeSigned=GLBuffers.isSignedGLType(tDataType);
this.tComps=tComps;
this.tCompsBytes=tComps * GLBuffers.sizeOfGLType(tDataType);
- this.useGLSL=useGLSL;
- this.useVBO = 0 != glBufferUsage;
this.vboName = 0;
this.vCount=0;
@@ -414,6 +453,7 @@ public class ImmModeSink {
this.bufferEnabled=false;
this.bufferWritten=false;
this.bufferWrittenOnce=false;
+ this.glslLocationSet = false;
}
protected int getResizeElementCount() { return resizeElementCount; }
@@ -423,7 +463,8 @@ public class ImmModeSink {
protected final VBOSet regenerate(GL gl) {
return new VBOSet(initialElementCount, vComps,
- vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL, glBufferUsage);
+ vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ useGLSL, glBufferUsage, shaderState, shaderProgram);
}
protected void checkSeal(boolean test) throws GLException {
@@ -439,10 +480,27 @@ public class ImmModeSink {
}
}
+ private boolean usingShaderProgram = false;
+
+ protected void useShaderProgram(GL2ES2 gl, boolean force) {
+ if( force || !usingShaderProgram ) {
+ if(null != shaderState) {
+ shaderState.useProgram(gl, true);
+ } else /* if( 0 != shaderProgram) */ {
+ gl.glUseProgram(shaderProgram);
+ }
+ usingShaderProgram = true;
+ }
+ }
+
protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i)
{
enableBuffer(gl, true);
-
+
+ if(null != shaderState || 0 != shaderProgram) {
+ useShaderProgram(gl.getGL2ES2(), false);
+ }
+
if(DEBUG_DRAW) {
System.err.println("ImmModeSink.draw["+i+"].0 (disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
}
@@ -788,6 +846,51 @@ public class ImmModeSink {
}
}
+ public void setShaderProgram(int program) {
+ if(null == shaderState && 0 == program) {
+ throw new IllegalArgumentException("Not allowed to zero shader program if no ShaderState is set");
+ }
+ shaderProgram = program;
+ glslLocationSet = false; // enforce location reset!
+ }
+
+ /**
+ * @param gl
+ * @return true if all locations for all used arrays are found (min 1 array), otherwise false.
+ * Also sets 'glslLocationSet' to the return value!
+ */
+ private boolean resetGLSLArrayLocation(GL2ES2 gl) {
+ int iA = 0;
+ int iL = 0;
+
+ if(null != vArrayData) {
+ iA++;
+ if( vArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ if(null != cArrayData) {
+ iA++;
+ if( cArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ if(null != nArrayData) {
+ iA++;
+ if( nArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ if(null != tArrayData) {
+ iA++;
+ if( tArrayData.setLocation(gl, shaderProgram) >= 0 ) {
+ iL++;
+ }
+ }
+ glslLocationSet = iA == iL;
+ return glslLocationSet;
+ }
+
public void destroy(GL gl) {
reset(gl);
@@ -868,8 +971,13 @@ public class ImmModeSink {
checkSeal(true);
}
bufferEnabled = enable;
- if(useGLSL) {
- enableBufferGLSL(gl, enable);
+ if(useGLSL) {
+ useShaderProgram(gl.getGL2ES2(), true);
+ if(null != shaderState) {
+ enableBufferGLSLShaderState(gl, enable);
+ } else {
+ enableBufferGLSLSimple(gl, enable);
+ }
} else {
enableBufferFixed(gl, enable);
}
@@ -901,7 +1009,7 @@ public class ImmModeSink {
}
}
- public void enableBufferFixed(GL gl, boolean enable) {
+ private void enableBufferFixed(GL gl, boolean enable) {
GL2ES1 glf = gl.getGL2ES1();
final boolean useV = vComps>0 && vElems>0 ;
@@ -969,11 +1077,75 @@ public class ImmModeSink {
}
}
- public void enableBufferGLSL(GL gl, boolean enable) {
- ShaderState st = ShaderState.getShaderState(gl);
- if(null==st) {
- throw new GLException("No ShaderState in "+gl);
- }
+ private void enableBufferGLSLShaderState(GL gl, boolean enable) {
+ GL2ES2 glsl = gl.getGL2ES2();
+
+ final boolean useV = vComps>0 && vElems>0 ;
+ final boolean useC = cComps>0 && cElems>0 ;
+ final boolean useN = nComps>0 && nElems>0 ;
+ final boolean useT = tComps>0 && tElems>0 ;
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableGLSL.A.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ }
+
+ if(enable) {
+ if(useVBO) {
+ if(0 == vboName) {
+ throw new InternalError("Using VBO but no vboName");
+ }
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+ if(!bufferWritten) {
+ writeBuffer(gl);
+ }
+ }
+ bufferWritten=true;
+ }
+
+ if(useV) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, vArrayData);
+ shaderState.vertexAttribPointer(glsl, vArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, vArrayData);
+ }
+ }
+ if(useC) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, cArrayData);
+ shaderState.vertexAttribPointer(glsl, cArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, cArrayData);
+ }
+ }
+ if(useN) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, nArrayData);
+ shaderState.vertexAttribPointer(glsl, nArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, nArrayData);
+ }
+ }
+ if(useT) {
+ if(enable) {
+ shaderState.enableVertexAttribArray(glsl, tArrayData);
+ shaderState.vertexAttribPointer(glsl, tArrayData);
+ } else {
+ shaderState.disableVertexAttribArray(glsl, tArrayData);
+ }
+ }
+ glslLocationSet = true; // ShaderState does set the location implicit
+
+ if(enable && useVBO) {
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableGLSL.A.X ");
+ }
+ }
+
+ private void enableBufferGLSLSimple(GL gl, boolean enable) {
GL2ES2 glsl = gl.getGL2ES2();
final boolean useV = vComps>0 && vElems>0 ;
@@ -982,7 +1154,20 @@ public class ImmModeSink {
final boolean useT = tComps>0 && tElems>0 ;
if(DEBUG_DRAW) {
- System.err.println("ImmModeSink.enableGLSL.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ System.err.println("ImmModeSink.enableGLSL.B.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ }
+
+ if(!glslLocationSet) {
+ if( !resetGLSLArrayLocation(glsl) ) {
+ if(DEBUG_DRAW) {
+ final int vLoc = null != vArrayData ? vArrayData.getLocation() : -1;
+ final int cLoc = null != cArrayData ? cArrayData.getLocation() : -1;
+ final int nLoc = null != nArrayData ? nArrayData.getLocation() : -1;
+ final int tLoc = null != tArrayData ? tArrayData.getLocation() : -1;
+ System.err.println("ImmModeSink.enableGLSL.B.X attribute locations in shader program "+shaderProgram+", incomplete ["+vLoc+", "+cLoc+", "+nLoc+", "+tLoc+"] - glslLocationSet "+glslLocationSet);
+ }
+ return;
+ }
}
if(enable) {
@@ -1000,34 +1185,34 @@ public class ImmModeSink {
if(useV) {
if(enable) {
- st.enableVertexAttribArray(glsl, vArrayData);
- st.vertexAttribPointer(glsl, vArrayData);
+ glsl.glEnableVertexAttribArray(vArrayData.getLocation());
+ glsl.glVertexAttribPointer(vArrayData);
} else {
- st.disableVertexAttribArray(glsl, vArrayData);
+ glsl.glDisableVertexAttribArray(vArrayData.getLocation());
}
}
if(useC) {
if(enable) {
- st.enableVertexAttribArray(glsl, cArrayData);
- st.vertexAttribPointer(glsl, cArrayData);
+ glsl.glEnableVertexAttribArray(cArrayData.getLocation());
+ glsl.glVertexAttribPointer(cArrayData);
} else {
- st.disableVertexAttribArray(glsl, cArrayData);
+ glsl.glDisableVertexAttribArray(cArrayData.getLocation());
}
}
if(useN) {
if(enable) {
- st.enableVertexAttribArray(glsl, nArrayData);
- st.vertexAttribPointer(glsl, nArrayData);
+ glsl.glEnableVertexAttribArray(nArrayData.getLocation());
+ glsl.glVertexAttribPointer(nArrayData);
} else {
- st.disableVertexAttribArray(glsl, nArrayData);
+ glsl.glDisableVertexAttribArray(nArrayData.getLocation());
}
}
if(useT) {
if(enable) {
- st.enableVertexAttribArray(glsl, tArrayData);
- st.vertexAttribPointer(glsl, tArrayData);
+ glsl.glEnableVertexAttribArray(tArrayData.getLocation());
+ glsl.glVertexAttribPointer(tArrayData);
} else {
- st.disableVertexAttribArray(glsl, tArrayData);
+ glsl.glDisableVertexAttribArray(tArrayData.getLocation());
}
}
@@ -1036,11 +1221,16 @@ public class ImmModeSink {
}
if(DEBUG_DRAW) {
- System.err.println("ImmModeSink.enableGLSL.X ");
+ System.err.println("ImmModeSink.enableGLSL.B.X ");
}
}
-
+
public String toString() {
+ final String glslS = useGLSL ?
+ ", useShaderState "+(null!=shaderState)+
+ ", shaderProgram "+shaderProgram+
+ ", glslLocationSet "+glslLocationSet : "";
+
return "VBOSet[mode "+mode+
", modeOrig "+modeOrig+
", use/count "+getElemUseCountStr()+
@@ -1049,6 +1239,8 @@ public class ImmModeSink {
", bufferEnabled "+bufferEnabled+
", bufferWritten "+bufferWritten+" (once "+bufferWrittenOnce+")"+
", useVBO "+useVBO+", vboName "+vboName+
+ ", useGLSL "+useGLSL+
+ glslS+
",\n\t"+vArrayData+
",\n\t"+cArrayData+
",\n\t"+nArrayData+
@@ -1264,7 +1456,9 @@ public class ImmModeSink {
}
final private int glBufferUsage, initialElementCount;
- final private boolean useVBO;
+ final private boolean useVBO, useGLSL;
+ final private ShaderState shaderState;
+ private int shaderProgram;
private int mode, modeOrig, resizeElementCount;
private ByteBuffer buffer;
@@ -1286,8 +1480,9 @@ public class ImmModeSink {
private Buffer vertexArray, colorArray, normalArray, textCoordArray;
private GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
- private boolean sealed, sealedGL, useGLSL;
+ private boolean sealed, sealedGL;
private boolean bufferEnabled, bufferWritten, bufferWrittenOnce;
+ private boolean glslLocationSet;
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
index ff8982ddf..9d71ee276 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -35,7 +35,6 @@ import java.util.Iterator;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLArrayData;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLUniformData;
@@ -58,7 +57,6 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
*/
public class ShaderState {
public static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLSLState", true);
- private static final String currentStateKey = "jogamp.opengl.glsl.ShaderState" ;
public ShaderState() {
}
@@ -68,46 +66,6 @@ public class ShaderState {
public void setVerbose(boolean v) { verbose = DEBUG || v; }
/**
- * Fetches the current shader state from this thread (TLS) current GLContext
- *
- * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#setShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
- */
- public static ShaderState getCurrentShaderState() {
- return getShaderState(GLContext.getCurrentGL());
- }
-
- /**
- * Gets the shader state attached to the GL object's GLContext
- *
- * @param gl the GL object referencing the GLContext
- *
- * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#setShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
- */
- public static ShaderState getShaderState(GL gl) {
- return (ShaderState) gl.getContext().getAttachedObject(currentStateKey);
- }
-
- /**
- * Attaches the shader state to the GL object's GLContext
- *
- * @param gl the GL object referencing the GLContext
- *
- * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#setShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
- */
- public final ShaderState setShaderState(GL gl) {
- return (ShaderState) gl.getContext().attachObject(currentStateKey, this);
- }
-
- /**
* Returns the attached user object for the given name to this ShaderState.
*/
public final Object getAttachedObject(String name) {
@@ -135,19 +93,14 @@ public class ShaderState {
/**
* Turns the shader program on or off.<br>
- * Puts this ShaderState to to the thread local storage (TLS),
- * if <code>on</code> is <code>true</code>.
*
* @throws GLException if no program is attached
*
* @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
public synchronized void useProgram(GL2ES2 gl, boolean on) throws GLException {
if(null==shaderProgram) { throw new GLException("No program is attached"); }
if(on) {
- setShaderState(gl);
if(shaderProgram.linked()) {
shaderProgram.useProgram(gl, true);
if(resetAllShaderData) {
@@ -332,6 +285,10 @@ public class ShaderState {
return activeAttribDataMap.get(name);
}
+ public boolean isActiveAttribute(GLArrayData attribute) {
+ return attribute == activeAttribDataMap.get(attribute.getName());
+ }
+
/**
* Binds or unbinds the {@link GLArrayData} lifecycle to this ShaderState.
*
@@ -343,11 +300,14 @@ public class ShaderState {
*
* <p>The data will not be transfered to the GPU, use {@link #vertexAttribPointer(GL2ES2, GLArrayData)} additionally.</p>
*
+ * <p>The data will also be {@link GLArrayData#associate(Object, boolean) associated} with this ShaderState.</p>
+ *
* @param attribute the {@link GLArrayData} which lifecycle shall be managed
* @param own true if <i>owning</i> shall be performs, false if <i>disowning</i>.
*
* @see #bindAttribLocation(GL2ES2, int, String)
* @see #getAttribute(String)
+ * @see GLArrayData#associate(Object, boolean)
*/
public void ownAttribute(GLArrayData attribute, boolean own) {
if(own) {
@@ -359,6 +319,7 @@ public class ShaderState {
} else {
managedAttributes.remove(attribute);
}
+ attribute.associate(this, own);
}
public boolean ownsAttribute(GLArrayData attribute) {
@@ -402,8 +363,12 @@ public class ShaderState {
* @see #getAttribute(String)
*/
public void bindAttribLocation(GL2ES2 gl, int location, GLArrayData data) {
- bindAttribLocation(gl, location, data.getName());
- data.setLocation(location);
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(shaderProgram.linked()) throw new GLException("Program is already linked");
+ final String name = data.getName();
+ final Integer loc = new Integer(location);
+ activeAttribLocationMap.put(name, loc);
+ data.setLocation(gl, shaderProgram.program(), location);
activeAttribDataMap.put(data.getName(), data);
}
@@ -465,8 +430,27 @@ public class ShaderState {
* @see #getAttribute(String)
*/
public int getAttribLocation(GL2ES2 gl, GLArrayData data) {
- int location = getAttribLocation(gl, data.getName());
- data.setLocation(location);
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ final String name = data.getName();
+ int location = getCachedAttribLocation(name);
+ if(0<=location) {
+ data.setLocation(location);
+ } else {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ location = data.setLocation(gl, shaderProgram.program());
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ activeAttribLocationMap.put(name, idx);
+ if(DEBUG) {
+ System.err.println("ShaderState: glGetAttribLocation: "+name+", loc: "+location);
+ }
+ } else if(verbose) {
+ System.err.println("ShaderState: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ }
+ }
activeAttribDataMap.put(data.getName(), data);
return location;
}
@@ -873,6 +857,7 @@ public class ShaderState {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
int location = getCachedUniformLocation(name);
if(0>location) {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
location = gl.glGetUniformLocation(shaderProgram.program(), name);
if(0<=location) {
Integer idx = new Integer(location);
@@ -886,7 +871,7 @@ public class ShaderState {
}
return location;
}
-
+
/**
* Validates and returns the location of a shader uniform.<br>
* Uses either the cached value {@link #getCachedUniformLocation(String)} if valid,
@@ -908,9 +893,25 @@ public class ShaderState {
* @see ShaderProgram#glReplaceShader
*/
public int getUniformLocation(GL2ES2 gl, GLUniformData data) {
- int location = getUniformLocation(gl, data.getName());
- data.setLocation(location);
- activeUniformDataMap.put(data.getName(), data);
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ final String name = data.getName();
+ int location = getCachedUniformLocation(name);
+ if(0<=location) {
+ data.setLocation(location);
+ } else {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ location = data.setLocation(gl, shaderProgram.program());
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ activeUniformLocationMap.put(name, idx);
+ } else if(verbose) {
+ System.err.println("ShaderState: glUniform failed, no location for: "+name+", index: "+location);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ }
+ }
+ activeUniformDataMap.put(name, data);
return location;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
index d8d6f7daa..d9be4ce31 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
@@ -144,7 +144,7 @@ public class PNGImage {
/** Returns the dpi of the image. */
public double[] getDpi() { return dpi; }
- /** Returns the OpenGL format for this texture; e.g. GL.GL_BGR or GL.GL_BGRA. */
+ /** Returns the OpenGL format for this texture; e.g. GL.GL_LUMINANCE, GL.GL_RGB or GL.GL_RGBA. */
public int getGLFormat() { return glFormat; }
/** Returns the OpenGL data type: GL.GL_UNSIGNED_BYTE. */
diff --git a/src/jogl/classes/javax/media/opengl/GLArrayData.java b/src/jogl/classes/javax/media/opengl/GLArrayData.java
index 5d17f6874..8e1383031 100644
--- a/src/jogl/classes/javax/media/opengl/GLArrayData.java
+++ b/src/jogl/classes/javax/media/opengl/GLArrayData.java
@@ -30,6 +30,8 @@ package javax.media.opengl;
import java.nio.Buffer;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+
/**
*
* The total number of bytes hold by the referenced buffer is:
@@ -38,6 +40,19 @@ import java.nio.Buffer;
*/
public interface GLArrayData {
/**
+ * Implementation and type dependent object association.
+ * <p>
+ * One currently known use case is to associate a {@link com.jogamp.opengl.util.glsl.ShaderState ShaderState}
+ * to an GLSL aware vertex attribute object, allowing to use the ShaderState to handle it's
+ * data persistence, location and state change.<br/>
+ * This is implicitly done via {@link com.jogamp.opengl.util.glsl.ShaderState#ownAttribute(GLArrayData, boolean) shaderState.ownAttribute(GLArrayData, boolean)}.
+ * </p>
+ * @param obj implementation and type dependent association
+ * @param enable pass true to enable the association and false to disable it.
+ */
+ public void associate(Object obj, boolean enable);
+
+ /**
* Returns true if this data set is intended for a GLSL vertex shader attribute,
* otherwise false, ie intended for fixed function vertex pointer
*/
@@ -47,10 +62,10 @@ public interface GLArrayData {
* The index of the predefined array index, see list below,
* or -1 in case of a shader attribute array.
*
- * @see javax.media.opengl.GL2#GL_VERTEX_ARRAY
- * @see javax.media.opengl.GL2#GL_NORMAL_ARRAY
- * @see javax.media.opengl.GL2#GL_COLOR_ARRAY
- * @see javax.media.opengl.GL2#GL_TEXTURE_COORD_ARRAY
+ * @see GLPointerFunc#GL_VERTEX_ARRAY
+ * @see GLPointerFunc#GL_NORMAL_ARRAY
+ * @see GLPointerFunc#GL_COLOR_ARRAY
+ * @see GLPointerFunc#GL_TEXTURE_COORD_ARRAY
*/
public int getIndex();
@@ -61,6 +76,11 @@ public interface GLArrayData {
/**
* Set a new name for this array.
+ * <p>
+ * This clears the location, i.e. sets it to -1.
+ * </p>
+ * @see #setLocation(int)
+ * @see #setLocation(GL2ES2, int)
*/
public void setName(String newName);
@@ -72,14 +92,37 @@ public interface GLArrayData {
public int getLocation();
/**
- * Sets the determined location of the shader attribute
- * This is usually done within ShaderState.
+ * Sets the given location of the shader attribute
*
+ * @return the given location
* @see com.jogamp.opengl.util.glsl.ShaderState#vertexAttribPointer(GL2ES2, GLArrayData)
*/
- public void setLocation(int v);
+ public int setLocation(int v);
/**
+ * Retrieves the location of the shader attribute from the linked shader program.
+ * <p>
+ * No validation is performed within the implementation.
+ * </p>
+ * @param gl
+ * @param program
+ * @return &ge;0 denotes a valid attribute location as found and used in the given shader program.
+ * &lt;0 denotes an invalid location, i.e. not found or used in the given shader program.
+ */
+ public int setLocation(GL2ES2 gl, int program);
+
+ /**
+ * Binds the location of the shader attribute to the given location for the unlinked shader program.
+ * <p>
+ * No validation is performed within the implementation.
+ * </p>
+ * @param gl
+ * @param program
+ * @return the given location
+ */
+ public int setLocation(GL2ES2 gl, int program, int location);
+
+ /**
* Determines whether the data is server side (VBO) and enabled,
* or a client side array (false).
*/
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index 9bcee819a..82bb06b9c 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -432,6 +432,19 @@ public interface GLBase {
* </p>
*/
public int getDefaultReadFramebuffer();
-
+
+ /**
+ * Returns the default color buffer within the current bound
+ * {@link #getDefaultReadFramebuffer()}, i.e. GL_READ_FRAMEBUFFER​,
+ * which will be used as the source for pixel reading commands,
+ * like {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)} etc.
+ * <p>
+ * For offscreen framebuffer objects this is {@link GL#GL_COLOR_ATTACHMENT0},
+ * otherwise this is {@link GL#GL_FRONT} for single buffer configurations
+ * and {@link GL#GL_BACK} for double buffer configurations.
+ * </p>
+ */
+ public int getDefaultReadBuffer();
+
}
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index de10a2815..235003c38 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -970,6 +970,32 @@ public abstract class GLContext {
*/
public abstract int getDefaultReadFramebuffer();
+ /**
+ * Returns the default color buffer within the current bound
+ * {@link #getDefaultReadFramebuffer()}, i.e. GL_READ_FRAMEBUFFER​,
+ * which will be used as the source for pixel reading commands,
+ * like {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)} etc.
+ * <p>
+ * For offscreen framebuffer objects this is {@link GL#GL_COLOR_ATTACHMENT0},
+ * otherwise this is {@link GL#GL_FRONT} for single buffer configurations
+ * and {@link GL#GL_BACK} for double buffer configurations.
+ * </p>
+ */
+ public abstract int getDefaultReadBuffer();
+
+ /** On some platforms the mismatch between OpenGL's coordinate
+ system (origin at bottom left) and the window system's
+ coordinate system (origin at top left) necessitates a vertical
+ flip of pixels read from offscreen contexts.
+ <p>
+ Default impl. is <code>true</code>.
+ </p>
+ */
+ public abstract boolean isGLOrientationFlippedVertical();
+
+ /** Get the default pixel data type, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}. */
+ public abstract int getDefaultPixelDataType();
+
/**
* @return The extension implementing the GLDebugOutput feature,
* either <i>GL_ARB_debug_output</i> or <i>GL_AMD_debug_output</i>.
diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
index 079d9af5c..4d6c7c20e 100644
--- a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
@@ -101,7 +101,8 @@ public interface GLFBODrawable extends GLDrawable {
void setTextureUnit(int unit);
/**
- * Set a new sample size
+ * Set the number of sample buffers if using MSAA
+ *
* @param gl GL context object bound to this drawable, will be made current during operation.
* A prev. current context will be make current after operation.
* @param newSamples new sample size
@@ -113,6 +114,25 @@ public interface GLFBODrawable extends GLDrawable {
* @return the number of sample buffers if using MSAA, otherwise 0
*/
int getNumSamples();
+
+ /**
+ * Sets the number of buffers (FBO) being used if using {@link GLCapabilities#getDoubleBuffered() double buffering}.
+ * <p>
+ * If {@link GLCapabilities#getDoubleBuffered() double buffering} is not chosen, this is a NOP.
+ * </p>
+ * <p>
+ * Must be called before {@link #isInitialized() initialization}, otherwise an exception is thrown.
+ * </p>
+ * @return the new number of buffers (FBO) used, maybe different than the requested <code>bufferCount</code> (see above)
+ * @throws GLException if already initialized, see {@link #isInitialized()}.
+ */
+ int setNumBuffers(int bufferCount) throws GLException;
+
+ /**
+ * @return the number of buffers (FBO) being used. 1 if not using {@link GLCapabilities#getDoubleBuffered() double buffering},
+ * otherwise &ge; 2, depending on {@link #setNumBuffers(int)}.
+ */
+ int getNumBuffers();
/**
* @return the used {@link DoubleBufferMode}
diff --git a/src/jogl/classes/javax/media/opengl/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
index 18a422670..60d0c58bf 100644
--- a/src/jogl/classes/javax/media/opengl/GLUniformData.java
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -147,10 +147,26 @@ public class GLUniformData {
public int getLocation() { return location; }
/**
- * Sets the determined location of the shader uniform.
+ * Sets the given location of the shader uniform.
+ * @return the given location
*/
- public GLUniformData setLocation(int location) { this.location=location; return this; }
+ public int setLocation(int location) { this.location=location; return location; }
+ /**
+ * Retrieves the location of the shader uniform from the linked shader program.
+ * <p>
+ * No validation is performed within the implementation.
+ * </p>
+ * @param gl
+ * @param program
+ * @return &ge;0 denotes a valid uniform location as found and used in the given shader program.
+ * &lt;0 denotes an invalid location, i.e. not found or used in the given shader program.
+ */
+ public int setLocation(GL2ES2 gl, int program) {
+ location = gl.glGetUniformLocation(program, name);
+ return location;
+ }
+
public Object getObject() {
return data;
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index a40cdcf88..efdc69ed8 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -915,7 +915,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// Catch dispose GLExceptions by GLEventListener, just 'print' them
// so we can continue with the destruction.
try {
- helper.disposeGL(GLCanvas.this, context);
+ helper.disposeGL(GLCanvas.this, context, true);
} catch (GLException gle) {
gle.printStackTrace();
}
@@ -1024,7 +1024,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
final RecursiveLock _lock = lock;
_lock.lock();
try {
- helper.invokeGL(drawable, context, displayAction, initAction);
+ if( null != drawable && drawable.isRealized() ) {
+ helper.invokeGL(drawable, context, displayAction, initAction);
+ }
} finally {
_lock.unlock();
}
@@ -1037,7 +1039,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
final RecursiveLock _lock = lock;
_lock.lock();
try {
- if(null != drawable) {
+ if( null != drawable && drawable.isRealized() ) {
drawable.swapBuffers();
}
} finally {
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index dcfc1f0dd..23dedaa66 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -49,10 +49,8 @@ import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.beans.Beans;
-import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.List;
@@ -73,7 +71,7 @@ import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLFBODrawable;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import javax.media.opengl.Threading;
@@ -86,10 +84,11 @@ import jogamp.opengl.GLDrawableHelper;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.awt.Java2D;
import jogamp.opengl.awt.Java2DGLContext;
+import jogamp.opengl.util.glsl.GLSLTextureRaster;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
import com.jogamp.opengl.FBObject;
-import com.jogamp.opengl.util.GLBuffers;
+import com.jogamp.opengl.util.GLPixelStorageModes;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
// context whenever the displayChanged() function is called on their
@@ -122,14 +121,17 @@ import com.jogamp.opengl.util.GLBuffers;
* </P>
*/
-@SuppressWarnings({ "serial", "deprecation" })
+@SuppressWarnings("serial")
public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("GLJPanel");
private GLDrawableHelper helper = new GLDrawableHelper();
private volatile boolean isInitialized;
+ //
// Data used for either pbuffers or pixmap-based offscreen surfaces
+ //
+ /** Single buffered offscreen caps */
private GLCapabilitiesImmutable offscreenCaps;
private GLProfile glProfile;
private GLDrawableFactoryImpl factory;
@@ -150,16 +152,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Used by all backends either directly or indirectly to hook up callbacks
private Updater updater = new Updater();
- // Turns off the pbuffer-based backend (used by default, unless the
- // Java 2D / OpenGL pipeline is in use)
- private static boolean hardwareAccelerationDisabled =
- Debug.isPropertyDefined("jogl.gljpanel.nohw", true);
-
- // Turns off the fallback to software-based rendering from
- // pbuffer-based rendering
- private static boolean softwareRenderingDisabled =
- Debug.isPropertyDefined("jogl.gljpanel.nosw", true);
-
// Indicates whether the Java 2D OpenGL pipeline is enabled
private boolean oglPipelineEnabled =
Java2D.isOGLPipelineActive() &&
@@ -354,7 +346,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// re-creating it -- tricky to do properly while the context is
// current
if (handleReshape) {
- handleReshape();
+ handleReshape = false;
+ sendReshape = handleReshape();
}
updater.setGraphics(g);
@@ -395,8 +388,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
called on all registered {@link GLEventListener}s. Subclasses
which override this method must call super.reshape() in
their reshape() method in order to function properly. <P>
-
- <DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ *
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("deprecation")
@Override
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
@@ -618,12 +613,18 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
public NativeSurface getNativeSurface() {
- throw new GLException("FIXME");
+ if(null != backend) {
+ return backend.getDrawable().getNativeSurface();
+ }
+ return null;
}
@Override
public long getHandle() {
- throw new GLException("FIXME");
+ if(null != backend) {
+ return backend.getDrawable().getNativeSurface().getSurfaceHandle();
+ }
+ return 0;
}
@Override
@@ -636,13 +637,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
//
private void createAndInitializeBackend() {
- if (panelWidth == 0 ||
- panelHeight == 0) {
+ if ( 0 >= panelWidth || 0 >= panelHeight ) {
// See whether we have a non-zero size yet and can go ahead with
// initialization
- if (reshapeWidth == 0 ||
- reshapeHeight == 0) {
- return;
+ if (0 >= reshapeWidth || 0 >= reshapeHeight ) {
+ return;
}
// Pull down reshapeWidth and reshapeHeight into panelWidth and
@@ -652,29 +651,18 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
panelHeight = reshapeHeight;
}
- do {
- if (backend == null) {
+ if ( null == backend ) {
if (oglPipelineEnabled) {
- backend = new J2DOGLBackend();
+ backend = new J2DOGLBackend();
} else {
- if (!hardwareAccelerationDisabled &&
- factory.canCreateGLPbuffer(null)) {
- backend = new PbufferBackend();
- } else {
- if (softwareRenderingDisabled) {
- throw new GLException("Fallback to software rendering disabled by user");
- }
- backend = new SoftwareBackend();
- }
+ backend = new OffscreenBackend();
}
- }
+ isInitialized = false;
+ }
- if (!isInitialized) {
+ if (!isInitialized) {
backend.initialize();
- }
- // The backend might set itself to null, indicating it punted to
- // a different implementation -- try again
- } while (backend == null);
+ }
awtWindowClosingProtocol.addClosingListenerOneShot();
}
@@ -689,7 +677,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return awtWindowClosingProtocol.setDefaultCloseOperation(op);
}
- private void handleReshape() {
+ private boolean handleReshape() {
panelWidth = reshapeWidth;
panelHeight = reshapeHeight;
@@ -698,9 +686,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
panelWidth + "," + panelHeight + ")");
}
- sendReshape = true;
- backend.handleReshape();
- handleReshape = false;
+ return backend.handleReshape();
}
// This is used as the GLEventListener for the pbuffer-based backend
@@ -762,16 +748,17 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
public void run() {
if ( null != backend ) {
final GLContext _context = backend.getContext();
+ final boolean backendDestroy = !backend.isUsingOwnLifecycle();
if( null != _context && _context.isCreated() ) {
// Catch dispose GLExceptions by GLEventListener, just 'print' them
// so we can continue with the destruction.
try {
- helper.disposeGL(GLJPanel.this, _context);
+ helper.disposeGL(GLJPanel.this, _context, !backendDestroy);
} catch (GLException gle) {
gle.printStackTrace();
}
}
- if ( !backend.isUsingOwnThreadManagment() ) {
+ if ( backendDestroy ) {
backend.destroy();
backend = null;
isInitialized = false;
@@ -815,15 +802,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
};
- private int getNextPowerOf2(int number) {
- // Workaround for problems where 0 width or height are transiently
- // seen during layout
- if (number == 0) {
- return 2;
- }
- return GLBuffers.getNextPowerOf2(number);
- }
-
private int getGLInteger(GL gl, int which) {
int[] tmp = new int[1];
gl.glGetIntegerv(which, tmp, 0);
@@ -843,7 +821,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// / JOGL bridge
static interface Backend {
// Create, Destroy, ..
- public boolean isUsingOwnThreadManagment();
+ public boolean isUsingOwnLifecycle();
// Called each time the backend needs to initialize itself
public void initialize();
@@ -876,7 +854,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Called to handle a reshape event. When this is called, the
// OpenGL context associated with the backend is not current, to
// make it easier to destroy and re-create pbuffers if necessary.
- public void handleReshape();
+ public boolean handleReshape();
// Called before the OpenGL work is done in init() and display().
// If false is returned, this render is aborted.
@@ -894,12 +872,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Base class used by both the software (pixmap) and pbuffer
// backends, both of which rely on reading back the OpenGL frame
// buffer and drawing it with a BufferedImage
- abstract class AbstractReadbackBackend implements Backend {
+ class OffscreenBackend implements Backend {
// This image is exactly the correct size to render into the panel
protected BufferedImage offscreenImage;
// One of these is used to store the read back pixels before storing
// in the BufferedImage
- protected ByteBuffer readBackBytes;
protected IntBuffer readBackInts;
protected int readBackWidthInPixels;
protected int readBackHeightInPixels;
@@ -907,12 +884,118 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private int glFormat;
private int glType;
+ // Implementation using software rendering
+ private GLDrawableImpl offscreenDrawable;
+ private FBObject fboFlipped;
+ private GLSLTextureRaster glslTextureRaster;
+ private final int fboTextureUnit = 0;
+
+ private GLContextImpl offscreenContext;
+ private boolean flippedVertical;
+
// For saving/restoring of OpenGL state during ReadPixels
- private int[] swapbytes = new int[1];
- private int[] rowlength = new int[1];
- private int[] skiprows = new int[1];
- private int[] skippixels = new int[1];
- private int[] alignment = new int[1];
+ private final GLPixelStorageModes psm = new GLPixelStorageModes();
+
+ @Override
+ public boolean isUsingOwnLifecycle() { return false; }
+
+ @Override
+ public void initialize() {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": OffscreenBackend: initialize()");
+ }
+ try {
+ offscreenDrawable = (GLDrawableImpl) factory.createOffscreenDrawable(
+ null /* default platform device */,
+ offscreenCaps,
+ chooser,
+ panelWidth, panelHeight);
+ offscreenDrawable.setRealized(true);
+ offscreenContext = (GLContextImpl) offscreenDrawable.createContext(shareWith);
+ offscreenContext.setContextCreationFlags(additionalCtxCreationFlags);
+ if( GLContext.CONTEXT_NOT_CURRENT < offscreenContext.makeCurrent() ) {
+ isInitialized = true;
+ final GL gl = offscreenContext.getGL();
+ flippedVertical = offscreenContext.isGLOrientationFlippedVertical();
+ final GLCapabilitiesImmutable chosenCaps = offscreenDrawable.getChosenGLCapabilities();
+ if( chosenCaps.isFBO() && flippedVertical && gl.isGL2ES2() ) {
+ helper.setAutoSwapBufferMode(false);
+ final GLFBODrawable fboDrawable = (GLFBODrawable) offscreenDrawable;
+ try {
+ fboFlipped = new FBObject();
+ fboFlipped.reset(gl, fboDrawable.getWidth(), fboDrawable.getHeight(), 0, false);
+ fboFlipped.attachTexture2D(gl, 0, chosenCaps.getAlphaBits()>0);
+ // fboFlipped.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+ glslTextureRaster = new GLSLTextureRaster(fboTextureUnit, true);
+ glslTextureRaster.init(gl.getGL2ES2());
+ glslTextureRaster.reshape(gl.getGL2ES2(), 0, 0, fboDrawable.getWidth(), fboDrawable.getHeight());
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ if(null != glslTextureRaster) {
+ glslTextureRaster.dispose(gl.getGL2ES2());
+ glslTextureRaster = null;
+ }
+ if(null != fboFlipped) {
+ fboFlipped.destroy(gl);
+ fboFlipped = null;
+ }
+ }
+ } else {
+ fboFlipped = null;
+ glslTextureRaster = null;
+ }
+ offscreenContext.release();
+ } else {
+ isInitialized = false;
+ }
+ } finally {
+ if( !isInitialized ) {
+ if(null != offscreenContext) {
+ offscreenContext.destroy();
+ offscreenContext = null;
+ }
+ if(null != offscreenDrawable) {
+ offscreenDrawable.setRealized(false);
+ offscreenDrawable = null;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void destroy() {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": OffscreenBackend: destroy() - offscreenContext: "+(null!=offscreenContext)+" - offscreenDrawable: "+(null!=offscreenDrawable));
+ }
+ if ( null != offscreenContext && offscreenContext.isCreated() ) {
+ if( GLContext.CONTEXT_NOT_CURRENT < offscreenContext.makeCurrent() ) {
+ try {
+ final GL gl = offscreenContext.getGL();
+ if(null != glslTextureRaster) {
+ glslTextureRaster.dispose(gl.getGL2ES2());
+ }
+ if(null != fboFlipped) {
+ fboFlipped.destroy(gl);
+ }
+ } finally {
+ offscreenContext.destroy();
+ }
+ }
+ }
+ offscreenContext = null;
+ glslTextureRaster = null;
+ fboFlipped = null;
+ offscreenContext = null;
+
+ if (offscreenDrawable != null) {
+ final AbstractGraphicsDevice adevice = offscreenDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
+ offscreenDrawable.setRealized(false);
+ offscreenDrawable = null;
+ if(null != adevice) {
+ adevice.close();
+ }
+ }
+ }
@Override
public void setOpaque(boolean opaque) {
@@ -935,128 +1018,85 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
if (isDisplay) {
// Must now copy pixels from offscreen context into surface
if (offscreenImage == null) {
- if (panelWidth > 0 && panelHeight > 0) {
- // It looks like NVidia's drivers (at least the ones on my
- // notebook) are buggy and don't allow a sub-rectangle to be
- // read from a pbuffer...this doesn't really matter because
- // it's the Graphics.drawImage() calls that are the
- // bottleneck
-
- int awtFormat = 0;
-
- // Should be more flexible in these BufferedImage formats;
- // perhaps see what the preferred image types are on the
- // given platform
- if (isOpaque()) {
- awtFormat = BufferedImage.TYPE_INT_RGB;
- } else {
- awtFormat = BufferedImage.TYPE_INT_ARGB;
- }
-
- offscreenImage = new BufferedImage(panelWidth,
- panelHeight,
- awtFormat);
- switch (awtFormat) {
- case BufferedImage.TYPE_3BYTE_BGR:
- glFormat = GL2.GL_BGR;
- glType = GL.GL_UNSIGNED_BYTE;
- readBackBytes = ByteBuffer.allocate(readBackWidthInPixels * readBackHeightInPixels * 3);
- break;
-
- case BufferedImage.TYPE_INT_RGB:
- case BufferedImage.TYPE_INT_ARGB:
- glFormat = GL.GL_BGRA;
- glType = getGLPixelType();
+ if (0 >= panelWidth || 0 >= panelHeight ) {
+ return;
+ }
+ final boolean withAlpha = !isOpaque();
+
+ glFormat = GL.GL_BGRA;
+ glType = GL.GL_UNSIGNED_BYTE; // offscreenContext.getDefaultPixelDataType();
+
+ if(!flippedVertical || null != glslTextureRaster) {
+ offscreenImage = new BufferedImage(panelWidth, panelHeight, withAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
+ final int[] readBackIntBuffer = ((DataBufferInt) offscreenImage.getRaster().getDataBuffer()).getData();
+ readBackInts = IntBuffer.wrap(readBackIntBuffer);
+ } else {
+ offscreenImage = new BufferedImage(panelWidth, panelHeight, withAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
readBackInts = IntBuffer.allocate(readBackWidthInPixels * readBackHeightInPixels);
- break;
-
- default:
- // FIXME: Support more off-screen image types (current
- // offscreen context implementations don't use others, and
- // some of the OpenGL formats aren't supported in the 1.1
- // headers, which we're currently using)
- throw new GLException("Unsupported offscreen image type " + awtFormat);
- }
+ }
+ if(DEBUG) {
+ System.err.println(getThreadName()+": OffscreenBackend postGL offscreenImage-init: flippedVertical "+flippedVertical+", glslTextureRaster "+(null!=glslTextureRaster));
}
}
- if (offscreenImage != null) {
- GL2 gl = getGL().getGL2();
- // Save current modes
- gl.glGetIntegerv(GL2.GL_PACK_SWAP_BYTES, swapbytes, 0);
- gl.glGetIntegerv(GL2.GL_PACK_ROW_LENGTH, rowlength, 0);
- gl.glGetIntegerv(GL2.GL_PACK_SKIP_ROWS, skiprows, 0);
- gl.glGetIntegerv(GL2.GL_PACK_SKIP_PIXELS, skippixels, 0);
- gl.glGetIntegerv(GL2.GL_PACK_ALIGNMENT, alignment, 0);
-
- gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, GL.GL_FALSE);
- gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, readBackWidthInPixels);
- gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, 0);
- gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, 0);
- gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 1);
-
- // Actually read the pixels.
- gl.glReadBuffer(GL2.GL_FRONT);
- if (readBackBytes != null) {
- gl.glReadPixels(0, 0, readBackWidthInPixels, readBackHeightInPixels, glFormat, glType, readBackBytes);
- } else if (readBackInts != null) {
+ final GL gl = offscreenContext.getGL();
+
+ // Save current modes
+ psm.setAlignment(gl, 1, 1);
+ if(gl.isGL2GL3()) {
+ final GL2GL3 gl2gl3 = gl.getGL2GL3();
+ gl2gl3.glPixelStorei(GL2GL3.GL_PACK_ROW_LENGTH, readBackWidthInPixels);
+ gl2gl3.glReadBuffer(gl2gl3.getDefaultReadBuffer());
+ }
+
+ if(null != glslTextureRaster) { // implies flippedVertical
+ // perform vert-flipping via OpenGL/FBO
+ final GLFBODrawable fboDrawable = (GLFBODrawable)offscreenDrawable;
+ final FBObject.TextureAttachment fboTex = fboDrawable.getTextureBuffer(GL.GL_FRONT);
+
+ fboDrawable.swapBuffers();
+ fboFlipped.bind(gl);
+
+ // gl.glActiveTexture(fboDrawable.getTextureUnit()); // implicit!
+ gl.glBindTexture(GL.GL_TEXTURE_2D, fboTex.getName());
+ // gl.glClear(GL.GL_DEPTH_BUFFER_BIT); // fboFlipped runs w/o DEPTH!
+ glslTextureRaster.display(gl.getGL2ES2());
gl.glReadPixels(0, 0, readBackWidthInPixels, readBackHeightInPixels, glFormat, glType, readBackInts);
- }
- // Restore saved modes.
- gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, swapbytes[0]);
- gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, rowlength[0]);
- gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, skiprows[0]);
- gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, skippixels[0]);
- gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, alignment[0]);
-
- if (readBackBytes != null || readBackInts != null) {
- // Copy temporary data into raster of BufferedImage for faster
- // blitting Note that we could avoid this copy in the cases
- // where !offscreenContext.offscreenImageNeedsVerticalFlip(),
- // but that's the software rendering path which is very slow
- // anyway
- Object src = null;
- Object dest = null;
- int srcIncr = 0;
- int destIncr = 0;
-
- if (readBackBytes != null) {
- src = readBackBytes.array();
- dest = ((DataBufferByte) offscreenImage.getRaster().getDataBuffer()).getData();
- srcIncr = readBackWidthInPixels * 3;
- destIncr = offscreenImage.getWidth() * 3;
- } else {
- src = readBackInts.array();
- dest = ((DataBufferInt) offscreenImage.getRaster().getDataBuffer()).getData();
- srcIncr = readBackWidthInPixels;
- destIncr = offscreenImage.getWidth();
+ fboFlipped.unbind(gl);
+ } else {
+ gl.glReadPixels(0, 0, readBackWidthInPixels, readBackHeightInPixels, glFormat, glType, readBackInts);
+
+ if ( flippedVertical ) {
+ // Copy temporary data into raster of BufferedImage for faster
+ // blitting Note that we could avoid this copy in the cases
+ // where !offscreenContext.offscreenImageNeedsVerticalFlip(),
+ // but that's the software rendering path which is very slow
+ // anyway
+ final Object src = readBackInts.array();
+ final Object dest = ((DataBufferInt) offscreenImage.getRaster().getDataBuffer()).getData();
+ final int srcIncr = readBackWidthInPixels;
+ final int destIncr = offscreenImage.getWidth();
+ int srcPos = 0;
+ int destPos = (offscreenImage.getHeight() - 1) * destIncr;
+ for (; destPos >= 0; srcPos += srcIncr, destPos -= destIncr) {
+ System.arraycopy(src, srcPos, dest, destPos, destIncr);
+ }
}
+ }
- if (flipVertically()) {
- int srcPos = 0;
- int destPos = (offscreenImage.getHeight() - 1) * destIncr;
- for (; destPos >= 0; srcPos += srcIncr, destPos -= destIncr) {
- System.arraycopy(src, srcPos, dest, destPos, destIncr);
- }
- } else {
- int srcPos = 0;
- int destEnd = destIncr * offscreenImage.getHeight();
- for (int destPos = 0; destPos < destEnd; srcPos += srcIncr, destPos += destIncr) {
- System.arraycopy(src, srcPos, dest, destPos, destIncr);
- }
- }
+ // Restore saved modes.
+ psm.restore(gl);
- // Note: image will be drawn back in paintComponent() for
- // correctness on all platforms
- }
- }
+ // Note: image will be drawn back in paintComponent() for
+ // correctness on all platforms
}
}
@Override
public void doPaintComponent(Graphics g) {
- doPaintComponentImpl();
+ helper.invokeGL(offscreenDrawable, offscreenContext, updaterDisplayAction, updaterInitAction);
+
if (offscreenImage != null) {
// Draw resulting image in one shot
g.drawImage(offscreenImage, 0, 0,
@@ -1066,57 +1106,52 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
- protected abstract void doPaintComponentImpl();
- protected abstract int getGLPixelType();
- protected abstract boolean flipVertically();
- }
-
- class SoftwareBackend extends AbstractReadbackBackend {
- // Implementation using software rendering
- private GLDrawableImpl offscreenDrawable;
- private GLContextImpl offscreenContext;
-
- @Override
- public boolean isUsingOwnThreadManagment() { return false; }
-
@Override
- public void initialize() {
- if(DEBUG) {
- System.err.println(getThreadName()+": SoftwareBackend: initialize()");
- }
- // Fall-through path: create an offscreen context instead
- offscreenDrawable = (GLDrawableImpl) factory.createOffscreenDrawable(
- null /* default platform device */,
- offscreenCaps,
- chooser,
- Math.max(1, panelWidth),
- Math.max(1, panelHeight));
- offscreenDrawable.setRealized(true);
- offscreenContext = (GLContextImpl) offscreenDrawable.createContext(shareWith);
- offscreenContext.setContextCreationFlags(additionalCtxCreationFlags);
-
- isInitialized = true;
- }
+ public boolean handleReshape() {
+ /** FIXME: Shall we utilize such resize optimization (snippet kept alive from removed pbuffer backend) ?
+ // Use factor larger than 2 during shrinks for some hysteresis
+ float shrinkFactor = 2.5f;
+ if ( (panelWidth > readBackWidthInPixels) || (panelHeight > readBackHeightInPixels) ||
+ (panelWidth < (readBackWidthInPixels / shrinkFactor)) || (panelHeight < (readBackHeightInPixels / shrinkFactor))) {
+ if (DEBUG) {
+ System.err.println(getThreadName()+": Resizing offscreen from (" + readBackWidthInPixels + ", " + readBackHeightInPixels + ") " +
+ " to fit (" + panelWidth + ", " + panelHeight + ")");
+ }
+ } */
+
+ GLDrawableImpl _drawable = offscreenDrawable;
+ {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, offscreenContext, panelWidth, panelHeight);
+ if(_drawable != _drawableNew) {
+ // write back
+ _drawable = _drawableNew;
+ offscreenDrawable = _drawableNew;
+ }
+ }
+ panelWidth = _drawable.getWidth();
+ panelHeight = _drawable.getHeight();
+ readBackWidthInPixels = panelWidth;
+ readBackHeightInPixels = panelHeight;
+
+ if( null != glslTextureRaster ) {
+ if( GLContext.CONTEXT_NOT_CURRENT < offscreenContext.makeCurrent() ) {
+ try {
+ final GL gl = offscreenContext.getGL();
+ fboFlipped.reset(gl, _drawable.getWidth(), _drawable.getHeight(), 0, false);
+ glslTextureRaster.reshape(gl.getGL2ES2(), 0, 0, _drawable.getWidth(), _drawable.getHeight());
+ } finally {
+ offscreenContext.release();
+ }
+ }
+ }
- @Override
- public void destroy() {
- if(DEBUG) {
- System.err.println(getThreadName()+": SoftwareBackend: destroy() - offscreenContext: "+(null!=offscreenContext)+" - offscreenDrawable: "+(null!=offscreenDrawable));
- }
- if (offscreenContext != null) {
- offscreenContext.destroy();
- offscreenContext = null;
- }
- if (offscreenDrawable != null) {
- final AbstractGraphicsDevice adevice = offscreenDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
- offscreenDrawable.setRealized(false);
- offscreenDrawable = null;
- if(null != adevice) {
- adevice.close();
+ if (offscreenImage != null) {
+ offscreenImage.flush();
+ offscreenImage = null;
}
- }
+ return _drawable.isRealized();
}
-
+
@Override
public GLContext createContext(GLContext shareWith) {
return (null != offscreenDrawable) ? offscreenDrawable.createContext(shareWith) : null;
@@ -1152,201 +1187,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
return offscreenDrawable.getGLProfile();
}
-
- @Override
- public void handleReshape() {
- destroy();
- initialize();
- readBackWidthInPixels = Math.max(1, panelWidth);
- readBackHeightInPixels = Math.max(1, panelHeight);
-
- if (offscreenImage != null) {
- offscreenImage.flush();
- offscreenImage = null;
- }
- }
-
- @Override
- protected void doPaintComponentImpl() {
- helper.invokeGL(offscreenDrawable, offscreenContext, updaterDisplayAction, updaterInitAction);
- }
-
- @Override
- protected int getGLPixelType() {
- return offscreenContext.getOffscreenContextPixelDataType();
- }
-
- @Override
- protected boolean flipVertically() {
- return offscreenContext.offscreenImageNeedsVerticalFlip();
- }
- }
-
- class PbufferBackend extends AbstractReadbackBackend {
- private GLPbuffer pbuffer;
- private int pbufferWidth = 256;
- private int pbufferHeight = 256;
-
- @Override
- public boolean isUsingOwnThreadManagment() { return false; }
-
- @Override
- public void initialize() {
- if (pbuffer != null) {
- throw new InternalError("Creating pbuffer twice without destroying it (memory leak / correctness bug)");
- }
- if(DEBUG) {
- System.err.println(getThreadName()+": PbufferBackend: initialize()");
- }
- try {
- pbuffer = factory.createGLPbuffer(null /* default platform device */,
- offscreenCaps,
- null,
- pbufferWidth,
- pbufferHeight,
- shareWith);
- pbuffer.setContextCreationFlags(additionalCtxCreationFlags);
- pbuffer.addGLEventListener(updater);
- isInitialized = true;
- } catch (GLException e) {
- if (DEBUG) {
- e.printStackTrace();
- System.err.println(getThreadName()+": GLJPanel: Falling back on software rendering because of problems creating pbuffer");
- }
- hardwareAccelerationDisabled = true;
- backend = null;
- isInitialized = false;
- createAndInitializeBackend();
- }
- }
-
- @Override
- public void destroy() {
- if(DEBUG) {
- System.err.println(getThreadName()+": PbufferBackend: destroy() - pbuffer: "+(null!=pbuffer));
- }
- if (pbuffer != null) {
- pbuffer.destroy();
- pbuffer = null;
- }
- }
-
- @Override
- public GLContext createContext(GLContext shareWith) {
- return (null != pbuffer) ? pbuffer.createContext(shareWith) : null;
- }
-
- @Override
- public void setContext(GLContext ctx) {
- if (pbuffer == null || Beans.isDesignTime()) {
- return;
- }
- pbuffer.setContext(ctx);
- }
-
- @Override
- public GLContext getContext() {
- // Workaround for crashes in NetBeans GUI builder
- if (null == pbuffer || Beans.isDesignTime()) {
- return null;
- }
- return pbuffer.getContext();
- }
-
- @Override
- public GLDrawable getDrawable() {
- return pbuffer;
- }
-
- @Override
- public GLCapabilitiesImmutable getChosenGLCapabilities() {
- if (pbuffer == null) {
- return null;
- }
- return pbuffer.getChosenGLCapabilities();
- }
-
- @Override
- public GLProfile getGLProfile() {
- if (pbuffer == null) {
- return null;
- }
- return pbuffer.getGLProfile();
- }
-
- @Override
- public void handleReshape() {
- // Use factor larger than 2 during shrinks for some hysteresis
- float shrinkFactor = 2.5f;
- if ((panelWidth > pbufferWidth) || (panelHeight > pbufferHeight) ||
- (panelWidth < (pbufferWidth / shrinkFactor)) || (panelHeight < (pbufferHeight / shrinkFactor))) {
- if (DEBUG) {
- System.err.println(getThreadName()+": Resizing pbuffer from (" + pbufferWidth + ", " + pbufferHeight + ") " +
- " to fit (" + panelWidth + ", " + panelHeight + ")");
- }
- // Must destroy and recreate pbuffer to fit
- if (pbuffer != null) {
- // Watch for errors during pbuffer destruction (due to
- // buggy / bad OpenGL drivers, in particular SiS) and fall
- // back to software rendering
- try {
- pbuffer.destroy();
- } catch (GLException e) {
- hardwareAccelerationDisabled = true;
- backend = null;
- isInitialized = false;
- // Just disabled hardware acceleration during this resize operation; do a fixup
- readBackWidthInPixels = Math.max(1, panelWidth);
- readBackHeightInPixels = Math.max(1, panelHeight);
- if (DEBUG) {
- System.err.println(getThreadName()+": Warning: falling back to software rendering due to bugs in OpenGL drivers");
- e.printStackTrace();
- }
- createAndInitializeBackend();
- return;
- }
- }
- pbuffer = null;
- isInitialized = false;
- pbufferWidth = getNextPowerOf2(panelWidth);
- pbufferHeight = getNextPowerOf2(panelHeight);
- if (DEBUG && !hardwareAccelerationDisabled) {
- System.err.println(getThreadName()+": New pbuffer size is (" + pbufferWidth + ", " + pbufferHeight + ")");
- }
- initialize();
- }
-
- // It looks like NVidia's drivers (at least the ones on my
- // notebook) are buggy and don't allow a rectangle of less than
- // the pbuffer's width to be read...this doesn't really matter
- // because it's the Graphics.drawImage() calls that are the
- // bottleneck. Should probably make the size of the offscreen
- // image be the exact size of the pbuffer to save some work on
- // resize operations...
- readBackWidthInPixels = pbufferWidth;
- readBackHeightInPixels = panelHeight;
-
- if (offscreenImage != null) {
- offscreenImage.flush();
- offscreenImage = null;
- }
- }
-
- @Override
- protected void doPaintComponentImpl() {
- pbuffer.display();
- }
-
- @Override
- protected int getGLPixelType() {
- // This seems to be a good choice on all platforms
- return GL2.GL_UNSIGNED_INT_8_8_8_8_REV;
- }
-
- @Override
- protected boolean flipVertically() {
- return true;
- }
}
class J2DOGLBackend implements Backend {
@@ -1399,7 +1239,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private GraphicsConfiguration workaroundConfig;
@Override
- public boolean isUsingOwnThreadManagment() { return true; }
+ public boolean isUsingOwnLifecycle() { return true; }
@Override
public void initialize() {
@@ -1472,8 +1312,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
@Override
- public void handleReshape() {
+ public boolean handleReshape() {
// Empty in this implementation
+ return true;
}
@Override
@@ -1618,7 +1459,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Cause OpenGL pipeline to flush its results because
// otherwise it's possible we will buffer up multiple frames'
// rendering results, resulting in apparent mouse lag
- GL gl = getGL();
+ GL gl = joglContext.getGL();
gl.glFinish();
if (Java2D.isFBOEnabled() &&
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index 68fbe3dd5..cbb7cd699 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -228,7 +228,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
// Catch dispose GLExceptions by GLEventListener, just 'print' them
// so we can continue with the destruction.
try {
- helper.disposeGL(this, context);
+ helper.disposeGL(this, context, true);
} catch (GLException gle) {
gle.printStackTrace();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 65b523394..f61b55497 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -448,7 +448,7 @@ public abstract class GLContextImpl extends GLContext {
*/
@Override
public int makeCurrent() throws GLException {
- boolean unlockContextAndDrawable = false;
+ boolean unlockContextAndDrawable = true;
int res = CONTEXT_NOT_CURRENT;
// Note: the surface is locked within [makeCurrent .. swap .. release]
@@ -457,50 +457,51 @@ public abstract class GLContextImpl extends GLContext {
return CONTEXT_NOT_CURRENT;
}
try {
+ if (0 == drawable.getHandle()) {
+ throw new GLException("drawable has invalid handle: "+drawable);
+ }
if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
drawable.updateHandle();
}
- lock.lock();
- try {
- // One context can only be current by one thread,
- // and one thread can only have one context current!
- final GLContext current = getCurrent();
- if (current != null) {
- if (current == this) {
- // Assume we don't need to make this context current again
- // For Mac OS X, however, we need to update the context to track resizes
- drawableUpdatedNotify();
- if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - keep - CONTEXT_CURRENT - "+lock);
+ if ( drawable.isRealized() ) {
+ lock.lock();
+ try {
+ // One context can only be current by one thread,
+ // and one thread can only have one context current!
+ final GLContext current = getCurrent();
+ if (current != null) {
+ if (current == this) {
+ // Assume we don't need to make this context current again
+ // For Mac OS X, however, we need to update the context to track resizes
+ drawableUpdatedNotify();
+ if(TRACE_SWITCH) {
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - keep - CONTEXT_CURRENT - "+lock);
+ }
+ return CONTEXT_CURRENT;
+ } else {
+ current.release();
}
- return CONTEXT_CURRENT;
- } else {
- current.release();
}
+ res = makeCurrentWithinLock(lockRes);
+ unlockContextAndDrawable = CONTEXT_NOT_CURRENT == res;
+
+ /**
+ * FIXME: refactor dependence on Java 2D / JOGL bridge
+ if ( tracker != null && res == CONTEXT_CURRENT_NEW ) {
+ // Increase reference count of GLObjectTracker
+ tracker.ref();
+ }
+ */
+ } catch (RuntimeException e) {
+ unlockContextAndDrawable = true;
+ throw e;
+ } finally {
+ if (unlockContextAndDrawable) {
+ lock.unlock();
+ }
}
- if (0 == drawable.getHandle()) {
- throw new GLException("drawable has invalid handle: "+drawable);
- }
- res = makeCurrentWithinLock(lockRes);
- unlockContextAndDrawable = CONTEXT_NOT_CURRENT == res;
-
- /**
- * FIXME: refactor dependence on Java 2D / JOGL bridge
- if ((tracker != null) &&
- (res == CONTEXT_CURRENT_NEW)) {
- // Increase reference count of GLObjectTracker
- tracker.ref();
- }
- */
- } catch (RuntimeException e) {
- unlockContextAndDrawable = true;
- throw e;
- } finally {
- if (unlockContextAndDrawable) {
- lock.unlock();
- }
- }
+ } /* if ( drawable.isRealized() ) */
} catch (RuntimeException e) {
unlockContextAndDrawable = true;
throw e;
@@ -511,8 +512,8 @@ public abstract class GLContextImpl extends GLContext {
}
if (res == CONTEXT_NOT_CURRENT) {
- if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - CONTEXT_NOT_CURRENT - "+lock);
+ if(DEBUG || TRACE_SWITCH) {
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+", drawable.isRealized() "+drawable.isRealized()+" - switch - CONTEXT_NOT_CURRENT - "+lock);
}
} else {
setCurrent(this);
@@ -693,8 +694,7 @@ public abstract class GLContextImpl extends GLContext {
* @see #createContextARBImpl
* @see #destroyContextARBImpl
*/
- protected abstract long createContextARBImpl(long share, boolean direct, int ctxOptionFlags,
- int major, int minor);
+ protected abstract long createContextARBImpl(long share, boolean direct, int ctxOptionFlags, int major, int minor);
/**
* Destroy the context created by {@link #createContextARBImpl}.
@@ -757,7 +757,7 @@ public abstract class GLContextImpl extends GLContext {
_ctp[0] |= additionalCtxCreationFlags;
_ctx = createContextARBImpl(share, direct, _ctp[0], _major[0], _minor[0]);
if(0!=_ctx) {
- setGLFunctionAvailability(true, _major[0], _minor[0], _ctp[0]);
+ setGLFunctionAvailability(true, _major[0], _minor[0], _ctp[0], false);
}
}
return _ctx;
@@ -940,8 +940,7 @@ public abstract class GLContextImpl extends GLContext {
_context = createContextARBImpl(share, direct, ctxOptionFlags, major[0], minor[0]);
if(0 != _context) {
- ok = true;
- setGLFunctionAvailability(true, major[0], minor[0], ctxOptionFlags);
+ ok = setGLFunctionAvailability(true, major[0], minor[0], ctxOptionFlags, true);
} else {
ok = false;
}
@@ -1166,15 +1165,17 @@ public abstract class GLContextImpl extends GLContext {
* @param major OpenGL major version
* @param minor OpenGL minor version
* @param ctxProfileBits OpenGL context profile and option bits, see {@link javax.media.opengl.GLContext#CTX_OPTION_ANY}
- *
+ * @param strictVersionMatch if <code>true</code> and the ctx version (by string) is lower than the given major.minor version,
+ * method aborts and returns <code>false</code>, otherwise <code>true</code>.
+ * @return returns <code>true</code> if successful, otherwise <code>false</code>. See <code>strictVersionMatch</code>.
* @see #setContextVersion
* @see javax.media.opengl.GLContext#CTX_OPTION_ANY
* @see javax.media.opengl.GLContext#CTX_PROFILE_COMPAT
* @see javax.media.opengl.GLContext#CTX_IMPL_ES2_COMPAT
*/
- protected final void setGLFunctionAvailability(boolean force, int major, int minor, int ctxProfileBits) {
+ protected final boolean setGLFunctionAvailability(boolean force, int major, int minor, int ctxProfileBits, boolean strictVersionMatch) {
if(null!=this.gl && null!=glProcAddressTable && !force) {
- return; // already done and not forced
+ return true; // already done and not forced
}
if(null==this.gl || !verifyInstance(gl.getGLProfile(), "Impl", this.gl)) {
@@ -1206,7 +1207,13 @@ public abstract class GLContextImpl extends GLContext {
{
final VersionNumber setGLVersionNumber = new VersionNumber(major, minor, 0);
final VersionNumber strGLVersionNumber = getGLVersionNumber(ctxProfileBits, glVersion);
- if( null != strGLVersionNumber && ( strGLVersionNumber.compareTo(setGLVersionNumber) <= 0 || 0 == major ) ) {
+ if( null != strGLVersionNumber && ( strGLVersionNumber.compareTo(setGLVersionNumber) < 0 || 0 == major ) ) {
+ if( 0 < major && strictVersionMatch ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch: "+major+"."+minor+", ctp "+toHexString(ctxProfileBits)+", "+glVersion+", "+strGLVersionNumber);
+ }
+ return false;
+ }
glVersionNumber = strGLVersionNumber;
major = glVersionNumber.getMajor();
minor = glVersionNumber.getMinor();
@@ -1299,8 +1306,9 @@ public abstract class GLContextImpl extends GLContext {
setDefaultSwapInterval();
if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: "+contextFQN+" - "+GLContext.getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, null));
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: OK "+contextFQN+" - "+GLContext.getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, null));
}
+ return true;
}
private final void setRendererQuirks(boolean hwAccel) {
@@ -1380,16 +1388,18 @@ public abstract class GLContextImpl extends GLContext {
}
synchronized(mappedContextTypeObjectLock) {
- ProcAddressTable table = mappedGLProcAddress.remove( contextFQN );
+ final ProcAddressTable table = mappedGLProcAddress.remove( contextFQN );
if(DEBUG) {
- System.err.println(getThreadName() + ": RM GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+table.hashCode());
+ final int hc = null != table ? table.hashCode() : 0;
+ System.err.println(getThreadName() + ": RM GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+toHexString(hc));
}
}
synchronized(mappedContextTypeObjectLock) {
- ExtensionAvailabilityCache eCache = mappedExtensionAvailabilityCache.remove( contextFQN );
+ final ExtensionAvailabilityCache eCache = mappedExtensionAvailabilityCache.remove( contextFQN );
if(DEBUG) {
- System.err.println(getThreadName() + ": RM GLContext GL ExtensionAvailabilityCache mapping key("+contextFQN+") -> "+eCache.hashCode());
+ final int hc = null != eCache ? eCache.hashCode() : 0;
+ System.err.println(getThreadName() + ": RM GLContext GL ExtensionAvailabilityCache mapping key("+contextFQN+") -> "+toHexString(hc));
}
}
}
@@ -1513,15 +1523,46 @@ public abstract class GLContextImpl extends GLContext {
throw new GLException("Not supported on non-pbuffer contexts");
}
- /** On some platforms the mismatch between OpenGL's coordinate
- system (origin at bottom left) and the window system's
- coordinate system (origin at top left) necessitates a vertical
- flip of pixels read from offscreen contexts. */
- public abstract boolean offscreenImageNeedsVerticalFlip();
+ @Override
+ public boolean isGLOrientationFlippedVertical() {
+ return true;
+ }
- /** Only called for offscreen contexts; needed by glReadPixels */
- public abstract int getOffscreenContextPixelDataType();
+ @Override
+ public int getDefaultPixelDataType() {
+ if(!pixelDataTypeEvaluated) {
+ synchronized(this) {
+ if(!pixelDataTypeEvaluated) {
+ evalPixelDataType();
+ pixelDataTypeEvaluated = true;
+ }
+ }
+ }
+ return pixelDataType;
+ }
+ private volatile boolean pixelDataTypeEvaluated = false;
+ int /* pixelDataInternalFormat, */ pixelDataFormat, pixelDataType;
+
+ private final void evalPixelDataType() {
+ /* if(isGL2GL3() && 3 == components) {
+ pixelDataInternalFormat=GL.GL_RGB;
+ pixelDataFormat=GL.GL_RGB;
+ pixelDataType = GL.GL_UNSIGNED_BYTE;
+ } else */ if(isGLES2Compatible() || isExtensionAvailable(GLExtensions.OES_read_format)) {
+ final int[] glImplColorReadVals = new int[] { 0, 0 };
+ gl.glGetIntegerv(GL.GL_IMPLEMENTATION_COLOR_READ_FORMAT, glImplColorReadVals, 0);
+ gl.glGetIntegerv(GL.GL_IMPLEMENTATION_COLOR_READ_TYPE, glImplColorReadVals, 1);
+ // pixelDataInternalFormat = (4 == components) ? GL.GL_RGBA : GL.GL_RGB;
+ pixelDataFormat = glImplColorReadVals[0];
+ pixelDataType = glImplColorReadVals[1];
+ } else {
+ // RGBA read is safe for all GL profiles
+ // pixelDataInternalFormat = (4 == components) ? GL.GL_RGBA : GL.GL_RGB;
+ pixelDataFormat=GL.GL_RGBA;
+ pixelDataType = GL.GL_UNSIGNED_BYTE;
+ }
+ }
//----------------------------------------------------------------------
// Helpers for buffer object optimizations
@@ -1599,8 +1640,10 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final int getDefaultDrawFramebuffer() { return drawable.getDefaultDrawFramebuffer(); }
@Override
- public final int getDefaultReadFramebuffer() { return drawable.getDefaultReadFramebuffer(); }
-
+ public final int getDefaultReadFramebuffer() { return drawable.getDefaultReadFramebuffer(); }
+ @Override
+ public final int getDefaultReadBuffer() { return drawable.getDefaultReadBuffer(gl); }
+
//---------------------------------------------------------------------------
// GL_ARB_debug_output, GL_AMD_debug_output helpers
//
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 0f8b6b816..dc5d50cf2 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -398,7 +398,7 @@ public class GLDrawableHelper {
* </p>
* <p>
* Please consider using {@link #disposeAllGLEventListener(GLAutoDrawable, GLContext, boolean)}
- * or {@link #disposeGL(GLAutoDrawable, GLContext)}
+ * or {@link #disposeGL(GLAutoDrawable, GLContext, boolean)}
* for correctness, i.e. encapsulating all calls w/ makeCurrent etc.
* </p>
* @param autoDrawable
@@ -826,12 +826,16 @@ public class GLDrawableHelper {
/**
* Principal helper method which runs
* {@link #disposeAllGLEventListener(GLAutoDrawable, boolean) disposeAllGLEventListener(autoDrawable, false)}
- * with the context made current <b>and</b> destroys the context afterwards while holding the lock.
+ * with the context made current.
+ * <p>
+ * If <code>destroyContext</code> is <code>true</code> the context is destroyed in the end while holding the lock.<br/>
+ * </p>
* @param autoDrawable
* @param context
+ * @param destroyContext destroy context in the end while holding the lock
*/
public final void disposeGL(final GLAutoDrawable autoDrawable,
- final GLContext context) {
+ final GLContext context, boolean destroyContext) {
// Support for recursive makeCurrent() calls as well as calling
// other drawables' display() methods from within another one's
GLContext lastContext = GLContext.getCurrent();
@@ -858,7 +862,11 @@ public class GLDrawableHelper {
}
} finally {
try {
- context.destroy();
+ if(destroyContext) {
+ context.destroy();
+ } else {
+ context.release();
+ }
flushGLRunnables();
} catch (Exception e) {
System.err.println("Catched: "+e.getMessage());
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index df7f742aa..2d062eaf1 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -76,7 +76,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
@Override
public final void swapBuffers() throws GLException {
- if( !realized ) {
+ if( !realized ) { // volatile OK (locked below)
return; // destroyed already
}
int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
@@ -87,17 +87,19 @@ public abstract class GLDrawableImpl implements GLDrawable {
if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
updateHandle();
}
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
- if ( caps.getDoubleBuffered() ) {
- if(!surface.surfaceSwap()) {
- swapBuffersImpl(true);
- }
- } else {
- final GLContext ctx = GLContext.getCurrent();
- if(null!=ctx && ctx.getGLDrawable()==this) {
- ctx.getGL().glFlush();
+ if( realized ) { // volatile OK
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
+ if ( caps.getDoubleBuffered() ) {
+ if(!surface.surfaceSwap()) {
+ swapBuffersImpl(true);
+ }
+ } else {
+ final GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ ctx.getGL().glFlush();
+ }
+ swapBuffersImpl(false);
}
- swapBuffersImpl(false);
}
} finally {
unlockSurface();
@@ -160,12 +162,11 @@ public abstract class GLDrawableImpl implements GLDrawable {
}
@Override
- public final synchronized void setRealized(boolean realizedArg) {
- if ( realized != realizedArg ) {
+ public final void setRealized(boolean realizedArg) {
+ if ( realized != realizedArg ) { // volatile: OK (locked below)
if(DEBUG) {
System.err.println(getThreadName() + ": setRealized: "+getClass().getSimpleName()+" "+realized+" -> "+realizedArg);
}
- realized = realizedArg;
AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice();
if(realizedArg) {
if(surface instanceof ProxySurface) {
@@ -178,12 +179,15 @@ public abstract class GLDrawableImpl implements GLDrawable {
aDevice.lock();
}
try {
- if(realizedArg) {
- setRealizedImpl();
- updateHandle();
- } else {
- destroyHandle();
- setRealizedImpl();
+ if ( realized != realizedArg ) { // volatile: OK
+ realized = realizedArg;
+ if(realizedArg) {
+ setRealizedImpl();
+ updateHandle();
+ } else {
+ destroyHandle();
+ setRealizedImpl();
+ }
}
} finally {
if(realizedArg) {
@@ -199,6 +203,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
System.err.println(getThreadName() + ": setRealized: "+getClass().getName()+" "+this.realized+" == "+realizedArg);
}
}
+
/**
* Platform specific realization of drawable
*/
@@ -244,10 +249,19 @@ public abstract class GLDrawableImpl implements GLDrawable {
/** Callback for special implementations, allowing GLContext to fetch a custom default render framebuffer. Defaults to zero.*/
protected int getDefaultDrawFramebuffer() { return 0; }
/** Callback for special implementations, allowing GLContext to fetch a custom default read framebuffer. Defaults to zero. */
- protected int getDefaultReadFramebuffer() { return 0; }
+ protected int getDefaultReadFramebuffer() { return 0; }
+ /** Callback for special implementations, allowing GLContext to fetch a custom default read buffer of current framebuffer. */
+ protected int getDefaultReadBuffer(GL gl) {
+ if(gl.isGLES() || getChosenGLCapabilities().getDoubleBuffered()) {
+ // Note-1: Neither ES1 nor ES2 supports selecting the read buffer via glReadBuffer
+ // Note-2: ES3 only supports GL_BACK, GL_NONE or GL_COLOR_ATTACHMENT0+i
+ return GL.GL_BACK;
+ }
+ return GL.GL_FRONT ;
+ }
@Override
- public final synchronized boolean isRealized() {
+ public final boolean isRealized() {
return realized;
}
@@ -297,6 +311,6 @@ public abstract class GLDrawableImpl implements GLDrawable {
// result of calling show() on the main thread. To work around this
// we prevent any JAWT or OpenGL operations from being done until
// addNotify() is called on the surface.
- protected boolean realized;
+ protected volatile boolean realized;
}
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index 7a468a41e..b72f79868 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -302,6 +302,9 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
protected final int getDefaultReadFramebuffer() { return initialized ? fbos[fboIFront].getReadFramebuffer() : 0; }
@Override
+ protected final int getDefaultReadBuffer(GL gl) { return initialized ? fbos[fboIFront].getDefaultReadBuffer() : GL.GL_COLOR_ATTACHMENT0 ; }
+
+ @Override
protected final void setRealizedImpl() {
final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
if(realized) {
@@ -435,6 +438,17 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
}
}
+ @Override
+ public final int setNumBuffers(int bufferCount) throws GLException {
+ // FIXME: Implement
+ return bufferCount;
+ }
+
+ @Override
+ public final int getNumBuffers() {
+ return bufferCount;
+ }
+
/** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
@Override
public final DoubleBufferMode getDoubleBufferMode() {
diff --git a/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
index 7701f209f..59a00170d 100644
--- a/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
@@ -95,6 +95,16 @@ public class GLOffscreenAutoDrawableImpl extends GLAutoDrawableDelegate implemen
windowRepaintOp();
}
+ @Override
+ public final int setNumBuffers(int bufferCount) throws GLException {
+ return ((GLFBODrawableImpl)drawable).setNumBuffers(bufferCount);
+ }
+
+ @Override
+ public final int getNumBuffers() {
+ return ((GLFBODrawableImpl)drawable).getNumBuffers();
+ }
+
/** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
@Override
public DoubleBufferMode getDoubleBufferMode() {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 84aeaa94a..bd8e7dee9 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -214,7 +214,7 @@ public abstract class EGLContext extends GLContextImpl {
throw new GLException("Error making context " +
toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError()));
}
- setGLFunctionAvailability(true, glProfile.usesNativeGLES2() ? 2 : 1, 0, CTX_PROFILE_ES);
+ setGLFunctionAvailability(true, glProfile.usesNativeGLES2() ? 2 : 1, 0, CTX_PROFILE_ES, false);
return true;
}
@@ -344,14 +344,4 @@ public abstract class EGLContext extends GLContextImpl {
public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
throw new GLException("Should not call this");
}
-
- @Override
- public boolean offscreenImageNeedsVerticalFlip() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public int getOffscreenContextPixelDataType() {
- throw new GLException("Should not call this");
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
index 84bd705db..da8fb519d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
@@ -45,7 +45,7 @@ public class EGLExternalContext extends EGLContext {
public EGLExternalContext(AbstractGraphicsScreen screen) {
super(null, null);
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_ES);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_ES, false);
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index eb7e320c8..9e5d9327b 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -41,7 +41,6 @@
package jogamp.opengl.egl;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.MutableSurface;
import javax.media.opengl.GLContext;
public class EGLPbufferDrawable extends EGLDrawable {
diff --git a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
index 62ff3aa09..7cd7da53e 100644
--- a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
+++ b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
@@ -120,6 +120,7 @@ import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import com.jogamp.opengl.util.ImmModeSink;
+import com.jogamp.opengl.util.glsl.ShaderState;
/**
* GLUquadricImpl.java
@@ -140,22 +141,26 @@ public class GLUquadricImpl implements GLUquadric {
private boolean immModeSinkImmediate;
public int normalType;
public GL gl;
+ public ShaderState shaderState;
+ public int shaderProgram;
public static final boolean USE_NORM = true;
public static final boolean USE_TEXT = false;
private ImmModeSink immModeSink=null;
- public GLUquadricImpl(GL gl, boolean useGLSL) {
+ public GLUquadricImpl(GL gl, boolean useGLSL, ShaderState st, int shaderProgram) {
this.gl=gl;
this.useGLSL = useGLSL;
- drawStyle = GLU.GLU_FILL;
- orientation = GLU.GLU_OUTSIDE;
- textureFlag = false;
- normals = GLU.GLU_SMOOTH;
- normalType = gl.isGLES1()?GL.GL_BYTE:GL.GL_FLOAT;
- immModeSinkImmediate=true;
- immModeSinkEnabled=!gl.isGL2();
+ this.drawStyle = GLU.GLU_FILL;
+ this.orientation = GLU.GLU_OUTSIDE;
+ this.textureFlag = false;
+ this.normals = GLU.GLU_SMOOTH;
+ this.normalType = gl.isGLES1()?GL.GL_BYTE:GL.GL_FLOAT;
+ this.immModeSinkImmediate=true;
+ this.immModeSinkEnabled=!gl.isGL2();
+ this.shaderState = st;
+ this.shaderProgram = shaderProgram;
replaceImmModeSink();
}
@@ -191,12 +196,21 @@ public class GLUquadricImpl implements GLUquadric {
ImmModeSink res = immModeSink;
if(useGLSL) {
- immModeSink = ImmModeSink.createGLSL (32,
- 3, GL.GL_FLOAT, // vertex
- 0, GL.GL_FLOAT, // color
- USE_NORM?3:0, normalType, // normal
- USE_TEXT?2:0, GL.GL_FLOAT, // texCoords
- GL.GL_STATIC_DRAW);
+ if(null != shaderState) {
+ immModeSink = ImmModeSink.createGLSL (32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW, shaderState);
+ } else {
+ immModeSink = ImmModeSink.createGLSL (32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW, shaderProgram);
+ }
} else {
immModeSink = ImmModeSink.createFixed(32,
3, GL.GL_FLOAT, // vertex
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index cde9841b8..838a0387d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -164,7 +164,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
final GLUniformData pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv
- pmvMatrixUniform.setLocation( gl.glGetUniformLocation( sp.program(), pmvMatrixUniform.getName() ) );
+ pmvMatrixUniform.setLocation(gl, sp.program());
gl.glUniform(pmvMatrixUniform);
sp.useProgram(gl, false);
@@ -420,20 +420,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
return super.isExtensionAvailable(glExtensionName);
}
- @Override
- public int getOffscreenContextPixelDataType() {
- throw new GLException("Should not call this");
- }
-
- public int getOffscreenContextReadBuffer() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public boolean offscreenImageNeedsVerticalFlip() {
- throw new GLException("Should not call this");
- }
-
// Support for "mode switching" as described in MacOSXCGLDrawable
public void setOpenGLMode(GLBackendType mode) {
if (mode == openGLMode) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index 65ed5fc15..f121a2547 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -64,7 +64,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL );
this.contextHandle = handle;
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT, false);
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java
index 7b13ce22e..f2e636796 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java
@@ -49,18 +49,8 @@ public class MacOSXOffscreenCGLContext extends MacOSXPbufferCGLContext
}
@Override
- public int getOffscreenContextPixelDataType() {
- GL gl = getGL();
+ public int getDefaultPixelDataType() {
+ final GL gl = getGL();
return gl.isGL2GL3()?GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1;
}
-
- @Override
- public int getOffscreenContextReadBuffer() {
- return GL.GL_FRONT;
- }
-
- @Override
- public boolean offscreenImageNeedsVerticalFlip() {
- return true;
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index 668e463a2..ddff43031 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -131,7 +131,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateOSXSharedResource(config.getScreen().getDevice());
if (DEBUG) {
- System.out.println("Pbuffer config: " + config);
+ System.out.println(getThreadName()+": Pbuffer config: " + config);
if(null != sr) {
System.out.println("Pbuffer NPOT Texure avail: "+sr.isNPOTTextureAvailable());
System.out.println("Pbuffer RECT Texture avail: "+sr.isRECTTextureAvailable());
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
index f41400d83..bd183b900 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
@@ -97,7 +97,7 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL
}
return false;
}
- setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT, false); // use GL_VERSION
contextHandle = ctx;
return true;
}
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
index a6314a216..1a4ca345b 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
@@ -31,9 +31,9 @@ package jogamp.opengl.util;
import javax.media.opengl.*;
/**
- * Handles consistency of buffer data and array state.
- * Implementations shall consider buffer types (VBO, ..), interleaved, etc.
- * They also need to consider array state types, i.e. fixed function or GLSL.
+ * Handles consistency of buffer data and array state.<br/>
+ * Implementations shall consider buffer types (VBO, ..), interleaved, etc.<br/>
+ * They also need to consider array state types, i.e. fixed function or GLSL.<br/>
*/
public interface GLArrayHandler {
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
index 79bed90c9..3c468f358 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
@@ -44,8 +44,8 @@ import com.jogamp.opengl.util.glsl.ShaderState;
* Used for 1:1 GLSL arrays, i.e. where the buffer data
* represents this array only.
*/
-public class GLSLArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
-
+public class GLSLArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
+
public GLSLArrayHandler(GLArrayDataEditable ad) {
super(ad);
}
@@ -60,8 +60,14 @@ public class GLSLArrayHandler extends GLVBOArrayHandler implements GLArrayHandle
public final void enableState(GL gl, boolean enable, Object ext) {
final GL2ES2 glsl = gl.getGL2ES2();
- final ShaderState st = (ShaderState) ext;
-
+ if( null != ext ) {
+ enableShaderState(glsl, enable, (ShaderState)ext);
+ } else {
+ enableSimple(glsl, enable);
+ }
+ }
+
+ private final void enableShaderState(GL2ES2 glsl, boolean enable, ShaderState st) {
if(enable) {
/*
* This would be the non optimized code path:
@@ -108,5 +114,57 @@ public class GLSLArrayHandler extends GLVBOArrayHandler implements GLArrayHandle
st.disableVertexAttribArray(glsl, ad);
}
}
+
+ private final void enableSimple(GL2ES2 glsl, boolean enable) {
+ final int location = ad.getLocation();
+ if( 0 > location ) {
+ return;
+ }
+ if(enable) {
+ /*
+ * This would be the non optimized code path:
+ *
+ if(ad.isVBO()) {
+ glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+ if(!ad.isVBOWritten()) {
+ if(null!=buffer) {
+ glsl.glBufferData(ad.getVBOTarget(), ad.getSizeInBytes(), buffer, ad.getVBOUsage());
+ }
+ ad.setVBOWritten(true);
+ }
+ }
+ st.vertexAttribPointer(glsl, ad);
+ */
+ final Buffer buffer = ad.getBuffer();
+ if(ad.isVBO()) {
+ // bind and refresh the VBO / vertex-attr only if necessary
+ if(!ad.isVBOWritten()) {
+ glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+ if(null!=buffer) {
+ glsl.glBufferData(ad.getVBOTarget(), ad.getSizeInBytes(), buffer, ad.getVBOUsage());
+ }
+ ad.setVBOWritten(true);
+ glsl.glVertexAttribPointer(ad);
+ glsl.glBindBuffer(ad.getVBOTarget(), 0);
+ } else {
+ // didn't experience a performance hit on this query ..
+ // (using ShaderState's location query above to validate the location)
+ final int[] qi = new int[1];
+ glsl.glGetVertexAttribiv(location, GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
+ if(ad.getVBOName() != qi[0]) {
+ glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+ glsl.glVertexAttribPointer(ad);
+ glsl.glBindBuffer(ad.getVBOTarget(), 0);
+ }
+ }
+ } else if(null!=buffer) {
+ glsl.glVertexAttribPointer(ad);
+ }
+
+ glsl.glEnableVertexAttribArray(location);
+ } else {
+ glsl.glDisableVertexAttribArray(location);
+ }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
index c5beb7dd0..855406db3 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
@@ -53,9 +53,13 @@ public class GLSLArrayHandlerFlat implements GLArrayHandlerFlat {
public final void syncData(GL gl, Object ext) {
final GL2ES2 glsl = gl.getGL2ES2();
- final ShaderState st = (ShaderState) ext;
-
- st.vertexAttribPointer(glsl, ad);
+ if( null != ext ) {
+ ((ShaderState)ext).vertexAttribPointer(glsl, ad);
+ } else {
+ if( 0 <= ad.getLocation() ) {
+ glsl.glVertexAttribPointer(ad);
+ }
+ }
/**
* Due to probable application VBO switching, this might not make any sense ..
*
@@ -75,13 +79,22 @@ public class GLSLArrayHandlerFlat implements GLArrayHandlerFlat {
public final void enableState(GL gl, boolean enable, Object ext) {
final GL2ES2 glsl = gl.getGL2ES2();
- final ShaderState st = (ShaderState) ext;
-
- if(enable) {
- st.enableVertexAttribArray(glsl, ad);
+ if( null != ext ) {
+ final ShaderState st = (ShaderState)ext;
+ if(enable) {
+ st.enableVertexAttribArray(glsl, ad);
+ } else {
+ st.disableVertexAttribArray(glsl, ad);
+ }
} else {
- st.disableVertexAttribArray(glsl, ad);
+ final int location = ad.getLocation();
+ if( 0 <= location ) {
+ if(enable) {
+ glsl.glEnableVertexAttribArray(location);
+ } else {
+ glsl.glDisableVertexAttribArray(location);
+ }
+ }
}
}
}
-
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java
new file mode 100644
index 000000000..20c251635
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java
@@ -0,0 +1,195 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.opengl.util.glsl;
+
+import java.nio.FloatBuffer;
+
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+public class GLSLTextureRaster {
+ private final boolean textureVertFlipped;
+ private final int textureUnit;
+
+ private ShaderProgram sp;
+ private PMVMatrix pmvMatrix;
+ private GLUniformData pmvMatrixUniform;
+ private GLUniformData activeTexUniform;
+ private GLArrayDataServer interleavedVBO;
+
+ public GLSLTextureRaster(int textureUnit, boolean textureVertFlipped) {
+ this.textureVertFlipped = textureVertFlipped;
+ this.textureUnit = textureUnit;
+ }
+
+ public int getTextureUnit() { return textureUnit; }
+
+ static final String shaderBasename = "texture01_xxx";
+ static final String shaderSrcPath = "../../shader";
+ static final String shaderBinPath = "../../shader/bin";
+
+ public void init(GL2ES2 gl) {
+ // Create & Compile the shader objects
+ final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(),
+ shaderSrcPath, shaderBinPath, shaderBasename, true);
+ final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(),
+ shaderSrcPath, shaderBinPath, shaderBasename, true);
+ rsVp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ rsFp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
+
+ // Create & Link the shader program
+ sp = new ShaderProgram();
+ sp.add(rsVp);
+ sp.add(rsFp);
+ if(!sp.link(gl, System.err)) {
+ throw new GLException("Couldn't link program: "+sp);
+ }
+ sp.useProgram(gl, true);
+
+ // setup mgl_PMVMatrix
+ pmvMatrix = new PMVMatrix();
+ pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv
+ if( pmvMatrixUniform.setLocation(gl, sp.program()) < 0 ) {
+ throw new GLException("Couldn't locate "+pmvMatrixUniform+" in shader: "+sp);
+ }
+ gl.glUniform(pmvMatrixUniform);
+
+ activeTexUniform = new GLUniformData("mgl_Texture0", textureUnit);
+ if( activeTexUniform.setLocation(gl, sp.program()) < 0 ) {
+ throw new GLException("Couldn't locate "+activeTexUniform+" in shader: "+sp);
+ }
+ gl.glUniform(activeTexUniform);
+
+ final float[] s_quadTexCoords;
+ if( textureVertFlipped ) {
+ s_quadTexCoords = s_quadTexCoords01;
+ } else {
+ s_quadTexCoords = s_quadTexCoords00;
+ }
+
+ interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+2, GL.GL_FLOAT, false, 2*4, GL.GL_STATIC_DRAW);
+ {
+ final GLArrayData vArrayData = interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER);
+ if( vArrayData.setLocation(gl, sp.program()) < 0 ) {
+ throw new GLException("Couldn't locate "+vArrayData+" in shader: "+sp);
+ }
+ final GLArrayData tArrayData = interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
+ if( tArrayData.setLocation(gl, sp.program()) < 0 ) {
+ throw new GLException("Couldn't locate "+tArrayData+" in shader: "+sp);
+ }
+ final FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
+ for(int i=0; i<4; i++) {
+ ib.put(s_quadVertices, i*3, 3);
+ ib.put(s_quadTexCoords, i*2, 2);
+ }
+ }
+ interleavedVBO.seal(gl, true);
+ interleavedVBO.enableBuffer(gl, false);
+
+ sp.useProgram(gl, false);
+ }
+
+ public void reshape(GL2ES2 gl, int x, int y, int width, int height) {
+ if(null != sp) {
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+
+ sp.useProgram(gl, true);
+ gl.glUniform(pmvMatrixUniform);
+ sp.useProgram(gl, false);
+ }
+ }
+
+ public void dispose(GL2ES2 gl) {
+ if(null != pmvMatrixUniform) {
+ pmvMatrixUniform = null;
+ }
+ if(null != pmvMatrix) {
+ pmvMatrix.destroy();
+ pmvMatrix=null;
+ }
+ if(null != interleavedVBO) {
+ interleavedVBO.destroy(gl);
+ interleavedVBO=null;
+ }
+ if(null != sp) {
+ sp.destroy(gl);
+ sp=null;
+ }
+ }
+
+ public void display(GL2ES2 gl) {
+ if(null != sp) {
+ sp.useProgram(gl, true);
+ interleavedVBO.enableBuffer(gl, true);
+
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+
+ interleavedVBO.enableBuffer(gl, false);
+ sp.useProgram(gl, false);
+ }
+ }
+
+ private static final float[] s_quadVertices = {
+ -1f, -1f, 0f, // LB
+ 1f, -1f, 0f, // RB
+ -1f, 1f, 0f, // LT
+ 1f, 1f, 0f // RT
+ };
+ private static final float[] s_quadTexCoords00 = {
+ 0f, 0f, // LB
+ 1f, 0f, // RB
+ 0f, 1f, // LT
+ 1f, 1f // RT
+ };
+ private static final float[] s_quadTexCoords01 = {
+ 0f, 1f, // LB
+ 1f, 1f, // RB
+ 0f, 0f, // LT
+ 1f, 0f // RT
+ };
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java
index 51341a098..c8aac7f7b 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java
@@ -49,18 +49,12 @@ public class WindowsBitmapWGLContext extends WindowsWGLContext {
}
@Override
- public int getOffscreenContextPixelDataType() {
+ public int getDefaultPixelDataType() {
return GL.GL_UNSIGNED_BYTE;
}
@Override
- public int getOffscreenContextReadBuffer() {
- // On Windows these contexts are always single-buffered
- return GL.GL_FRONT;
- }
-
- @Override
- public boolean offscreenImageNeedsVerticalFlip() {
+ public boolean isGLOrientationFlippedVertical() {
// We can take care of this in the DIB creation (see below)
return false;
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
index cf6f43b1c..6993191f6 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -79,7 +79,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
int werr;
NativeSurface ns = getNativeSurface();
if(DEBUG) {
- System.err.println("WindowsBitmapWGLDrawable (1): "+ns);
+ System.err.println(getThreadName()+": WindowsBitmapWGLDrawable (1): "+ns);
}
WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getRequestedCapabilities();
@@ -141,7 +141,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
}
((MutableSurface)ns).setSurfaceHandle(hdc);
if(DEBUG) {
- System.err.println("WindowsBitmapWGLDrawable (2): "+ns);
+ System.err.println(getThreadName()+": WindowsBitmapWGLDrawable (2): "+ns);
}
if ((origbitmap = GDI.SelectObject(hdc, hbitmap)) == 0) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
index f6cc2956d..84b29a09f 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -65,7 +65,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
System.err.println(getThreadName() + ": Created external OpenGL context " + toHexString(ctx) + " for " + this);
}
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT, false); // use GL_VERSION
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index 7a512c85f..6c7893c3e 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -131,7 +131,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt();
if (DEBUG) {
- System.out.println("Pbuffer config: " + config);
+ System.out.println(getThreadName()+": Pbuffer config: " + config);
}
final int winattrPbuffer = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(false /* onscreen */, false /* fbo */, true /* pbuffer */, false /* bitmap */);
@@ -146,8 +146,8 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
final AbstractGraphicsDevice device = config.getScreen().getDevice();
if (DEBUG) {
- System.out.println("Pbuffer parentHdc = " + toHexString(sharedHdc));
- System.out.println("Pbuffer chosenCaps: " + chosenCaps);
+ System.out.println(getThreadName()+": Pbuffer parentHdc = " + toHexString(sharedHdc));
+ System.out.println(getThreadName()+": Pbuffer chosenCaps: " + chosenCaps);
}
if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(chosenCaps,
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index 57f16522c..a654cdd04 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -308,7 +308,7 @@ public class WindowsWGLContext extends GLContextImpl {
if (!WGL.wglMakeCurrent(drawable.getHandle(), temp_ctx)) {
throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: "+GDI.GetLastError());
}
- setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT, false); // use GL_VERSION
WGL.wglMakeCurrent(0, 0); // release temp context
if( !createContextARBTried) {
@@ -538,20 +538,6 @@ public class WindowsWGLContext extends GLContextImpl {
}
@Override
- public int getOffscreenContextPixelDataType() {
- throw new GLException("Should not call this");
- }
-
- public int getOffscreenContextReadBuffer() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public boolean offscreenImageNeedsVerticalFlip() {
- throw new GLException("Should not call this");
- }
-
- @Override
public void bindPbufferToTexture() {
throw new GLException("Should not call this");
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
index 3b3f0c123..8b8cb2052 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -67,7 +67,7 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
config.updateGraphicsConfiguration(getFactory(), ns, null);
if (DEBUG) {
- System.err.println("WindowsWGLDrawable.setRealized(true): "+config);
+ System.err.println(getThreadName()+": WindowsWGLDrawable.setRealized(true): "+config);
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index bebb4e68a..12fa5786a 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -64,7 +64,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
super(drawable, null);
this.contextHandle = ctx;
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT, false);
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 76e0bc15c..5b0d32353 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -308,7 +308,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
throw new GLException(getThreadName()+": Error making temp context(0) current: display "+toHexString(display)+", context "+toHexString(contextHandle)+", drawable "+drawable);
}
- setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT, false); // use GL_VERSION
isDirect = GLX.glXIsDirect(display, contextHandle);
if (DEBUG) {
System.err.println(getThreadName() + ": createContextImpl: OK (old-1) share "+share+", direct "+isDirect+"/"+direct);
@@ -338,7 +338,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), temp_ctx)) {
throw new GLException(getThreadName()+": Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(temp_ctx)+", drawable "+drawable);
}
- setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT, false); // use GL_VERSION
glXMakeContextCurrent(display, 0, 0, 0); // release temp context
if( !createContextARBTried ) {
// is*Available calls are valid since setGLFunctionAvailability(..) was called
@@ -619,20 +619,6 @@ public abstract class X11GLXContext extends GLContextImpl {
}
@Override
- public int getOffscreenContextPixelDataType() {
- throw new GLException("Should not call this");
- }
-
- public int getOffscreenContextReadBuffer() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public boolean offscreenImageNeedsVerticalFlip() {
- throw new GLException("Should not call this");
- }
-
- @Override
public void bindPbufferToTexture() {
throw new GLException("Should not call this");
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
index 8c642777d..155c00c4c 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
@@ -63,7 +63,7 @@ public abstract class X11GLXDrawable extends GLDrawableImpl {
config.updateGraphicsConfiguration();
if (DEBUG) {
- System.err.println("X11GLXDrawable.setRealized(true): "+config);
+ System.err.println(getThreadName()+": X11GLXDrawable.setRealized(true): "+config);
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index 28db2ade9..d2d0c6789 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -54,6 +54,7 @@ import javax.media.opengl.GLPbuffer;
import com.jogamp.common.nio.Buffers;
+@SuppressWarnings("deprecation")
public class X11PbufferGLXDrawable extends X11GLXDrawable {
protected X11PbufferGLXDrawable(GLDrawableFactory factory, NativeSurface target) {
/* GLCapabilities caps,
@@ -82,6 +83,9 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
GLX.glXDestroyPbuffer(ns.getDisplayHandle(), ns.getSurfaceHandle());
}
((MutableSurface)ns).setSurfaceHandle(0);
+ if (DEBUG) {
+ System.err.println(getThreadName()+": Destroyed pbuffer " + this);
+ }
}
private void createPbuffer() {
@@ -92,7 +96,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
final long display = aDevice.getHandle();
if (DEBUG) {
- System.out.println("Pbuffer config: " + config);
+ System.out.println(getThreadName()+": Pbuffer config: " + config);
}
if (display==0) {
@@ -131,7 +135,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
ms.setSurfaceHandle(pbuffer);
if (DEBUG) {
- System.err.println("Created pbuffer " + this);
+ System.err.println(getThreadName()+": Created pbuffer " + this);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java
index 96d0f18dc..1cfb7e427 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java
@@ -50,24 +50,9 @@ public class X11PixmapGLXContext extends X11GLXContext {
}
@Override
- public int getOffscreenContextPixelDataType() {
+ public int getDefaultPixelDataType() {
GL gl = getGL();
return gl.isGL2GL3()?GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1;
}
- @Override
- public int getOffscreenContextReadBuffer() {
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
- if (caps.getDoubleBuffered()) {
- return GL.GL_BACK;
- }
- return GL.GL_FRONT;
- }
-
- @Override
- public boolean offscreenImageNeedsVerticalFlip() {
- // There doesn't seem to be a way to do this in the construction
- // of the Pixmap or GLXPixmap
- return true;
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
index 04627724c..ab25e4ef4 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
@@ -95,7 +95,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
}
((MutableSurface)ns).setSurfaceHandle(drawable);
if (DEBUG) {
- System.err.println("Created pixmap " + toHexString(pixmap) +
+ System.err.println(getThreadName()+": Created pixmap " + toHexString(pixmap) +
", GLXPixmap " + toHexString(drawable) +
", display " + toHexString(dpy));
}
@@ -109,7 +109,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
long drawable = ns.getSurfaceHandle();
if (DEBUG) {
- System.err.println("Destroying pixmap " + toHexString(pixmap) +
+ System.err.println(getThreadName()+": Destroying pixmap " + toHexString(pixmap) +
", GLXPixmap " + toHexString(drawable) +
", display " + toHexString(display));
}