diff options
Diffstat (limited to 'src')
59 files changed, 3272 insertions, 1114 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index 7a8e41cce..c597e5d88 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -40,15 +40,17 @@ package com.jogamp.opengl.impl; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.gluegen.runtime.FunctionAddressResolver; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLExtensionNames; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; + import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; @@ -556,15 +558,9 @@ public abstract class GLContextImpl extends GLContext { ctp |= CTX_PROFILE_COMPAT ; } - // FIXME GL3GL4: - // To avoid OpenGL implementation bugs and raise compatibility - // within JOGL, we map to the proper GL version. - // This may change later when GL3 and GL4 drivers become more mature! - // Bug: To ensure GL profile compatibility within the JOGL application - // Bug: we always try to map against the highest GL version, - // Bug: so the use can always cast to a higher one - // Bug: int majorMax=GLContext.getMaxMajor(); - // Bug: int minorMax=GLContext.getMaxMinor(majorMax); + // To ensure GL profile compatibility within the JOGL application + // we always try to map against the highest GL version, + // so the user can always cast to the highest available one. int majorMax, minorMax; int majorMin, minorMin; int major[] = new int[1]; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java index 01e0b8298..32a4f5e70 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java @@ -165,7 +165,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // fix caps .. GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); caps2.setPBuffer(true); capsChosen = caps2; } else { @@ -175,7 +174,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLDrawableImpl drawable = null; device.lock(); try { - drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, height, height) ); + drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) ); } finally { device.unlock(); } @@ -207,20 +206,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } - GLCapabilitiesImmutable capsChosen; + GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) { - // fix caps .. - GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); - caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); - if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) { - caps2.setPBuffer(false); - } - capsChosen = caps2; - } else { - capsChosen = capsRequested; - } device.lock(); try { return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) ); @@ -233,25 +220,12 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { - GLCapabilitiesImmutable capsChosen; - AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } + GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) { - // fix caps .. - GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); - caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); - if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) { - caps2.setPBuffer(false); - } - capsChosen = caps2; - } else { - capsChosen = capsRequested; - } device.lock(); try { return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java index 4dae603c7..62770daf8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java @@ -28,16 +28,27 @@ package com.jogamp.opengl.impl; +import java.util.List; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.NativeWindowException; import javax.media.opengl.DefaultGLCapabilitiesChooser; -public abstract class GLGraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { +public abstract class GLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + + protected static int chooseCapabilities(CapabilitiesChooser chooser, CapabilitiesImmutable capsRequested, + List /*<CapabilitiesImmutable>*/ availableCaps, int recommendedIndex) { + if (null == capsRequested) { + throw new NativeWindowException("Null requested capabilities"); + } + if ( 0 == availableCaps.size() ) { + if (DEBUG) { + System.err.println("Empty available capabilities"); + } + return -1; // none available + } - protected static int chooseCapabilities(CapabilitiesChooser chooser, - CapabilitiesImmutable capsRequested, CapabilitiesImmutable[] availableCaps, int recommendedIndex) { if(null == chooser && 0 <= recommendedIndex) { if (DEBUG) { System.err.println("chooseCapabilities: Using recommendedIndex: idx " + recommendedIndex); @@ -66,10 +77,10 @@ public abstract class GLGraphicsConfigurationFactoryImpl extends GraphicsConfigu // keep on going .. // seek first available one .. - for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) { + for (chosenIndex = 0; chosenIndex < availableCaps.size() && availableCaps.get(chosenIndex) == null; chosenIndex++) { // nop } - if (chosenIndex == availableCaps.length) { + if (chosenIndex == availableCaps.size()) { // give up .. if (DEBUG) { System.err.println("chooseCapabilities: Failed .. nothing available, bail out"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java new file mode 100644 index 000000000..53d42259a --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java @@ -0,0 +1,133 @@ +/** + * 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.impl; + +import java.util.ArrayList; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; + +public class GLGraphicsConfigurationUtil { + public static final int WINDOW_BIT = 1 << 0; + public static final int BITMAP_BIT = 1 << 1; + public static final int PBUFFER_BIT = 1 << 2; + public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT ; + + public static final StringBuffer winAttributeBits2String(StringBuffer sb, int winattrbits) { + if(null==sb) { + sb = new StringBuffer(); + } + boolean seperator = false; + if( 0 != ( WINDOW_BIT & winattrbits ) ) { + sb.append("WINDOW"); + seperator=true; + } + if( 0 != ( BITMAP_BIT & winattrbits ) ) { + if(seperator) { + sb.append(", "); + } + sb.append("BITMAP"); + seperator=true; + } + if( 0 != ( PBUFFER_BIT & winattrbits ) ) { + if(seperator) { + sb.append(", "); + } + sb.append("PBUFFER"); + } + return sb; + } + + /** + * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set + */ + public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer) { + int winattrbits = 0; + if(isOnscreen) { + winattrbits |= WINDOW_BIT; + } else if (!isPBuffer) { + winattrbits |= BITMAP_BIT; + } else { + winattrbits |= PBUFFER_BIT; + } + return winattrbits; + } + + /** + * @see #getWinAttributeBits(boolean, boolean) + */ + public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) { + return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer()); + } + + public static final boolean addGLCapabilitiesPermutations(ArrayList capsBucket, GLCapabilitiesImmutable temp, int winattrbits) { + int preSize = capsBucket.size(); + if( 0 != ( WINDOW_BIT & winattrbits ) ) { + GLCapabilities cpy = (GLCapabilities) temp.cloneMutable(); + cpy.setOnscreen(true); + capsBucket.add(cpy); + } + if( 0 != ( PBUFFER_BIT & winattrbits ) ) { + GLCapabilities cpy = (GLCapabilities) temp.cloneMutable(); + cpy.setPBuffer(true); + capsBucket.add(cpy); + } + if( 0 != ( BITMAP_BIT & winattrbits ) ) { + GLCapabilities cpy = (GLCapabilities) temp.cloneMutable(); + cpy.setOnscreen(false); + cpy.setPBuffer(false); + capsBucket.add(cpy); + } + return capsBucket.size() > preSize; + } + + public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable) + { + if( !capsRequested.isOnscreen() ) { + return fixOffScreenGLCapabilities(capsRequested, pbufferAvailable); + } + return capsRequested; + } + public static GLCapabilitiesImmutable fixOffScreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable) + { + if( capsRequested.getDoubleBuffered() || + capsRequested.isOnscreen() || + ( !pbufferAvailable && capsRequested.isPBuffer() ) ) + { + // fix caps .. + GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); + caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN + caps2.setOnscreen(false); + if(caps2.isPBuffer() && !pbufferAvailable) { + caps2.setPBuffer(false); + } + return caps2; + } + return capsRequested; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java index f451cb9bc..c32f2f22c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java @@ -37,13 +37,16 @@ package com.jogamp.opengl.impl.egl; import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.EGLGraphicsDevice; import javax.media.opengl.*; + import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.ProxySurface; + import java.util.HashMap; -import javax.media.nativewindow.egl.EGLGraphicsDevice; +import java.util.List; public class EGLDrawableFactory extends GLDrawableFactoryImpl { @@ -166,6 +169,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return null; } + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) getOrCreateShared(device); + } + public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) { if (2==esProfile) { if(null==eglES2DynamicLookupHelper) { @@ -184,6 +191,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { protected final void shutdownInstance() {} + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java new file mode 100644 index 000000000..db6d485e3 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java @@ -0,0 +1,96 @@ +/** + * 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.impl.egl; + +import java.util.Comparator; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +public class EGLGLCapabilities extends GLCapabilities { + long eglcfg; + int eglcfgid; + + /** Comparing EGLConfig ID only */ + public static class EglCfgIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof EGLGLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a EGLGLCapabilities object: " + c); + } + if ( ! ( o2 instanceof EGLGLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a EGLGLCapabilities object: " + c); + } + + final EGLGLCapabilities caps1 = (EGLGLCapabilities) o1; + final long id1 = caps1.getEGLConfigID(); + + final EGLGLCapabilities caps2 = (EGLGLCapabilities) o2; + final long id2 = caps2.getEGLConfigID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public EGLGLCapabilities(long eglcfg, int eglcfgid, GLProfile glp) { + super(glp); + this.eglcfg = eglcfg; + this.eglcfgid = eglcfgid; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public long getEGLConfig() { return eglcfg; } + final public int getEGLConfigID() { return eglcfgid; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append("0x").append(Long.toHexString(eglcfgid)).append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java index b655fc511..eca324046 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java @@ -36,31 +36,29 @@ package com.jogamp.opengl.impl.egl; -import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.common.util.ReflectionUtil; +import java.util.ArrayList; import javax.media.nativewindow.*; import javax.media.nativewindow.egl.*; import javax.media.opengl.*; +import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.opengl.impl.*; public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); - public long getNativeConfig() { - return config; + public final long getNativeConfig() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfig(); } - public int getNativeConfigID() { - return configID; + public final int getNativeConfigID() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfigID(); } EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, - long cfg, int cfgID) { + EGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { super(absScreen, capsChosen, capsRequested); this.chooser = chooser; - config = cfg; - configID = cfgID; } public static EGLGraphicsConfiguration create(GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int cfgID) { @@ -74,8 +72,8 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } GLProfile glp = capsRequested.getGLProfile(); long cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID); - GLCapabilitiesImmutable caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer()); - return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser(), cfg, cfgID); + EGLGLCapabilities caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer()); + return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser()); } public Object clone() { @@ -89,8 +87,6 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple if(null!=newConfig) { // FIXME: setScreen( ... ); setChosenCapabilities(newConfig.getChosenCapabilities()); - config = newConfig.getNativeConfig(); - configID = newConfig.getNativeConfigID(); if(DEBUG) { System.err.println("!!! updateGraphicsConfiguration: "+this); } @@ -116,27 +112,61 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple return configs.get(0); } - static boolean EGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static int EGLConfigDrawableTypeBits(final long display, final long config) { + int val = 0; - if ( onscreen ) { - res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ; - } + int[] stype = new int[1]; + if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) { + throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); } - return res; + if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } + + return val; } - public static GLCapabilitiesImmutable EGLConfig2Capabilities(GLProfile glp, long display, long config, + public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config, boolean relaxed, boolean onscreen, boolean usePBuffer) { - GLCapabilities caps = new GLCapabilities(glp); + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask) ) { + return (EGLGLCapabilities) bucket.get(0); + } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS) ) { + return (EGLGLCapabilities) bucket.get(0); + } + return null; + } + + public static boolean EGLConfig2Capabilities(ArrayList capsBucket, + GLProfile glp, long display, long config, + int winattrmask) { + final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + int[] val = new int[1]; + // get the configID + if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val, 0)) { + if(DEBUG) { + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError())); + } + return false; + } + GLCapabilities caps = new EGLGLCapabilities(config, val[0], glp); + // Read the actual configuration into the choosen caps if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val, 0)) { caps.setRedBits(val[0]); @@ -178,26 +208,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple caps.setTransparentAlphaValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]); } */ } - if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, val, 0)) { - if(EGLConfigDrawableTypeVerify(val[0], onscreen, usePBuffer)) { - caps.setDoubleBuffered(onscreen); - caps.setOnscreen(onscreen); - caps.setPBuffer(usePBuffer); - } else if(relaxed) { - caps.setDoubleBuffered( 0 != (val[0] & EGL.EGL_WINDOW_BIT) ); - caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) ); - caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) ); - } else { - if(DEBUG) { - System.err.println("EGL_SURFACE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val[0] & EGL.EGL_WINDOW_BIT) )+", pbuffer "+( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) )+", pixmap "+( 0 != (val[0] & EGL.EGL_PIXMAP_BIT) )+")"); - } - return null; - } - } else { - throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); - } - - return caps; + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits ); } public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) { @@ -289,7 +300,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } public String toString() { - return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", eglConfigID 0x"+Integer.toHexString(configID)+ + return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", eglConfigID "+toHexString(getNativeConfigID())+ ",\n\trequested " + getRequestedCapabilities()+ ",\n\tchosen " + getChosenCapabilities()+ "]"; @@ -297,7 +308,5 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } private GLCapabilitiesChooser chooser; - private long config; - private int configID; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java index ff6e025a8..3e3d4f964 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java @@ -33,7 +33,6 @@ package com.jogamp.opengl.impl.egl; -import java.io.PrintStream; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; @@ -41,18 +40,22 @@ import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.egl.EGLGraphicsDevice; -import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; +import javax.media.opengl.GLDrawableFactory; import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.io.PrintStream; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits @@ -60,8 +63,9 @@ import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL"); + static EGLGLCapabilities.EglCfgIDComparator EglCfgIDComparator = new EGLGLCapabilities.EglCfgIDComparator(); EGLGraphicsConfigurationFactory() { // become the selector for KD/EGL .. @@ -94,6 +98,41 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact absScreen); } + protected static List/*<EGLGLCapabilities>*/ getAvailableCapabilities(EGLDrawableFactory factory, AbstractGraphicsDevice device) { + EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + EGLGraphicsDevice eglDevice = sharedResource.getDevice(); + long eglDisplay = eglDevice.getHandle(); + + List/*<EGLGLCapabilities>*/ availableCaps = null; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); + int[] numConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if (numConfigs[0] > 0) { + GLProfile glp = GLProfile.getDefault(device); + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], GLGraphicsConfigurationUtil.ALL_BITS); + if( null != availableCaps ) { + Collections.sort(availableCaps, EglCfgIDComparator); + } + } + + return availableCaps; + } + private static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, @@ -101,7 +140,6 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact if (capsChosen == null) { capsChosen = new GLCapabilities(null); } - GLProfile glp = capsChosen.getGLProfile(); if(null==absScreen) { throw new GLException("Null AbstractGraphicsScreen"); @@ -117,12 +155,10 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact throw new GLException("Invalid EGL display: "+absDevice); } - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } + EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory(); + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) ); + + GLProfile glp = capsChosen.getGLProfile(); EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, capsChosen, capsReq, chooser, absScreen); if(null!=res) { @@ -132,43 +168,6 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact System.err.println("eglChooseConfig failed with given capabilities "+capsChosen); } - if (chooser == null) { - chooser = new DefaultGLCapabilitiesChooser(); - } - - PointerBuffer configs = PointerBuffer.allocateDirect(10); - int[] numConfigs = new int[1]; - - if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { - throw new GLException("Graphics configuration fetch (eglGetConfigs) failed"); - } - if (numConfigs[0] == 0) { - throw new GLException("Graphics configuration fetch (eglGetConfigs) - no EGLConfig found"); - } - GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], - capsChosen.isOnscreen(), capsChosen.isPBuffer()); - if(DEBUG) { - System.err.println("EGL Get Configs: "+numConfigs[0]+", Caps "+caps.length); - printCaps("eglGetConfigs", caps, System.err); - } - int chosen = -1; - try { - chosen = chooser.chooseCapabilities(capsChosen, caps, -1); - } catch (NativeWindowException e) { throw new GLException(e); } - if(chosen<0) { - throw new GLException("Graphics configuration chooser failed"); - } - if(DEBUG) { - System.err.println("Chosen "+caps[chosen]); - } - res = eglChooseConfig(eglDisplay, caps[chosen], capsReq, chooser, absScreen); - if(null!=res) { - return res; - } - if(DEBUG) { - System.err.println("eglChooseConfig failed with eglGetConfig/choosen capabilities "+caps[chosen]); - } - // Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..] // // rgb888 - d16, s4 @@ -222,73 +221,100 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact } static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay, - GLCapabilitiesImmutable capsChosen0, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { - GLProfile glp = capsChosen0.getGLProfile(); - int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen0); - PointerBuffer configs = PointerBuffer.allocateDirect(1); + GLProfile glp = capsChosen.getGLProfile(); + boolean onscreen = capsChosen.isOnscreen(); + boolean usePBuffer = capsChosen.isPBuffer(); + List/*<EGLGLCapabilities>*/ availableCaps = null; + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + int recommendedIndex = -1; + long recommendedEGLConfig = -1; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + if (DEBUG) { + System.err.println("!!! eglChooseConfig maxConfigs: "+maxConfigs[0]); + } + + int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen); + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); int[] numConfigs = new int[1]; + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice if (!EGL.eglChooseConfig(eglDisplay, attrs, 0, configs, configs.capacity(), numConfigs, 0)) { - throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen0); + throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen+", error "+toHexString(EGL.eglGetError())); } if (numConfigs[0] > 0) { - if(DEBUG) { - GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], - capsChosen0.isOnscreen(), capsChosen0.isPBuffer()); - System.err.println("EGL Choose Configs: "+numConfigs[0]+", Caps "+caps.length); - printCaps("eglChooseConfig", caps, System.err); - } - int[] val = new int[1]; - // get the configID - if(!EGL.eglGetConfigAttrib(eglDisplay, configs.get(0), EGL.EGL_CONFIG_ID, val, 0)) { - if(DEBUG) { - // FIXME: this happens on a ATI PC Emulation .. - System.err.println("EGL couldn't retrieve ConfigID for already chosen eglConfig "+capsChosen0+", error 0x"+Integer.toHexString(EGL.eglGetError())); + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); + if(availableCaps.size() > 0) { + recommendedEGLConfig = configs.get(0); + recommendedIndex = 0; + if (DEBUG) { + System.err.println("!!! eglChooseConfig recommended fbcfg " + toHexString(recommendedEGLConfig) + ", idx " + recommendedIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); } - return null; + } else if (DEBUG) { + System.err.println("!!! eglChooseConfig no caps for recommended fbcfg " + toHexString(configs.get(0))); + System.err.println("!!! user caps " + capsChosen); } - GLCapabilitiesImmutable capsChosen1 = EGLGraphicsConfiguration.EGLConfig2Capabilities( - glp, eglDisplay, configs.get(0), - true, capsChosen0.isOnscreen(), capsChosen0.isPBuffer()); - if(null!=capsChosen1) { - if(DEBUG) { - System.err.println("eglChooseConfig found: eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", eglConfig ID 0x"+Integer.toHexString(val[0])+ - ", "+capsChosen0+" -> "+capsChosen1); - } - return new EGLGraphicsConfiguration(absScreen, capsChosen1, capsRequested, chooser, configs.get(0), val[0]); + } + + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + if( null == availableCaps || 0 == availableCaps.size() ) { + // reset .. + recommendedEGLConfig = -1; + recommendedIndex = -1; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); } - if(DEBUG) { - System.err.println("eglChooseConfig couldn't verify: eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", eglConfig ID 0x"+Integer.toHexString(val[0])+ - ", for "+capsChosen0); + if (numConfigs[0] > 0) { + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); } - } else { + } + + if( null == availableCaps || 0 == availableCaps.size() ) { if(DEBUG) { - System.err.println("EGL Choose Configs: None using eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", "+capsChosen0); + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("Graphics configuration 1st choice and 2nd choice failed - no configs"); } + return null; } - return null; + + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; + } + EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex); + + return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser); } - static GLCapabilitiesImmutable[] eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, - boolean onscreen, boolean usePBuffer) { - GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[num]; + static List/*<GLCapabilitiesImmutable>*/ eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask) { + ArrayList caps = new ArrayList(num); for(int i=0; i<num; i++) { - caps[i] = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs.get(i), - true, onscreen, usePBuffer); + EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask); } return caps; } - static void printCaps(String prefix, GLCapabilitiesImmutable[] caps, PrintStream out) { - for(int i=0; i<caps.length; i++) { - out.println(prefix+"["+i+"] "+caps[i]); + static void printCaps(String prefix, List/*GLCapabilitiesImmutable*/ caps, PrintStream out) { + for(int i=0; i<caps.size(); i++) { + out.println(prefix+"["+i+"] "+caps.get(i)); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index 1895c8e67..421bae715 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -41,14 +41,17 @@ package com.jogamp.opengl.impl.macosx.cgl; import java.nio.*; +import java.util.HashMap; +import java.util.List; + import javax.media.nativewindow.*; +import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; import javax.media.opengl.*; + import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.ProxySurface; -import java.util.HashMap; -import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper; @@ -123,6 +126,10 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { protected final void shutdownInstance() {} + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + throw new UnsupportedOperationException("not yet implemented"); + } + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java index f12f5d31a..cc06a6775 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -33,7 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; @@ -48,7 +48,7 @@ import javax.media.opengl.GLCapabilitiesImmutable; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); MacOSXCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java index e4249f9c8..95b6f473f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java @@ -33,7 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl.awt; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -55,7 +55,7 @@ import javax.media.opengl.GLException; import com.jogamp.opengl.impl.macosx.cgl.MacOSXCGLGraphicsConfiguration; -public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public MacOSXAWTCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java new file mode 100644 index 000000000..b5be4bf8d --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java @@ -0,0 +1,243 @@ +/** + * 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.impl.windows.wgl; + +import java.util.Comparator; + +import com.jogamp.nativewindow.impl.windows.GDI; +import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; +import javax.media.opengl.GL; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +public class WGLGLCapabilities extends GLCapabilities { + PIXELFORMATDESCRIPTOR pfd; + int pfdID; + int arb_pixelformat; // -1 PFD, 0 NOP, 1 ARB + + /** Comparing pfd id only */ + public static class PfdIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof WGLGLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a WGLGLCapabilities object: " + c); + } + if ( ! ( o2 instanceof WGLGLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a WGLGLCapabilities object: " + c); + } + + final WGLGLCapabilities caps1 = (WGLGLCapabilities) o1; + final long id1 = caps1.getPFDID(); + + final WGLGLCapabilities caps2 = (WGLGLCapabilities) o2; + final long id2 = caps2.getPFDID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public WGLGLCapabilities(PIXELFORMATDESCRIPTOR pfd, int pfdID, GLProfile glp) { + super(glp); + this.pfd = pfd; + this.pfdID = pfdID; + this.arb_pixelformat = 0; + } + + public boolean setValuesByGDI() { + arb_pixelformat = -1; + + setRedBits(pfd.getCRedBits()); + setGreenBits(pfd.getCGreenBits()); + setBlueBits(pfd.getCBlueBits()); + setAlphaBits(pfd.getCAlphaBits()); + setAccumRedBits(pfd.getCAccumRedBits()); + setAccumGreenBits(pfd.getCAccumGreenBits()); + setAccumBlueBits(pfd.getCAccumBlueBits()); + setAccumAlphaBits(pfd.getCAccumAlphaBits()); + setDepthBits(pfd.getCDepthBits()); + setStencilBits(pfd.getCStencilBits()); + setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); + setStereo((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); + setHardwareAccelerated((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 + || (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0); + // n/a with non ARB/GDI method: + // multisample + // opaque + // pbuffer + + return true; + } + + public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) { + arb_pixelformat = 1; + + for (int i = 0; i < niattribs; i++) { + int attr = iattribs[i]; + switch (attr) { + case WGLExt.WGL_DRAW_TO_WINDOW_ARB: + case WGLExt.WGL_DRAW_TO_BITMAP_ARB: + case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: + break; + + case WGLExt.WGL_ACCELERATION_ARB: + setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB); + break; + + case WGLExt.WGL_SUPPORT_OPENGL_ARB: + if (iresults[i] != GL.GL_TRUE) { + return false; + } + break; + + case WGLExt.WGL_DEPTH_BITS_ARB: + setDepthBits(iresults[i]); + break; + + case WGLExt.WGL_STENCIL_BITS_ARB: + setStencilBits(iresults[i]); + break; + + case WGLExt.WGL_DOUBLE_BUFFER_ARB: + setDoubleBuffered(iresults[i] == GL.GL_TRUE); + break; + + case WGLExt.WGL_STEREO_ARB: + setStereo(iresults[i] == GL.GL_TRUE); + break; + + case WGLExt.WGL_PIXEL_TYPE_ARB: + // Fail softly with unknown results here + if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB || + iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { + setPbufferFloatingPointBuffers(true); + } + break; + + case WGLExt.WGL_FLOAT_COMPONENTS_NV: + if (iresults[i] != 0) { + setPbufferFloatingPointBuffers(true); + } + break; + + case WGLExt.WGL_RED_BITS_ARB: + setRedBits(iresults[i]); + break; + + case WGLExt.WGL_GREEN_BITS_ARB: + setGreenBits(iresults[i]); + break; + + case WGLExt.WGL_BLUE_BITS_ARB: + setBlueBits(iresults[i]); + break; + + case WGLExt.WGL_ALPHA_BITS_ARB: + setAlphaBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_RED_BITS_ARB: + setAccumRedBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_GREEN_BITS_ARB: + setAccumGreenBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_BLUE_BITS_ARB: + setAccumBlueBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB: + setAccumAlphaBits(iresults[i]); + break; + + case WGLExt.WGL_SAMPLE_BUFFERS_ARB: + setSampleBuffers(iresults[i] != 0); + break; + + case WGLExt.WGL_SAMPLES_ARB: + setNumSamples(iresults[i]); + break; + + default: + throw new GLException("Unknown pixel format attribute " + iattribs[i]); + } + } + return true; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public PIXELFORMATDESCRIPTOR getPFD() { return pfd; } + final public int getPFDID() { return pfdID; } + + final public boolean isSetByARB() { return 0 < arb_pixelformat; } + final public boolean isSetByGDI() { return 0 > arb_pixelformat; } + final public boolean isSet() { return 0 != arb_pixelformat; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append(pfdID).append(" "); + switch (arb_pixelformat) { + case -1: + sink.append("gdi"); + break; + case 0: + sink.append("nop"); + break; + case 1: + sink.append("arb"); + break; + default: + throw new InternalError("invalid arb_pixelformat: " + arb_pixelformat); + } + sink.append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java index f2f65622b..a307e295d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java @@ -89,7 +89,6 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { caps.setDepthBits(16); caps.setDoubleBuffered(true); caps.setOnscreen (true); - caps.setPBuffer (true); return new WindowsDummyWGLDrawable(factory, caps, absScreen); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index 41889e703..720ac84ca 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -50,7 +50,6 @@ import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; -import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { @@ -174,96 +173,57 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format"); } - boolean haveMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); - if (DEBUG) { System.err.println("" + nformats + " suitable pixel formats found"); - // query pixel format - iattributes[0] = WGLExt.WGL_RED_BITS_ARB; - iattributes[1] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[2] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[3] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[4] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB); - iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - int[] ivalues = new int[9]; for (int i = 0; i < nformats; i++) { - if (!wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) { - throw new GLException("Error while querying pixel format " + pformats[i] + - "'s (index " + i + "'s) capabilities for debugging"); - } - System.err.print("pixel format " + pformats[i] + " (index " + i + "): "); - System.err.print( "r: " + ivalues[0]); - System.err.print(" g: " + ivalues[1]); - System.err.print(" b: " + ivalues[2]); - System.err.print(" a: " + ivalues[3]); - System.err.print(" depth: " + ivalues[4]); - if (haveMultisample) { - System.err.print(" multisample: " + ivalues[6]); - } - System.err.print(" samples: " + ivalues[7]); - if (useFloat) { - if (ati) { - if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { - System.err.print(" [ati float]"); - } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA_ARB) { - System.err.print(" [unknown pixel type " + ivalues[5] + "]"); - } - } else { - if (ivalues[5] != 0) { - System.err.print(" [float]"); - } - } - } - - if (ivalues[8] != 0) { - System.err.print(" [pbuffer]"); - } - System.err.println(); + WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pformats[i], glProfile, false, true); + System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps); } } + int pfdid = 0; long tmpBuffer = 0; - int whichFormat = -1; - // Loop is a workaround for bugs in NVidia's recent drivers - for (whichFormat = 0; whichFormat < nformats; whichFormat++) { - int format = pformats[whichFormat]; - - // Create the p-buffer. - niattribs = 0; - - if (rtt) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB; - if (useFloat) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; - } else { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB; - } + { + int whichFormat; + // Loop is a workaround for bugs in NVidia's recent drivers + for (whichFormat = 0; whichFormat < nformats; whichFormat++) { + int format = pformats[whichFormat]; + + // Create the p-buffer. + niattribs = 0; + + if (rtt) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB; + if (useFloat) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; + } else { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB; + } - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB; - iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB; + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB; + iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB; - iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB; - iattributes[niattribs++] = GL.GL_FALSE; + iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB; + iattributes[niattribs++] = GL.GL_FALSE; - iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; - iattributes[niattribs++] = GL.GL_FALSE; - } + iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; + iattributes[niattribs++] = GL.GL_FALSE; + } - iattributes[niattribs++] = 0; + iattributes[niattribs++] = 0; - tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0); - if (tmpBuffer != 0) { - // Done - break; - } - } + tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0); + if (tmpBuffer != 0) { + // Done + break; + } + } - if (tmpBuffer == 0) { - throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + - " pixel formats, last error was: " + wglGetLastError()); + if (0 == tmpBuffer) { + throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + + " pixel formats, last error was: " + wglGetLastError()); + } + pfdid = pformats[whichFormat]; } // Get the device context. @@ -280,48 +240,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { // Re-query chosen pixel format { - niattribs = 0; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; - iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; - iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - int[] ivalues = new int[niattribs]; - if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { - GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, false, true); - if(null == newCaps|| newCaps.isOnscreen() || !newCaps.isPBuffer()) { - throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); - } - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { - if (DEBUG) { - System.err.println("Unable to describe pixel format (Continue: true) " + whichFormat + "/" + nformats + " pfdID " + pformats[whichFormat]+":\n\t"+newCaps); - } - } - config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true); - } else { - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { - throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); - } - GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, false, true); - if(newCaps.isOnscreen()) { - throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps); - } - config.setCapsPFD(newCaps, pfd, pformats[whichFormat], false); + WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pfdid, glProfile, false, true); + if(null == newCaps) { + throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + this.toHexString(tmpHdc)); + } + if(newCaps.isOnscreen() || !newCaps.isPBuffer()) { + throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); } + config.setCapsPFD(newCaps); } // Determine the actual width and height we were able to create. diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index 0b4933db8..7d38f8ee8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -48,6 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; +import javax.media.opengl.GLCapabilitiesImmutable; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -55,8 +56,6 @@ import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.opengl.impl.GLContextImpl; import com.jogamp.opengl.impl.GLContextShareSet; import com.jogamp.opengl.impl.GLDrawableImpl; -import javax.media.opengl.GLCapabilitiesImmutable; - public class WindowsWGLContext extends GLContextImpl { static final Map/*<String, String>*/ functionNameMap; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index ac71d6e9c..674690e50 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -53,6 +53,8 @@ import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.windows.WindowsGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; @@ -71,8 +73,6 @@ import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDrawableImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; import com.jogamp.opengl.impl.SharedResourceRunner; -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper; @@ -179,13 +179,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { canCreateGLPbuffer = canPbuffer; readDrawableAvailable = readBufferAvail; } - public AbstractGraphicsDevice getDevice() { return device; } - public AbstractGraphicsScreen getScreen() { return screen; } - public GLDrawableImpl getDrawable() { return drawable; } - public GLContextImpl getContext() { return context; } + final public AbstractGraphicsDevice getDevice() { return device; } + final public AbstractGraphicsScreen getScreen() { return screen; } + final public GLDrawableImpl getDrawable() { return drawable; } + final public GLContextImpl getContext() { return context; } - boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } - boolean isReadDrawableAvailable() { return readDrawableAvailable; } + final boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } + final boolean isReadDrawableAvailable() { return readDrawableAvailable; } } class SharedResourceImplementation implements SharedResourceRunner.Implementation { @@ -218,7 +218,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (null == absScreen) { throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); } - GLProfile glp = GLProfile.getDefault(sharedDevice); + GLProfile glp = GLProfile.getMinDesktop(sharedDevice); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } @@ -330,7 +330,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return null; } - protected WindowsWGLDrawable getSharedDrawable(AbstractGraphicsDevice device) { + protected WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return (WindowsWGLDrawable) sr.getDrawable(); @@ -338,11 +338,19 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return null; } + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); + } + protected final void shutdownInstance() { sharedResourceRunner.releaseAndWait(); RegisteredClassFactory.shutdownSharedClasses(); } + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java index 0ff1832d1..36d78b38d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -33,11 +33,15 @@ package com.jogamp.opengl.impl.windows.wgl; +import java.util.ArrayList; +import java.util.List; + import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsConfiguration; import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GL; -import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; @@ -47,8 +51,7 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; import com.jogamp.opengl.impl.GLContextImpl; -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.opengl.GLCapabilitiesImmutable; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { // Keep this under the same debug flag as the drawable factory for convenience @@ -60,28 +63,21 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio protected static final int MAX_PFORMATS = 256; protected static final int MAX_ATTRIBS = 256; - private PIXELFORMATDESCRIPTOR pixelfmt; - private int pixelfmtID; private GLCapabilitiesChooser chooser; private boolean isChosen = false; - private boolean choosenByARBPixelFormat=false; WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { super(screen, capsChosen, capsRequested); - this.pixelfmt = null; - this.pixelfmtID = -1; this.chooser=chooser; - isChosen = false; - choosenByARBPixelFormat=false; + this.isChosen = false; } WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, - PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, boolean choosenByARBPixelFormat) { + WGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested) { super(screen, capsChosen, capsRequested); - setCapsPFD(capsChosen, pixelfmt, pixelfmtID, choosenByARBPixelFormat); + setCapsPFD(capsChosen); this.chooser=null; } @@ -106,8 +102,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); boolean hasARB = null != sharedContext && sharedContext.isExtensionAvailable(WGL_ARB_pixel_format) ; - GLCapabilitiesImmutable caps = null; - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); // PFD storage + WGLGLCapabilities caps = null; if(hasARB) { sharedContext.makeCurrent(); @@ -116,18 +111,14 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio } finally { sharedContext.release(); } - } else { - caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen, usePBuffer, pfd); + } else if(!usePBuffer) { + caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen); } if(null==caps) { throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID+", hasARB "+hasARB); } - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Unable to describe pixel format " + pfdID); - } - - return new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, hasARB); + return new WindowsWGLGraphicsConfiguration(screen, caps, caps); } public Object clone() { @@ -164,24 +155,18 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs); } - final void setCapsPFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByARBPixelFormat) { - this.pixelfmt = pfd; - this.pixelfmtID = pfdID; + final void setCapsPFD(WGLGLCapabilities caps) { setChosenCapabilities(caps); this.isChosen=true; - this.choosenByARBPixelFormat=choosenByARBPixelFormat; if (DEBUG) { - System.err.println("*** setCapsPFD: ARB-Choosen "+choosenByARBPixelFormat+", pfdID "+pfdID+", "+caps); + System.err.println("*** setCapsPFD: "+caps); } } - public final boolean isDetermined() { - return isChosen; - } - - public final PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; } - public final int getPixelFormatID() { return pixelfmtID; } - public final boolean isChoosenByWGL() { return choosenByARBPixelFormat; } + public final boolean isDetermined() { return isChosen; } + public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; } + public final int getPixelFormatID() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; } + public final boolean isChoosenByARB() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; } static int fillAttribsForGeneralWGLARBQuery(boolean haveWGLARBMultisample, int[] iattributes) { int niattribs = 0; @@ -207,6 +192,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; } + // pbo float buffer + iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; // ati + iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia + return niattribs; } @@ -251,8 +240,8 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pfdIDs; } - static GLCapabilitiesImmutable wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, - GLProfile glp, boolean onscreen, boolean usePBuffer) { + static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, + GLProfile glp, boolean onscreen, boolean usePBuffer) { boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; @@ -265,10 +254,14 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context"); + throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context"); } - return AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, - onscreen, usePBuffer); + ArrayList bucket = new ArrayList(1); + final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) { + return (WGLGLCapabilities) bucket.get(0); + } + return null; } static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext, @@ -300,8 +293,11 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return null; } int numFormats = numFormatsTmp[0]; - int[] pformats = new int[numFormats]; - System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats); + int[] pformats = null; + if( 0 < numFormats ) { + pformats = new int[numFormats]; + System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats); + } if (DEBUG) { System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x" + Integer.toHexString(accelerationMode) + ": " + numFormats); @@ -309,97 +305,43 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pformats; } - static GLCapabilitiesImmutable[] wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, - GLProfile glp, boolean onscreen, boolean usePBuffer) { + static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp, boolean onscreen, boolean usePBuffer) { + final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, winattrbits); + } + + static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2AllGLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp) { + return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS); + } + + private static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp, int winattrbits) { boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; } boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); final int numFormats = pfdIDs.length; - GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[numFormats]; - int[] iattributes = new int [2*MAX_ATTRIBS]; - int[] iresults = new int [2*MAX_ATTRIBS]; + int[] iattributes = new int [2*MAX_ATTRIBS]; + int[] iresults = new int [2*MAX_ATTRIBS]; int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); + ArrayList bucket = new ArrayList(); + for(int i = 0; i<numFormats; i++) { if ( pfdIDs[i] >= 1 && sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) { - caps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); - } else { - if (DEBUG) { - System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + - i + "/" + numFormats + ": " + pfdIDs[i]); - } - caps[i] = null; + AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits); + } else if (DEBUG) { + System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + + i + "/" + numFormats + ": " + pfdIDs[i] + ", " + + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); } } - return caps; - } - - /** - * - * @param sharedCtx - * @param hdc - * @param glp - * @param onscreen - * @param usePBuffer - * @param pfIDs stores the PIXELFORMAT ID for the GLCapabilitiesImmutable[] - * @return the resulting GLCapabilitiesImmutable[] - */ - static GLCapabilitiesImmutable[] wglARBAllPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, - GLProfile glp, boolean onscreen, boolean usePBuffer, int[] pfIDs) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); - if (!haveWGLChoosePixelFormatARB) { - return null; - } - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); - - // Produce a list of GLCapabilities to give to the - // GLCapabilitiesChooser. - // Use wglGetPixelFormatAttribivARB instead of - // DescribePixelFormat to get higher-precision information - // about the pixel format (should make the GLCapabilities - // more precise as well...i.e., remove the - // "HardwareAccelerated" bit, which is basically - // meaningless, and put in whether it can render to a - // window, to a pbuffer, or to a pixmap) - GLCapabilitiesImmutable[] availableCaps = null; - int numFormats = 0; - int niattribs = 0; - int[] iattributes = new int[2 * MAX_ATTRIBS]; - int[] iresults = new int[2 * MAX_ATTRIBS]; - - WGLExt wglExt = sharedCtx.getWGLExt(); - iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; - if (wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { - numFormats = iresults[0]; - if (DEBUG) { - System.err.println("wglARBAllPFIDs2GLCapabilities: wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats + ", pfIDs sz "+pfIDs.length); - } - if (numFormats > pfIDs.length) { - numFormats = pfIDs.length; - } - - niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); - - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - pfIDs[i] = i + 1; - if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfIDs[i], 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("wglARBAllPFIDs2GLCapabilities: Error getting pixel format attributes for pixel format " + pfIDs[i]); - } - availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); - } - } else { - long lastErr = GDI.GetLastError(); - // Some GPU's falsely fails with a zero error code (success) - if (lastErr != GDI.ERROR_SUCCESS) { - throw new GLException("wglARBAllPFIDs2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + lastErr); - } - } - return availableCaps; + return bucket; } static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps, @@ -573,161 +515,50 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return true; } - public static final int WINDOW_BIT = 1 << 0 ; - public static final int BITMAP_BIT = 1 << 1 ; - public static final int PBUFFER_BIT = 1 << 2 ; - - static int WGLConfig2DrawableTypeBits(int[] iattribs, - int niattribs, - int[] iresults) { + static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) { int val = 0; for (int i = 0; i < niattribs; i++) { int attr = iattribs[i]; switch (attr) { case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - if(iresults[i] == GL.GL_TRUE) val |= WINDOW_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT; break; case WGLExt.WGL_DRAW_TO_BITMAP_ARB: - if(iresults[i] == GL.GL_TRUE) val |= BITMAP_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT; break; case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: - if(iresults[i] == GL.GL_TRUE) val |= PBUFFER_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; break; } } return val; } - static boolean WGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static boolean AttribList2GLCapabilities( ArrayList capsBucket, + final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs, + final int niattribs, + final int[] iresults, final int winattrmask) { + final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults); + int drawableTypeBits = winattrmask & allDrawableTypeBits; - if ( onscreen ) { - res = ( 0 != (val & WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & BITMAP_BIT) ) ; - } + if( 0 == drawableTypeBits ) { + return false; } + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - return res; - } - - static GLCapabilitiesImmutable AttribList2GLCapabilities( - GLProfile glp, int[] iattribs, - int niattribs, - int[] iresults, - boolean onscreen, boolean usePBuffer) { - GLCapabilities res = new GLCapabilities(glp); - int drawableTypeBits = WGLConfig2DrawableTypeBits(iattribs, niattribs, iresults); - if(WGLConfigDrawableTypeVerify(drawableTypeBits, onscreen, usePBuffer)) { - res.setOnscreen(onscreen); - res.setPBuffer(usePBuffer); - } else { - if(DEBUG) { - System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+ - "), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+ - ", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+ - ", bitmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")"); + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + // remove displayable bits, since pfdID is non displayable + drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT); + if( 0 == drawableTypeBits ) { + return false; } - return null; + // non displayable requested (pbuffer) } + WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByARB(iattribs, niattribs, iresults); - for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; - switch (attr) { - case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - case WGLExt.WGL_DRAW_TO_BITMAP_ARB: - case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: - break; - - case WGLExt.WGL_ACCELERATION_ARB: - res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB); - break; - - case WGLExt.WGL_SUPPORT_OPENGL_ARB: - if (iresults[i] != GL.GL_TRUE) { - return null; - } - break; - - case WGLExt.WGL_DEPTH_BITS_ARB: - res.setDepthBits(iresults[i]); - break; - - case WGLExt.WGL_STENCIL_BITS_ARB: - res.setStencilBits(iresults[i]); - break; - - case WGLExt.WGL_DOUBLE_BUFFER_ARB: - res.setDoubleBuffered(iresults[i] == GL.GL_TRUE); - break; - - case WGLExt.WGL_STEREO_ARB: - res.setStereo(iresults[i] == GL.GL_TRUE); - break; - - case WGLExt.WGL_PIXEL_TYPE_ARB: - // Fail softly with unknown results here - if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB|| - iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { - res.setPbufferFloatingPointBuffers(true); - } - break; - - case WGLExt.WGL_FLOAT_COMPONENTS_NV: - if (iresults[i] != 0) { - res.setPbufferFloatingPointBuffers(true); - } - break; - - case WGLExt.WGL_RED_BITS_ARB: - res.setRedBits(iresults[i]); - break; - - case WGLExt.WGL_GREEN_BITS_ARB: - res.setGreenBits(iresults[i]); - break; - - case WGLExt.WGL_BLUE_BITS_ARB: - res.setBlueBits(iresults[i]); - break; - - case WGLExt.WGL_ALPHA_BITS_ARB: - res.setAlphaBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_RED_BITS_ARB: - res.setAccumRedBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_GREEN_BITS_ARB: - res.setAccumGreenBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_BLUE_BITS_ARB: - res.setAccumBlueBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB: - res.setAccumAlphaBits(iresults[i]); - break; - - case WGLExt.WGL_SAMPLE_BUFFERS_ARB: - res.setSampleBuffers(iresults[i] != 0); - break; - - case WGLExt.WGL_SAMPLES_ARB: - res.setNumSamples(iresults[i]); - break; - - default: - throw new GLException("Unknown pixel format attribute " + iattribs[i]); - } - } - return res; + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } // @@ -747,39 +578,48 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pfdIDs; } - static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen, boolean usePBuffer, PIXELFORMATDESCRIPTOR pfd) { - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Error describing pixel format " + pfdID + " of device context"); + static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) { + int val = 0; + + int dwFlags = pfd.getDwFlags(); + + if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; } - return PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer); + if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + return val; } - static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) { + static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) { + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); + ArrayList capsBucket = new ArrayList(1); + if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) { + return (WGLGLCapabilities) capsBucket.get(0); + } + return null; + } + + static boolean PFD2GLCapabilities(ArrayList capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) { + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); + if(null == pfd) { + return false; + } if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { - return null; - } - GLCapabilities res = new GLCapabilities(glp); - res.setRedBits (pfd.getCRedBits()); - res.setGreenBits (pfd.getCGreenBits()); - res.setBlueBits (pfd.getCBlueBits()); - res.setAlphaBits (pfd.getCAlphaBits()); - res.setAccumRedBits (pfd.getCAccumRedBits()); - res.setAccumGreenBits(pfd.getCAccumGreenBits()); - res.setAccumBlueBits (pfd.getCAccumBlueBits()); - res.setAccumAlphaBits(pfd.getCAccumAlphaBits()); - res.setDepthBits (pfd.getCDepthBits()); - res.setStencilBits (pfd.getCStencilBits()); - res.setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); - res.setStereo ((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); - res.setHardwareAccelerated( (pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 || - (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0 ); - res.setOnscreen ( onscreen && ((pfd.getDwFlags() & GDI.PFD_DRAW_TO_WINDOW) != 0) ); - res.setPBuffer ( usePBuffer ); - // n/a with non ARB/GDI method: - // multisample - // opaque - // pbuffer - return res; + return false; + } + final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + + WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByGDI(); + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) { @@ -828,15 +668,28 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return pfd; } - static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) { PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); pfd.setNSize((short) pfd.size()); pfd.setNVersion((short) 1); + if(0 != hdc && 1 <= pfdID) { + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + // Accelerated pixel formats that are non displayable + if(DEBUG) { + System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError()); + } + return null; + } + } return pfd; } + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + return createPixelFormatDescriptor(0, 0); + } + public String toString() { - return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", ARB-Choosen "+choosenByARBPixelFormat+ + return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() + ",\n\trequested " + getRequestedCapabilities() + ",\n\tchosen " + getChosenCapabilities() + "]"; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index 0996438db..812829168 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -43,7 +43,6 @@ import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.opengl.GLCapabilitiesImmutable; -import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; @@ -51,15 +50,22 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; +import com.jogamp.opengl.impl.SharedResourceRunner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits are used on Windows platforms. Toolkits will likely need to delegate to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); + static WGLGLCapabilities.PfdIDComparator PfdIDComparator = new WGLGLCapabilities.PfdIDComparator(); WindowsWGLGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this); @@ -91,17 +97,67 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat if(null==absScreen) { absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); } + AbstractGraphicsDevice absDevice = absScreen.getDevice(); - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( + capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) ); return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser ); } + protected static List/*<WGLGLCapabilities>*/ getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + WindowsWGLDrawable sharedDrawable = (WindowsWGLDrawable) sharedResource.getDrawable(); + GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + WindowsWGLContext sharedContext = (WindowsWGLContext) sharedResource.getContext(); + List availableCaps = null; + + sharedDrawable.lockSurface(); + try { + long hdc = sharedDrawable.getHandle(); + if (0 == hdc) { + throw new GLException("Error: HDC is null"); + } + if (sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { + availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedContext, capsChosen.getGLProfile()); + } + if( null == availableCaps || 0 == availableCaps.size() ) { + availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen); + } + } finally { + sharedDrawable.unlockSurface(); + } + + if( null != availableCaps ) { + Collections.sort(availableCaps, PfdIDComparator); + } + return availableCaps; + } + + static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesARB(long hdc, WindowsWGLContext sharedContext, GLProfile glProfile) { + int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc); + return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedContext, hdc, pformats, glProfile); + } + + static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesGDI(long hdc, GLCapabilitiesImmutable capsChosen) { + boolean onscreen = capsChosen.isOnscreen(); + if(capsChosen.isPBuffer()) { + return null; + } + GLProfile glProfile = capsChosen.getGLProfile(); + + int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); + int numFormats = pformats.length; + ArrayList bucket = new ArrayList(numFormats); + for (int i = 0; i < numFormats; i++) { + bucket.add( WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen) ); + } + return bucket; + } + /** * * @param chooser @@ -161,7 +217,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat throw new IllegalArgumentException("WindowsWGLGraphicsConfiguration is null"); } WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; - WindowsWGLDrawable sharedDrawable = factory.getSharedDrawable(device); + WindowsWGLDrawable sharedDrawable = factory.getOrCreateSharedDrawable(device); if(null == sharedDrawable) { throw new IllegalArgumentException("Shared Drawable is null"); } @@ -202,35 +258,35 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } + if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available"); + } + return false; + } + GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); boolean onscreen = capsChosen.isOnscreen(); boolean usePBuffer = capsChosen.isPBuffer(); GLProfile glProfile = capsChosen.getGLProfile(); - GLCapabilitiesImmutable[] availableCaps = null; // caps array matching PFD ID of pformats array - int pfdID; // chosen or preset PFD ID - GLCapabilitiesImmutable pixelFormatCaps = null; // chosen or preset PFD ID's caps + WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available"); - } - return false; - } sharedContext.makeCurrent(); try { - if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) { + final int presetPFDID = extHDC ? -1 : GDI.GetPixelFormat(hdc) ; + if ( 1 <= presetPFDID ) { // Pixelformat already set by either // - a previous preselectGraphicsConfiguration() call on the same HDC, // - the graphics driver, copying the HDC's pixelformat to the new one, // - or the Java2D/OpenGL pipeline's configuration if (DEBUG) { System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc) - + ", pixelformat " + pfdID); + + ", pixelformat " + presetPFDID); } pixelFormatSet = true; - pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, pfdID, glProfile, onscreen, usePBuffer); + pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, presetPFDID, glProfile, onscreen, usePBuffer); } else { int recommendedIndex = -1; // recommended index @@ -242,13 +298,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat float[] fattributes = new float[1]; pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen, iattributes, -1, fattributes); + if (null != pformats) { recommendedIndex = 0; - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: NumFormats (wglChoosePixelFormatARB) " + pformats.length); - System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + pformats[recommendedIndex] + ", idx " + recommendedIndex); - } } else { + if(DEBUG) { + System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen); + } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc); if (DEBUG) { @@ -262,9 +318,27 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return false; } } - // translate chosen/all or given PFD IDs - availableCaps = WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, - glProfile, onscreen, usePBuffer); + + List /*<WGLGLCapabilities>*/ availableCaps = + WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, + glProfile, onscreen, usePBuffer); + if( null == availableCaps || 0 == availableCaps.size() ) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + + " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer); + Thread.dumpStack(); + } + return false; + } + + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: " + pformats.length + + " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps"); + if(0 <= recommendedIndex) { + System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + + pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex)); + } + } int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if ( 0 > chosenIndex ) { @@ -273,56 +347,52 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } - pixelFormatCaps = availableCaps[chosenIndex]; - pfdID = pformats[chosenIndex]; + pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); if( null == pixelFormatCaps) { throw new GLException("Null Capabilities with "+ " chosen pfdID: native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID); + " chosen "+pixelFormatCaps.getPFDID()); } if (DEBUG) { System.err.println("!!! chosen pfdID (ARB): native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID+", caps " + pixelFormatCaps); + " chosen "+pixelFormatCaps); } } } finally { sharedContext.release(); } - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("updateGraphicsConfigurationARB: Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); - } - if ( !extHDC && !pixelFormatSet ) { - if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { - throw new GLException("Unable to set pixel format " + pfdID + + if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { + throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } if (DEBUG) { - System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID); + System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pixelFormatCaps.getPFDID()); } } - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); + config.setCapsPFD(pixelFormatCaps); return true; } private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, int[] pformats) { GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + if(capsChosen.isPBuffer()) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen); + } + return false; + } boolean onscreen = capsChosen.isOnscreen(); - boolean usePBuffer = capsChosen.isPBuffer(); GLProfile glProfile = capsChosen.getGLProfile(); - GLCapabilitiesImmutable[] availableCaps = null; // caps array matching PFD ID of pformats array + ArrayList/*<WGLGLCapabilities>*/ availableCaps = new ArrayList(); int pfdID; // chosen or preset PFD ID - GLCapabilitiesImmutable pixelFormatCaps = null; // chosen or preset PFD ID's caps + WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); // PFD storage - if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) { // Pixelformat already set by either // - a previous preselectGraphicsConfiguration() call on the same HDC, @@ -333,26 +403,30 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat + ", pixelformat " + pfdID); } pixelFormatSet = true; - pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen, usePBuffer, pfd); + pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen); } else { if(null == pformats) { pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); } - int numFormats = pformats.length; - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen, usePBuffer, pfd); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); + + for (int i = 0; i < pformats.length; i++) { + WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask); } + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd); pfdID = GDI.ChoosePixelFormat(hdc, pfd); int recommendedIndex = -1 ; if( 1 <= pfdID ) { // seek index .. - for (recommendedIndex = numFormats - 1 ; - 0 <= recommendedIndex && pfdID != pformats[recommendedIndex]; + for (recommendedIndex = availableCaps.size() - 1 ; + 0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID(); recommendedIndex--) { /* nop */ } } + // 2nd choice: if no preferred recommendedIndex available if (DEBUG) { System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")"); } @@ -363,44 +437,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } - pixelFormatCaps = availableCaps[chosenIndex]; - pfdID = pformats[chosenIndex]; - if( null == pixelFormatCaps) { - throw new GLException("Null Capabilities with "+ - " chosen pfdID: native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID); - } + pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); if (DEBUG) { System.err.println("!!! chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) + - " chosen "+pfdID+", caps " + pixelFormatCaps); + ", caps " + pixelFormatCaps); } } - - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); - } if ( !extHDC && !pixelFormatSet ) { - if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { - throw new GLException("Unable to set pixel format " + pfdID + + if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { + throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } if (DEBUG) { - System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID); + System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> " + pixelFormatCaps.getPFDID()); } } - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, false); + config.setCapsPFD(pixelFormatCaps); return true; - - } - - static String getThreadName() { - return Thread.currentThread().getName(); - } - - static String toHexString(long hex) { - return "0x" + Long.toHexString(hex); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java index 4fbdab9c2..f753c08c5 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java @@ -36,7 +36,7 @@ package com.jogamp.opengl.impl.windows.wgl.awt; import com.jogamp.common.util.ArrayHashSet; import com.jogamp.nativewindow.impl.jawt.windows.Win32SunJDKReflection; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -59,7 +59,7 @@ import javax.media.opengl.GLException; import com.jogamp.opengl.impl.windows.wgl.WindowsWGLGraphicsConfiguration; import javax.media.opengl.GLDrawableFactory; -public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public WindowsAWTWGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java new file mode 100644 index 000000000..e3a1e7d72 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java @@ -0,0 +1,116 @@ +/** + * 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.impl.x11.glx; + +import com.jogamp.nativewindow.impl.x11.XVisualInfo; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import java.util.Comparator; + +public class X11GLCapabilities extends GLCapabilities { + XVisualInfo xVisualInfo; + long fbcfg; + int fbcfgid; + + /** Comparing xvisual id only */ + public static class XVisualIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof X11GLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a X11GLCapabilities object: " + c); + } + if ( ! ( o2 instanceof X11GLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a X11GLCapabilities object: " + c); + } + + final X11GLCapabilities caps1 = (X11GLCapabilities) o1; + final long id1 = caps1.getXVisualID(); + + final X11GLCapabilities caps2 = (X11GLCapabilities) o2; + final long id2 = caps2.getXVisualID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, long fbcfg, int fbcfgid, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = fbcfg; + this.fbcfgid = fbcfgid; + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = 0; + this.fbcfgid = -1; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public XVisualInfo getXVisualInfo() { return xVisualInfo; } + final public long getXVisualID() { return xVisualInfo.getVisualid(); } + + final public long getFBConfig() { return fbcfg; } + final public int getFBConfigID() { return fbcfgid; } + final public boolean isFBConfig() { return 0!=fbcfg && fbcfgid>0; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append("0x").append(Long.toHexString(xVisualInfo.getVisualid())).append(" "); + if(isFBConfig()) { + sink.append("0x").append(Integer.toHexString(fbcfgid)); + } else { + sink.append("----"); + } + sink.append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index 32d70ad6b..dd25f241e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -40,11 +40,14 @@ package com.jogamp.opengl.impl.x11.glx; -import com.jogamp.common.util.VersionNumber; import java.nio.*; import java.util.*; + import javax.media.opengl.*; import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.X11GraphicsDevice; + +import com.jogamp.common.util.VersionNumber; import com.jogamp.opengl.impl.*; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -119,21 +122,23 @@ public abstract class X11GLXContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } - public final boolean isGLReadDrawableAvailable() { + public final boolean isGLXVersionGreaterEqualOneThree() { if(null == glXVersion) { X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); + X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice(); glXVersion = factory.getGLXVersion(device); - if( null != glXVersion ) { - glXVersionOneThreeCapable = glXVersion.compareTo(factory.versionOneThree)>=0; - } + glXVersionOneThreeCapable = ( null != glXVersion ) ? glXVersion.compareTo(X11GLXDrawableFactory.versionOneThree) >= 0 : false ; } return glXVersionOneThreeCapable; } + public final boolean isGLReadDrawableAvailable() { + return isGLXVersionGreaterEqualOneThree(); + } + private final boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) { boolean res = false; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 186bd5ec5..709e2ddab 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -37,7 +37,11 @@ package com.jogamp.opengl.impl.x11.glx; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; import java.nio.*; + import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; import javax.media.opengl.*; @@ -47,8 +51,6 @@ import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.nativewindow.impl.ProxySurface; import com.jogamp.nativewindow.impl.x11.*; -import java.util.Collection; -import java.util.HashMap; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @@ -70,6 +72,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } } + public static VersionNumber getGLXVersion(X11GraphicsDevice device) { + int[] major = new int[1]; + int[] minor = new int[1]; + GLXUtil.getGLXVersion(device.getHandle(), major, minor); + return new VersionNumber(major[0], minor[0], 0); + } + public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { return x11GLXDynamicLookupHelper; } @@ -125,15 +134,18 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName); isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName); } - public AbstractGraphicsDevice getDevice() { return device; } - public AbstractGraphicsScreen getScreen() { return screen; } - public GLDrawableImpl getDrawable() { return drawable; } - public GLContextImpl getContext() { return context; } - - String getGLXVendorName() { return glXVendorName; } - boolean isGLXVendorATI() { return isGLXVendorATI; } - boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } - VersionNumber getGLXVersion() { return glXVersion; } + final public AbstractGraphicsDevice getDevice() { return device; } + final public AbstractGraphicsScreen getScreen() { return screen; } + final public GLDrawableImpl getDrawable() { return drawable; } + final public GLContextImpl getContext() { return context; } + + final String getGLXVendorName() { return glXVendorName; } + final boolean isGLXVendorATI() { return isGLXVendorATI; } + final boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } + final VersionNumber getGLXVersion() { return glXVersion; } + final boolean isGLXVersionGreaterEqualOneThree() { + return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; + } } class SharedResourceImplementation implements SharedResourceRunner.Implementation { @@ -168,7 +180,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if (null == sharedScreen) { throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); } - GLProfile glp = GLProfile.getDefault(sharedDevice); + GLProfile glp = GLProfile.getMinDesktop(sharedDevice); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } @@ -181,20 +193,18 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); } sharedContext.setSynchronized(true); - VersionNumber glXVersion; + VersionNumber glXVersion = getGLXVersion(sharedDevice); + boolean madeCurrent = false; sharedContext.makeCurrent(); try { - int[] major = new int[1]; - int[] minor = new int[1]; - GLXUtil.getGLXVersion(sharedDevice.getHandle(), major, minor); - glXVersion = new VersionNumber(major[0], minor[0], 0); + madeCurrent = sharedContext.isCurrent(); } finally { sharedContext.release(); } if (DEBUG) { System.err.println("!!! SharedDevice: " + sharedDevice); System.err.println("!!! SharedScreen: " + sharedScreen); - System.err.println("!!! SharedContext: " + sharedContext); + System.err.println("!!! SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent); System.err.println("!!! GLX Vendor: " + glXVendorName); System.err.println("!!! GLX Version: " + glXVersion + " >= 1.3: " + (glXVersion.compareTo(versionOneThree) >= 0)); @@ -273,15 +283,11 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return 0; } - protected final VersionNumber getGLXVersion(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); - if(null!=sr) { - return ((SharedResource)sr).getGLXVersion(); - } - return null; + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); } - protected final String getGLXVendorName(AbstractGraphicsDevice device) { + public final String getGLXVendorName(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return ((SharedResource)sr).getGLXVendorName(); @@ -289,7 +295,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return GLXUtil.getVendorName(device.getHandle()); } - protected final boolean isGLXVendorATI(AbstractGraphicsDevice device) { + public final boolean isGLXVendorATI(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return ((SharedResource)sr).isGLXVendorATI(); @@ -297,7 +303,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return GLXUtil.isVendorATI(device.getHandle()); } - protected final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { + public final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return ((SharedResource)sr).isGLXVendorNVIDIA(); @@ -313,6 +319,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { X11Util.shutdown( false, DEBUG ); } + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); @@ -354,9 +364,16 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return pbufferDrawable; } - public final boolean glXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { - VersionNumber glXVersion = getGLXVersion(device); - return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; + public final boolean isGLXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return sr.isGLXVersionGreaterEqualOneThree(); + } + if( device instanceof X11GraphicsDevice ) { + VersionNumber v = getGLXVersion( (X11GraphicsDevice) device); + return ( null != v ) ? v.compareTo(versionOneThree) >= 0 : false ; + } + return false; } public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { @@ -366,7 +383,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { device = sr.getDevice(); } } - return glXVersionGreaterEqualOneThree(device); + return isGLXVersionGreaterEqualOneThree(device); } protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java index 3dbaab21b..f7779ab28 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -33,10 +33,13 @@ package com.jogamp.opengl.impl.x11.glx; -import com.jogamp.common.nio.PointerBuffer; +import java.util.ArrayList; + import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; import javax.media.opengl.*; + +import com.jogamp.common.nio.PointerBuffer; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.x11.*; @@ -44,17 +47,12 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public static final int MAX_ATTRIBS = 128; - private long fbConfig; - private int fbConfigID; private GLCapabilitiesChooser chooser; X11GLXGraphicsConfiguration(X11GraphicsScreen screen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, - XVisualInfo info, long fbcfg, int fbcfgID) { - super(screen, capsChosen, capsRequested, info); + X11GLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + super(screen, capsChosen, capsRequested, capsChosen.getXVisualInfo()); this.chooser=chooser; - fbConfig = fbcfg; - fbConfigID = fbcfgID; } static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) { @@ -70,23 +68,23 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem if(null==glp) { glp = GLProfile.getDefault(x11Screen.getDevice()); } - GLCapabilitiesImmutable caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); if(null==caps) { throw new GLException("GLCapabilities null of "+toHexString(fbcfg)); } - XVisualInfo xvi = GLX.glXGetVisualFromFBConfig(display, fbcfg); - if(null==xvi) { - throw new GLException("XVisualInfo null of "+toHexString(fbcfg)); - } - return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID); + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); } public Object clone() { return super.clone(); } - public long getFBConfig() { return fbConfig; } - public int getFBConfigID() { return fbConfigID; } + public final long getFBConfig() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfig(); + } + public final int getFBConfigID() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfigID(); + } void updateGraphicsConfiguration() { X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration) @@ -96,8 +94,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem // FIXME: setScreen( ... ); setXVisualInfo(newConfig.getXVisualInfo()); setChosenCapabilities(newConfig.getChosenCapabilities()); - fbConfig = newConfig.getFBConfig(); - fbConfigID = newConfig.getFBConfigID(); if(DEBUG) { System.err.println("!!! updateGraphicsConfiguration: "+this); } @@ -220,49 +216,63 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return true; } - static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static int FBCfgDrawableTypeBits(final long display, final long fbcfg) { + int val = 0; - if ( onscreen ) { - res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ; - } - } + int[] tmp = new int[1]; + int fbtype = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); - return res; + if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } + return val; } - static GLCapabilitiesImmutable GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, + static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, boolean relaxed, boolean onscreen, boolean usePBuffer, boolean isMultisampleAvailable) { - int[] tmp = new int[1]; - int val; - val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0); - if (val != GLX.GLX_RGBA_BIT) { - if(DEBUG) { - System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val)); - } - return null; + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, winattrmask, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); + } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); } - GLCapabilities res = new GLCapabilities(glp); - - val = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); - if(GLXFBConfigDrawableTypeVerify(val, onscreen, usePBuffer)) { - res.setOnscreen(onscreen); - res.setPBuffer(usePBuffer); - } else if(relaxed) { - res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) ); - res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) ); - } else { + return null; + } + + static boolean GLXFBConfig2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, long fbcfg, + int winattrmask, boolean isMultisampleAvailable) { + final int allDrawableTypeBits = FBCfgDrawableTypeBits(display, fbcfg); + int drawableTypeBits = winattrmask & allDrawableTypeBits; + + int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); + XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); + if(null == visualInfo) { if(DEBUG) { - System.err.println("FBConfig ("+toHexString(fbcfg)+") GLX_DRAWABLE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val & GLX.GLX_WINDOW_BIT) )+", pbuffer "+( 0 != (val & GLX.GLX_PBUFFER_BIT) )+", pixmap "+( 0 != (val & GLX.GLX_PIXMAP_BIT) )+")"); + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid)); } - return null; + // onscreen must have an XVisualInfo + drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT; } + + if( 0 == drawableTypeBits ) { + return false; + } + + int[] tmp = new int[1]; + if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) { + return false; + } + + GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp); res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0); res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG); @@ -297,7 +307,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem try { res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); } catch (Exception e) {} - return res; + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } private static String glXGetFBConfigErrorCode(int err) { @@ -352,26 +363,34 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return res; } - static GLCapabilitiesImmutable XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, - boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) { + static boolean XVisualInfo2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, XVisualInfo info, + final int winattrmask, boolean isMultisampleEnabled) { + final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ; + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + int[] tmp = new int[1]; int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); if (val == 0) { if(DEBUG) { System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL"); } - return null; + return false; } val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0); if (val == 0) { if(DEBUG) { System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA"); } - return null; + return false; } - GLCapabilities res = new GLCapabilities(glp); - res.setOnscreen (onscreen); - res.setPBuffer (usePBuffer); + + GLCapabilities res = new X11GLCapabilities(info, glp); + res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0); // Note: use of hardware acceleration is determined by @@ -393,7 +412,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); } - return res; + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits); } private static String glXGetConfigErrorCode(int err) { @@ -417,16 +437,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return tmp[tmp_offset]; } - static String toHexString(int val) { - return "0x"+Integer.toHexString(val); - } - - static String toHexString(long val) { - return "0x"+Long.toHexString(val); - } - public String toString() { - return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) + + return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(getFBConfigID()) + ",\n\trequested " + getRequestedCapabilities()+ ",\n\tchosen " + getChosenCapabilities()+ "]"; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 88ed852d5..b391dc948 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -39,12 +39,13 @@ import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.x11.X11GraphicsScreen; +import javax.media.nativewindow.x11.X11GraphicsDevice; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; @@ -53,7 +54,12 @@ import com.jogamp.nativewindow.impl.x11.X11Lib; import com.jogamp.nativewindow.impl.x11.X11Util; import com.jogamp.nativewindow.impl.x11.XVisualInfo; import com.jogamp.opengl.impl.Debug; -import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** Subclass of GraphicsConfigurationFactory used when non-AWT toolkits @@ -61,8 +67,9 @@ import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + static X11GLCapabilities.XVisualIDComparator XVisualIDComparator = new X11GLCapabilities.XVisualIDComparator(); X11GLXGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this); @@ -89,6 +96,86 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF (GLCapabilitiesChooser)chooser, (X11GraphicsScreen)absScreen); } + protected static List/*<X11GLCapabilities>*/ getAvailableCapabilities(X11GLXDrawableFactory factory, AbstractGraphicsDevice device) { + X11GLXDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen(); + X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable(); + GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + GLProfile glp = capsChosen.getGLProfile(); + + List/*GLCapabilitiesImmutable*/ availableCaps = null; + + if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { + availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp); + } + if( null == availableCaps || 0 == availableCaps.size() ) { + availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp); + } + if( null != availableCaps ) { + Collections.sort(availableCaps, XVisualIDComparator); + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesFBConfig(X11GraphicsScreen x11Screen, GLProfile glProfile) { + PointerBuffer fbcfgsL = null; + + // Utilizing FBConfig + // + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] count = { -1 }; + ArrayList availableCaps = new ArrayList(); + + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<=0) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); + } + return null; + } + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile) { + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setScreen(screen); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + ArrayList availableCaps = new ArrayList(); + for (int i = 0; i < infos.length; i++) { + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } + } + return availableCaps; + } + + static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, @@ -100,18 +187,16 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF if (capsChosen == null) { capsChosen = new GLCapabilities(null); } + X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice(); + X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory(); - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } - + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device) ); boolean usePBuffer = capsChosen.isPBuffer(); - X11GLXGraphicsConfiguration res; - res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); + X11GLXGraphicsConfiguration res = null; + if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { + res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); + } if(null==res) { if(usePBuffer) { throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+capsChosen); @@ -139,14 +224,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } return null; } - XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); - if (visualInfo==null) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+toHexString(fbcfg)+")"); - return null; - } - GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); - return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), visualInfo, fbcfg, fbID); - + X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); } private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilitiesImmutable capsChosen, @@ -155,10 +234,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF X11GraphicsScreen x11Screen) { long recommendedFBConfig = -1; int recommendedIndex = -1; - int retFBID=-1; - GLCapabilitiesImmutable[] availableCaps = null; PointerBuffer fbcfgsL = null; - XVisualInfo retXVisualInfo = null; GLProfile glProfile = capsChosen.getGLProfile(); boolean onscreen = capsChosen.isOnscreen(); boolean usePBuffer = capsChosen.isPBuffer(); @@ -172,39 +248,39 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen); int[] count = { -1 }; + ArrayList/*<X11GLCapabilities>*/ availableCaps = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); if (fbcfgsL != null && fbcfgsL.limit()>0) { - availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } - } else { - availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); } } - if(availableCaps[0]!=null) { + if(availableCaps.size() > 0) { recommendedFBConfig = fbcfgsL.get(0); recommendedIndex=0; if (DEBUG) { System.err.println("!!! glXChooseFBConfig recommended fbcfg " + toHexString(recommendedFBConfig) + ", idx " + recommendedIndex); System.err.println("!!! user caps " + capsChosen); - System.err.println("!!! fbcfg caps " + availableCaps[recommendedIndex]); - } - } else { - if (DEBUG) { - System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(recommendedFBConfig)); - System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); } + } else if (DEBUG) { + System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0))); + System.err.println("!!! user caps " + capsChosen); } } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available - if(null == availableCaps) { + if( 0 == availableCaps.size() ) { + // reset .. + recommendedFBConfig = -1; + recommendedIndex = -1; + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<=0) { if(DEBUG) { @@ -213,19 +289,14 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF return null; } - availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } - } else { - availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); } } } - int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if ( 0 > chosenIndex ) { if (DEBUG) { @@ -233,20 +304,9 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } return null; } - retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosenIndex)); + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); - retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosenIndex)); - if (retXVisualInfo==null) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosenIndex) +" (Continue: "+(false==availableCaps[chosenIndex].isOnscreen())+"):\n\t"+availableCaps[chosenIndex]); - } - if(availableCaps[chosenIndex].isOnscreen()) { - // Onscreen drawables shall have a XVisual .. - return null; - } - } - - return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, fbcfgsL.get(chosenIndex), retFBID); + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); } private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilitiesImmutable capsChosen, @@ -257,15 +317,10 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF chooser = new DefaultGLCapabilitiesChooser(); } - // Until we have a rock-solid visual selection algorithm written - // in pure Java, we're going to provide the underlying window - // system's selection to the chooser as a hint - GLProfile glProfile = capsChosen.getGLProfile(); - boolean onscreen = capsChosen.isOnscreen(); - GLCapabilitiesImmutable[] availableCaps = null; + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */); + ArrayList availableCaps = new ArrayList(); int recommendedIndex = -1; - XVisualInfo retXVisualInfo = null; AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); @@ -273,8 +328,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen); - XVisualInfo[] infos = null; + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); if (DEBUG) { System.err.print("!!! glXChooseVisual recommended "); @@ -284,21 +339,29 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); } } + + // 2nd choice: get all GLCapabilities available, preferred recommendedIndex might be available if 1st choice was successful int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setScreen(screen); - infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null || infos.length<1) { throw new GLException("Error while enumerating available XVisualInfos"); } - availableCaps = new GLCapabilitiesImmutable[infos.length]; + for (int i = 0; i < infos.length; i++) { - availableCaps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); - // Attempt to find the visual chosenIndex by glXChooseVisual - if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { - recommendedIndex = i; + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } else { + // Attempt to find the visual chosenIndex by glXChooseVisual + if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { + recommendedIndex = availableCaps.size() - 1; + } } } + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if ( 0 > chosenIndex ) { if (DEBUG) { @@ -306,17 +369,9 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } return null; } + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); - retXVisualInfo = XVisualInfo.create(infos[chosenIndex]); - return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, 0, -1); - } - - static String toHexString(int val) { - return "0x"+Integer.toHexString(val); - } - - static String toHexString(long val) { - return "0x"+Long.toHexString(val); + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java index 51f9f53cc..898a8a658 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -44,7 +44,7 @@ import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.jawt.x11.*; import com.jogamp.nativewindow.impl.x11.*; -public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { +public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public X11AWTGLXGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java index f22e11cb7..6073a75f8 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 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 @@ -43,11 +44,9 @@ import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.util.*; import com.jogamp.opengl.util.packrect.*; import com.jogamp.opengl.util.texture.*; -import com.jogamp.opengl.util.texture.awt.*; import java.awt.AlphaComposite; import java.awt.Color; -import java.awt.Composite; // For debugging purposes import java.awt.EventQueue; @@ -71,7 +70,6 @@ import java.security.*; import javax.media.opengl.*; import javax.media.opengl.glu.*; -import javax.media.opengl.glu.gl2.*; import javax.media.opengl.awt.*; @@ -720,7 +718,7 @@ public class TextRenderer { // The OpenGL spec is unclear about whether this changes the // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER // binding - if (is15Available(gl)) { + if (getUseVertexArrays() && is15Available(gl)) { try { gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); } catch (Exception e) { @@ -1236,7 +1234,7 @@ public class TextRenderer { // The OpenGL spec is unclear about whether this changes the // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER // binding - if (is15Available(gl)) { + if (getUseVertexArrays() && is15Available(gl)) { try { gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); } catch (Exception e) { @@ -1558,6 +1556,8 @@ public class TextRenderer { final int undefined = -2; FontRenderContext fontRenderContext; List/*<Glyph>*/ glyphsOutput = new ArrayList/*<Glyph>*/(); + HashMap/*<String, GlyphVector>*/fullGlyphVectorCache = new HashMap/*<String, GlyphVector>*/(); + HashMap/*<Character, GlyphMetrics>*/glyphMetricsCache = new HashMap/*<Character, GlyphMetrics>*/(); // The mapping from unicode character to font-specific glyph ID int[] unicodes2Glyphs; // The mapping from glyph ID to Glyph @@ -1573,8 +1573,13 @@ public class TextRenderer { public List/*<Glyph>*/ getGlyphs(CharSequence inString) { glyphsOutput.clear(); - iter.initFromCharSequence(inString); - GlyphVector fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + GlyphVector fullRunGlyphVector; + fullRunGlyphVector = (GlyphVector) fullGlyphVectorCache.get(inString.toString()); + if (fullRunGlyphVector == null) { + iter.initFromCharSequence(inString); + fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + fullGlyphVectorCache.put(inString.toString(), fullRunGlyphVector); + } boolean complex = (fullRunGlyphVector.getLayoutFlags() != 0); if (complex || DISABLE_GLYPH_CACHE) { // Punt to the robust version of the renderer @@ -1585,7 +1590,13 @@ public class TextRenderer { int lengthInGlyphs = fullRunGlyphVector.getNumGlyphs(); int i = 0; while (i < lengthInGlyphs) { - Glyph glyph = getGlyph(inString, fullRunGlyphVector, i); + Character letter = CharacterCache.valueOf(inString.charAt(i)); + GlyphMetrics metrics = (GlyphMetrics) glyphMetricsCache.get(letter); + if (metrics == null) { + metrics = fullRunGlyphVector.getGlyphMetrics(i); + glyphMetricsCache.put(letter, metrics); + } + Glyph glyph = getGlyph(inString, metrics, i); if (glyph != null) { glyphsOutput.add(glyph); i++; @@ -1594,7 +1605,7 @@ public class TextRenderer { // the cache StringBuffer buf = new StringBuffer(); while (i < lengthInGlyphs && - getGlyph(inString, fullRunGlyphVector, i) == null) { + getGlyph(inString, fullRunGlyphVector.getGlyphMetrics(i), i) == null) { buf.append(inString.charAt(i++)); } glyphsOutput.add(new Glyph(buf.toString(), @@ -1645,7 +1656,7 @@ public class TextRenderer { // if the unicode or glyph ID would be out of bounds of the // glyph cache. private Glyph getGlyph(CharSequence inString, - GlyphVector fullRunGlyphVector, + GlyphMetrics glyphMetrics, int index) { char unicodeID = inString.charAt(index); @@ -1661,7 +1672,7 @@ public class TextRenderer { // Must fabricate the glyph singleUnicode[0] = unicodeID; GlyphVector gv = font.createGlyphVector(getFontRenderContext(), singleUnicode); - return getGlyph(unicodeID, gv, fullRunGlyphVector.getGlyphMetrics(index)); + return getGlyph(unicodeID, gv, glyphMetrics); } // It's unclear whether this variant might produce less @@ -1698,6 +1709,26 @@ public class TextRenderer { return glyph; } } + + private static class CharacterCache { + private CharacterCache() { + } + + static final Character cache[] = new Character[127 + 1]; + + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new Character((char) i); + } + } + + public static Character valueOf(char c) { + if (c <= 127) { // must cache + return CharacterCache.cache[c]; + } + return new Character(c); + } + } class Pipelined_QuadRenderer { int mOutstandingGlyphsVerticesPipeline = 0; @@ -1712,7 +1743,7 @@ public class TextRenderer { mVertCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsVerts); mTexCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsTex); - usingVBOs = is15Available(gl); + usingVBOs = getUseVertexArrays() && is15Available(gl); if (usingVBOs) { try { @@ -1918,7 +1949,7 @@ public class TextRenderer { * rendering, or whether text is rendered using the OpenGL * immediate mode commands. Defaults to true. */ - public boolean getUseVertexArrays() { + public final boolean getUseVertexArrays() { return useVertexArrays; } @@ -1943,7 +1974,7 @@ public class TextRenderer { return smoothing; } - private boolean is15Available(GL gl) { + private final boolean is15Available(GL gl) { if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) { isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5"); checkFor_isExtensionAvailable_GL_VERSION_1_5 = true; diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java index bc5aa517e..86dca59f4 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 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 @@ -47,10 +48,8 @@ import java.awt.Rectangle; import java.awt.image.*; import javax.media.opengl.*; -import javax.media.opengl.glu.*; import javax.media.opengl.glu.gl2.*; import com.jogamp.opengl.util.texture.*; -import com.jogamp.opengl.util.texture.spi.*; import com.jogamp.opengl.util.texture.awt.*; /** Provides the ability to render into an OpenGL {@link diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java index 695fad5a9..ecba18147 100644 --- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java +++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java @@ -42,6 +42,7 @@ package javax.media.opengl; import javax.media.nativewindow.NativeWindowException; import com.jogamp.opengl.impl.Debug; +import java.util.List; import javax.media.nativewindow.CapabilitiesImmutable; /** <P> The default implementation of the {@link @@ -85,38 +86,40 @@ import javax.media.nativewindow.CapabilitiesImmutable; public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { private static final boolean DEBUG = Debug.debug("CapabilitiesChooser"); - public int chooseCapabilities(CapabilitiesImmutable desired, - CapabilitiesImmutable[] available, - int windowSystemRecommendedChoice) { - GLCapabilitiesImmutable _desired = (GLCapabilitiesImmutable) desired; - GLCapabilitiesImmutable[] _available = (GLCapabilitiesImmutable[]) available; - int availnum = 0; - - for (int i = 0; i < _available.length; i++) { - if(null != _available[i]) { availnum++; } + public int chooseCapabilities(final CapabilitiesImmutable desired, + final List /*<CapabilitiesImmutable>*/ available, + final int windowSystemRecommendedChoice) { + if ( null == desired ) { + throw new NativeWindowException("Null desired capabilities"); + } + if ( 0 == available.size() ) { + throw new NativeWindowException("Empty available capabilities"); } + final GLCapabilitiesImmutable gldes = (GLCapabilitiesImmutable) desired; + final int availnum = available.size(); + if (DEBUG) { - System.err.println("Desired: " + _desired); - System.err.println("Available: Valid " + availnum + "/" + _available.length); - for (int i = 0; i < _available.length; i++) { - System.err.println(i + ": " + _available[i]); + System.err.println("Desired: " + gldes); + System.err.println("Available: " + availnum); + for (int i = 0; i < available.size(); i++) { + System.err.println(i + ": " + available.get(i)); } System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice); } if (windowSystemRecommendedChoice >= 0 && - windowSystemRecommendedChoice < _available.length && - _available[windowSystemRecommendedChoice] != null) { + windowSystemRecommendedChoice < availnum && + null != available.get(windowSystemRecommendedChoice)) { if (DEBUG) { System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice); - System.err.println(_available[windowSystemRecommendedChoice]); + System.err.println(available.get(windowSystemRecommendedChoice)); } return windowSystemRecommendedChoice; } // Create score array - int[] scores = new int[_available.length]; + int[] scores = new int[availnum]; int NO_SCORE = -9999999; int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000; int STENCIL_MISMATCH_PENALTY = 500; @@ -131,18 +134,18 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { scores[i] = NO_SCORE; } // Compute score for each - for (int i = 0; i < scores.length; i++) { - GLCapabilitiesImmutable cur = _available[i]; + for (int i = 0; i < availnum; i++) { + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (cur == null) { continue; } - if (_desired.isOnscreen() != cur.isOnscreen()) { + if (gldes.isOnscreen() != cur.isOnscreen()) { continue; } - if (!_desired.isOnscreen() && _desired.isPBuffer() && !cur.isPBuffer()) { + if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) { continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available } - if (_desired.getStereo() != cur.getStereo()) { + if (gldes.getStereo() != cur.getStereo()) { continue; } int score = 0; @@ -150,20 +153,20 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // (Note that this decides the direction of all other penalties) score += (COLOR_MISMATCH_PENALTY_SCALE * ((cur.getRedBits() + cur.getGreenBits() + cur.getBlueBits() + cur.getAlphaBits()) - - (_desired.getRedBits() + _desired.getGreenBits() + _desired.getBlueBits() + _desired.getAlphaBits()))); + (gldes.getRedBits() + gldes.getGreenBits() + gldes.getBlueBits() + gldes.getAlphaBits()))); // Compute difference in depth buffer depth score += (DEPTH_MISMATCH_PENALTY_SCALE * sign(score) * - Math.abs(cur.getDepthBits() - _desired.getDepthBits())); + Math.abs(cur.getDepthBits() - gldes.getDepthBits())); // Compute difference in accumulation buffer depth score += (ACCUM_MISMATCH_PENALTY_SCALE * sign(score) * Math.abs((cur.getAccumRedBits() + cur.getAccumGreenBits() + cur.getAccumBlueBits() + cur.getAccumAlphaBits()) - - (_desired.getAccumRedBits() + _desired.getAccumGreenBits() + _desired.getAccumBlueBits() + _desired.getAccumAlphaBits()))); + (gldes.getAccumRedBits() + gldes.getAccumGreenBits() + gldes.getAccumBlueBits() + gldes.getAccumAlphaBits()))); // Compute difference in stencil bits - score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - _desired.getStencilBits()); - if (cur.getDoubleBuffered() != _desired.getDoubleBuffered()) { + score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - gldes.getStencilBits()); + if (cur.getDoubleBuffered() != gldes.getDoubleBuffered()) { score += sign(score) * DOUBLE_BUFFER_MISMATCH_PENALTY; } - if ((_desired.getStencilBits() > 0) && (cur.getStencilBits() == 0)) { + if ((gldes.getStencilBits() > 0) && (cur.getStencilBits() == 0)) { score += sign(score) * STENCIL_MISMATCH_PENALTY; } scores[i] = score; @@ -172,12 +175,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // non-hardware-accelerated visuals out boolean gotHW = false; int maxAbsoluteHWScore = 0; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; } - GLCapabilitiesImmutable cur = _available[i]; + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (cur.getHardwareAccelerated()) { int absScore = Math.abs(score); if (!gotHW || @@ -188,12 +191,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { } } if (gotHW) { - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; } - GLCapabilitiesImmutable cur = _available[i]; + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (!cur.getHardwareAccelerated()) { if (score <= 0) { score -= maxAbsoluteHWScore; @@ -207,7 +210,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (DEBUG) { System.err.print("Scores: ["); - for (int i = 0; i < _available.length; i++) { + for (int i = 0; i < availnum; i++) { if (i > 0) { System.err.print(","); } @@ -219,7 +222,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // Ready to select. Choose score closest to 0. int scoreClosestToZero = NO_SCORE; int chosenIndex = -1; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; @@ -238,7 +241,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (DEBUG) { System.err.println("Chosen index: " + chosenIndex); System.err.println("Chosen capabilities:"); - System.err.println(_available[chosenIndex]); + System.err.println(available.get(chosenIndex)); } return chosenIndex; @@ -250,4 +253,5 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { } return 1; } + } diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java index 82f83dc82..1ae9e40aa 100644 --- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java +++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java @@ -143,6 +143,56 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return res; } + /** comparing hw/sw, stereo, multisample, stencil, RGBA and depth only */ + public int compareTo(Object o) { + if ( ! ( o instanceof GLCapabilities ) ) { + Class c = (null != o) ? o.getClass() : null ; + throw new ClassCastException("Not a GLCapabilities object: " + c); + } + + final GLCapabilities caps = (GLCapabilities) o; + + if(hardwareAccelerated && !caps.hardwareAccelerated) { + return 1; + } else if(!hardwareAccelerated && caps.hardwareAccelerated) { + return -1; + } + + if(stereo && !caps.stereo) { + return 1; + } else if(!stereo && caps.stereo) { + return -1; + } + + final int ms = sampleBuffers ? numSamples : 0; + final int xms = caps.sampleBuffers ? caps.numSamples : 0; + + if(ms > xms) { + return 1; + } else if( ms < xms ) { + return -1; + } + + if(stencilBits > caps.stencilBits) { + return 1; + } else if(stencilBits < caps.stencilBits) { + return -1; + } + + final int sc = super.compareTo(caps); // RGBA + if(0 != sc) { + return sc; + } + + if(depthBits > caps.depthBits) { + return 1; + } else if(depthBits < caps.depthBits) { + return -1; + } + + return 0; // they are equal: hw/sw, stereo, multisample, stencil, RGBA and depth + } + /** Returns the GL profile you desire or used by the drawable. */ public GLProfile getGLProfile() { return glProfile; @@ -158,11 +208,30 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return pbuffer; } - /** Enables or disables pbuffer usage. */ + /** + * Enables or disables pbuffer usage.<br> + * If enabled, onscreen := false. + * Defaults to false. + */ public void setPBuffer(boolean onOrOff) { + if(onOrOff) { + setOnscreen(false); + } pbuffer = onOrOff; } + /** + * Sets whether the drawable surface supports onscreen.<br> + * If enabled, pbuffer := false.<br> + * Defaults to true. + */ + public void setOnscreen(boolean onscreen) { + if(onscreen) { + setPBuffer(false); + } + super.setOnscreen(onscreen); + } + /** Indicates whether double-buffering is enabled. */ public boolean getDoubleBuffered() { return doubleBuffered; @@ -340,28 +409,54 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return pbufferRenderToTextureRectangle; } + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + + int samples = sampleBuffers ? numSamples : 0 ; + + super.toString(sink); + + sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits); + sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples); + if(doubleBuffered) { + sink.append(", dbl"); + } else { + sink.append(", one"); + } + if(stereo) { + sink.append(", stereo"); + } else { + sink.append(", mono "); + } + if(hardwareAccelerated) { + sink.append(", hw, "); + } else { + sink.append(", sw, "); + } + sink.append(glProfile); + if(!isOnscreen()) { + if(pbuffer) { + sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0) + .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0) + .append(", float ").append(pbufferFloatingPointBuffers?1:0) + .append("]"); + } else { + sink.append(", pixmap"); + } + } + + return sink; + } + /** Returns a textual representation of this GLCapabilities object. */ public String toString() { StringBuffer msg = new StringBuffer(); - msg.append("GLCapabilities["); - msg.append(super.toString()); - msg.append(", GL profile: " + glProfile + - ", PBuffer: " + pbuffer + - ", DoubleBuffered: " + doubleBuffered + - ", Stereo: " + stereo + - ", HardwareAccelerated: " + hardwareAccelerated + - ", DepthBits: " + depthBits + - ", StencilBits: " + stencilBits + - ", Red Accum: " + accumRedBits + - ", Green Accum: " + accumGreenBits + - ", Blue Accum: " + accumBlueBits + - ", Alpha Accum: " + accumAlphaBits + - ", Multisample: " + sampleBuffers + - ", Num samples: "+(sampleBuffers ? numSamples : 0)); - msg.append(", PBuffer-FloatingPointBuffers: "+pbufferFloatingPointBuffers+ - ", PBuffer-RenderToTexture: "+pbufferRenderToTexture+ - ", PBuffer-RenderToTextureRectangle: "+pbufferRenderToTextureRectangle+ "]"); + msg.append("GLCaps["); + toString(msg); + msg.append("]"); return msg.toString(); } } diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 8c06acfd6..4c9b737d5 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -40,10 +40,10 @@ package javax.media.opengl; -import com.jogamp.opengl.impl.Debug; import java.util.HashMap; import java.util.HashSet; import javax.media.nativewindow.AbstractGraphicsDevice; +import com.jogamp.opengl.impl.Debug; /** Abstraction for an OpenGL rendering context. In order to perform OpenGL rendering, a context must be "made current" on the current diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index fe591c9fc..500173cf2 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -40,13 +40,14 @@ package javax.media.opengl; -import com.jogamp.common.JogampRuntimeException; -import com.jogamp.common.impl.Debug; -import com.jogamp.common.util.ReflectionUtil; - import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; +import java.util.List; + +import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.impl.Debug; +import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; @@ -239,6 +240,24 @@ public abstract class GLDrawableFactory { */ public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device); + protected final AbstractGraphicsDevice validateDevice(AbstractGraphicsDevice device) { + if(null==device) { + device = getDefaultDevice(); + if(null==device) { + throw new InternalError("no default device"); + } + if (GLProfile.DEBUG) { + System.err.println("Info: GLDrawableFactory.validateDevice: using default device : "+device); + } + } else if( !getIsDeviceCompatible(device) ) { + if (GLProfile.DEBUG) { + System.err.println("Info: GLDrawableFactory.validateDevice: device not compatible : "+device); + } + return null; + } + return device; + } + /** * Returns true if a shared context is already mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()}, * or if a new shared context could be created and mapped. Otherwise return false.<br> @@ -258,24 +277,28 @@ public abstract class GLDrawableFactory { * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device. */ protected final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) { - if(null==device) { - device = getDefaultDevice(); - if(null==device) { - throw new InternalError("no default device"); - } - if (GLProfile.DEBUG) { - System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: using default device : "+device); - } - } else if( !getIsDeviceCompatible(device) ) { - if (GLProfile.DEBUG) { - System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: device not compatible : "+device); - } - return null; + device = validateDevice(device); + if(null!=device) { + return getOrCreateSharedContextImpl(device); } - return getOrCreateSharedContextImpl(device); + return null; } protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device); + /** + * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null + */ + public static GLDrawableFactory getDesktopFactory() { + return nativeOSFactory; + } + + /** + * Returns the sole GLDrawableFactory instance for EGL if exist or null + */ + public static GLDrawableFactory getEGLFactory() { + return eglFactory; + } + /** * Returns the sole GLDrawableFactory instance. * @@ -300,16 +323,6 @@ public abstract class GLDrawableFactory { throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+glProfileImplName); } - /** - * Returns the sole GLDrawableFactory instance. - * - * @param device AbstractGraphicsDevice to determine the factory type, ie EGLDrawableFactory, - * or one of the native GLDrawableFactory's, ie X11/GLX, Windows/WGL or MacOSX/CGL. - */ - public static GLDrawableFactory getFactory(AbstractGraphicsDevice device) throws GLException { - return getFactoryImpl(device); - } - protected static GLDrawableFactory getFactoryImpl(AbstractGraphicsDevice device) throws GLException { if(null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) { return nativeOSFactory; @@ -320,6 +333,24 @@ public abstract class GLDrawableFactory { throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+device); } + /** + * Returns an array of available GLCapabilities for the device.<br> + * The list is sorted by the native ID, ascending.<br> + * The chosen GLProfile statement in the result may not refer to the maximum available profile + * due to implementation constraints, ie using the shared resource. + * + * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device. + * @return A list of {@link javax.media.opengl.GLCapabilitiesImmutable}'s, maybe empty if none is available. + */ + public final List/*GLCapabilitiesImmutable*/ getAvailableCapabilities(AbstractGraphicsDevice device) { + device = validateDevice(device); + if(null!=device) { + return getAvailableCapabilitiesImpl(device); + } + return null; + } + protected abstract List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device); + //---------------------------------------------------------------------- // Methods to create high-level objects diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 3e1727f50..10d92b050 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -47,12 +47,13 @@ import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper; import com.jogamp.opengl.JoglVersion; -import java.util.HashMap; -import java.util.Iterator; -import java.security.*; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.fixedfunc.GLPointerFunc; import javax.media.nativewindow.NativeWindowFactory; +import java.util.HashMap; +import java.util.Iterator; +import java.security.*; +import java.util.List; /** * Specifies the the OpenGL profile. @@ -346,17 +347,35 @@ public class GLProfile { /** * All GL Profiles in the order of default detection. - * Desktop compatibility profiles (the one with fixed function pipeline) comes first. - * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! + * Desktop compatibility profiles (the one with fixed function pipeline) comes first + * from highest to lowest version. * * <ul> - * <li> GL2 - * <li> GL3bc * <li> GL4bc + * <li> GL3bc + * <li> GL2 * <li> GL2GL3 + * <li> GL4 * <li> GL3 + * <li> GL2ES2 + * <li> GLES2 + * <li> GL2ES1 + * <li> GLES1 + * </ul> + * + */ + public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL4bc, GL3bc, GL2, GL2GL3, GL4, GL3, GL2ES2, GLES2, GL2ES1, GLES1 }; + + /** + * Order of maximum profiles. + * + * <ul> + * <li> GL4bc * <li> GL4 + * <li> GL3bc + * <li> GL3 + * <li> GL2 + * <li> GL2GL3 * <li> GL2ES2 * <li> GLES2 * <li> GL2ES1 @@ -364,7 +383,21 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL2, GL3bc, GL4bc, GL2GL3, GL3, GL4, GL2ES2, GLES2, GL2ES1, GLES1 }; + public static final String[] GL_PROFILE_LIST_MAX = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3, GL2ES2, GLES2, GL2ES1, GLES1 }; + + /** + * Order of minimum original desktop profiles. + * + * <ul> + * <li> GL2 + * <li> GL3bc + * <li> GL4bc + * <li> GL3 + * <li> GL4 + * </ul> + * + */ + public static final String[] GL_PROFILE_LIST_MIN_DESKTOP = new String[] { GL2, GL3bc, GL4bc, GL3, GL4 }; /** * Order of maximum fixed function profiles @@ -394,13 +427,11 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4, GL4bc, GL3, GL3bc, GL2, GL2ES2, GLES2 }; + public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2ES2, GLES2 }; /** * All GL2ES2 Profiles in the order of default detection. * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! - * * <ul> * <li> GL2ES2 * <li> GL2 @@ -410,13 +441,11 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL2, GL3, GL4, GLES2 }; + public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL4, GL3, GL2, GLES2 }; /** * All GL2ES1 Profiles in the order of default detection. * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! - * * <ul> * <li> GL2ES1 * <li> GL2 @@ -426,7 +455,7 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL2, GL3bc, GL4bc, GLES1 }; + public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL4bc, GL3bc, GL2, GLES1 }; /** * All GLES Profiles in the order of default detection. @@ -454,7 +483,48 @@ public class GLProfile { } /** - * Returns the highest profile, implementing the fixed function pipeline + * Returns the highest profile. + * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX} + * + * @throws GLException if no implementation for the given profile is found. + * @see #GL_PROFILE_LIST_MAX + */ + public static GLProfile getMaximum(AbstractGraphicsDevice device) + throws GLException + { + return get(device, GL_PROFILE_LIST_MAX); + } + + /** Uses the default device */ + public static GLProfile getMaximum() + throws GLException + { + return get(GL_PROFILE_LIST_MAX); + } + + /** + * Returns the lowest desktop profile. + * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MIN_DESKTOP} + * + * @throws GLException if no implementation for the given profile is found. + * @see #GL_PROFILE_LIST_MIN_DESKTOP + */ + public static GLProfile getMinDesktop(AbstractGraphicsDevice device) + throws GLException + { + return get(device, GL_PROFILE_LIST_MIN_DESKTOP); + } + + /** Uses the default device */ + public static GLProfile getMinDesktop() + throws GLException + { + return get(GL_PROFILE_LIST_MIN_DESKTOP); + } + + + /** + * Returns the highest profile, implementing the fixed function pipeline. * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_FIXEDFUNC} * * @throws GLException if no implementation for the given profile is found. @@ -1301,8 +1371,16 @@ public class GLProfile { System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device)); if(addedDesktopProfile) { dumpGLInfo(desktopFactory, device); + List/*<GLCapabilitiesImmutable>*/ availCaps = desktopFactory.getAvailableCapabilities(device); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } } else if(addedEGLProfile) { dumpGLInfo(eglFactory, device); + List/*<GLCapabilitiesImmutable>*/ availCaps = eglFactory.getAvailableCapabilities(device); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } } } @@ -1314,13 +1392,10 @@ public class GLProfile { System.err.println("GLProfile.dumpGLInfo: "+ctx); ctx.makeCurrent(); try { - System.err.println("GLProfile.dumpGLInfo: p2"); System.err.println(JoglVersion.getGLInfo(ctx.getGL(), null)); - System.err.println("GLProfile.dumpGLInfo: p3"); } finally { ctx.release(); } - System.err.println("GLProfile.dumpGLInfo: p4"); } public static AbstractGraphicsDevice getDefaultDevice() { diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index d47501795..acabe58a5 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -54,9 +54,10 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.geom.Rectangle2D; -import com.jogamp.common.GlueGenVersion; -import com.jogamp.common.util.VersionUtil; -import com.jogamp.common.util.locks.RecursiveLock; +import java.awt.EventQueue; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.AbstractGraphicsConfiguration; @@ -69,7 +70,6 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration; import javax.media.nativewindow.awt.AWTGraphicsDevice; import javax.media.nativewindow.awt.AWTGraphicsScreen; import javax.media.nativewindow.awt.AWTWindowClosingProtocol; -import com.jogamp.nativewindow.NativeWindowVersion; import javax.media.opengl.GL; import javax.media.opengl.GLAnimatorControl; @@ -85,14 +85,17 @@ import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import javax.media.opengl.GLRunnable; import javax.media.opengl.Threading; + +import com.jogamp.nativewindow.NativeWindowVersion; +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.util.VersionUtil; import com.jogamp.opengl.JoglVersion; + +import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.impl.GLContextImpl; import com.jogamp.opengl.impl.GLDrawableHelper; import com.jogamp.opengl.impl.ThreadingImpl; -import java.awt.EventQueue; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; // FIXME: Subclasses need to call resetGLFunctionAvailability() on their // context whenever the displayChanged() function is called on our @@ -996,6 +999,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing System.err.println(NativeWindowVersion.getInstance()); System.err.println(JoglVersion.getInstance()); + GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory(); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } + GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) ); Frame frame = new Frame("JOGL AWT Test"); diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java index e844c4f3e..79d69c703 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java +++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java @@ -44,7 +44,7 @@ package javax.media.nativewindow; must support, such as color depth per channel. It currently contains the minimal number of routines which allow configuration on all supported window systems. */ -public class Capabilities implements CapabilitiesImmutable, Cloneable { +public class Capabilities implements CapabilitiesImmutable, Cloneable, Comparable { private int redBits = 8; private int greenBits = 8; private int blueBits = 8; @@ -114,6 +114,30 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable { return res; } + /** comparing RGBA values only */ + public int compareTo(Object o) { + if ( ! ( o instanceof Capabilities ) ) { + Class c = (null != o) ? o.getClass() : null ; + throw new ClassCastException("Not a Capabilities object: " + c); + } + + final Capabilities caps = (Capabilities) o; + + final int a = ( alphaBits > 0 ) ? alphaBits : 1; + final int rgba = redBits * greenBits * blueBits * a; + + final int xa = ( caps.alphaBits ) > 0 ? caps.alphaBits : 1; + final int xrgba = caps.redBits * caps.greenBits * caps.blueBits * xa; + + if(rgba > xrgba) { + return 1; + } else if(rgba < xrgba) { + return -1; + } + + return 0; // they are equal: RGBA + } + /** Returns the number of bits requested for the color buffer's red component. On some systems only the color depth, which is the sum of the red, green, and blue bits, is considered. */ @@ -274,25 +298,31 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable { A value of -1 is interpreted as any value. */ public void setTransparentAlphaValue(int transValueAlpha) { transparentValueAlpha=transValueAlpha; } + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + if(onscreen) { + sink.append("on-scr"); + } else { + sink.append("offscr"); + } + sink.append(", rgba ").append(redBits).append("/").append(greenBits).append("/").append(blueBits).append("/").append(alphaBits); + if(backgroundOpaque) { + sink.append(", opaque"); + } else { + sink.append(", trans-rgba 0x").append(Integer.toHexString(transparentValueRed)).append("/").append(Integer.toHexString(transparentValueGreen)).append("/").append(Integer.toHexString(transparentValueBlue)).append("/").append(Integer.toHexString(transparentValueAlpha)); + } + return sink; + } /** Returns a textual representation of this Capabilities object. */ public String toString() { StringBuffer msg = new StringBuffer(); - msg.append("Capabilities["); - msg.append("Onscreen: "+ onscreen + - ", Red: " + redBits + - ", Green: " + greenBits + - ", Blue: " + blueBits + - ", Alpha: " + alphaBits + - ", Opaque: " + backgroundOpaque); - if(!backgroundOpaque) { - msg.append(", Transparent RGBA: [0x"+ Integer.toHexString(transparentValueRed)+ - " 0x"+ Integer.toHexString(transparentValueGreen)+ - " 0x"+ Integer.toHexString(transparentValueBlue)+ - " 0x"+ Integer.toHexString(transparentValueAlpha)+"] "); - } - msg.append("]"); + msg.append("Caps["); + toString(msg); + msg.append("]"); return msg.toString(); } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java index 94b0f68af..a306363dc 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java +++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java @@ -39,6 +39,8 @@ package javax.media.nativewindow; +import java.util.List; + /** Provides a mechanism by which applications can customize the window type selection for a given {@link Capabilities}. Developers can implement this interface and pass an instance into @@ -63,6 +65,6 @@ public interface CapabilitiesChooser { choice to some other CapabilitiesChooser object. */ public int chooseCapabilities(CapabilitiesImmutable desired, - CapabilitiesImmutable[] available, + List /*<CapabilitiesImmutable>*/ available, int windowSystemRecommendedChoice); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java index 72828b9f0..3aae8c8fb 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java +++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java @@ -109,6 +109,9 @@ public interface CapabilitiesImmutable extends WriteCloneable { /** hash code over the immutable attributes of both objects */ int hashCode(); + /** Return a textual representation of this object. Use the given StringBuffer [optional]. */ + StringBuffer toString(StringBuffer sink); + /** Returns a textual representation of this object. */ String toString(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java index 856c29420..b43db8292 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 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 @@ -39,6 +40,8 @@ package javax.media.nativewindow; +import java.util.List; + /** <P> The default implementation of the {@link CapabilitiesChooser} interface, which provides consistent visual selection behavior across platforms. The precise algorithm is @@ -63,37 +66,38 @@ package javax.media.nativewindow; public class DefaultCapabilitiesChooser implements CapabilitiesChooser { private static final boolean DEBUG = false; // FIXME: Debug.debug("DefaultCapabilitiesChooser"); - public int chooseCapabilities(CapabilitiesImmutable desired, - CapabilitiesImmutable[] available, - int windowSystemRecommendedChoice) { + public int chooseCapabilities(final CapabilitiesImmutable desired, + final List /*<CapabilitiesImmutable>*/ available, + final int windowSystemRecommendedChoice) { if (DEBUG) { System.err.println("Desired: " + desired); - for (int i = 0; i < available.length; i++) { - System.err.println("Available " + i + ": " + available[i]); + for (int i = 0; i < available.size(); i++) { + System.err.println("Available " + i + ": " + available.get(i)); } System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice); } + final int availnum = available.size(); if (windowSystemRecommendedChoice >= 0 && - windowSystemRecommendedChoice < available.length && - available[windowSystemRecommendedChoice] != null) { + windowSystemRecommendedChoice < availnum && + null != available.get(windowSystemRecommendedChoice)) { if (DEBUG) { System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice); - System.err.println(available[windowSystemRecommendedChoice]); + System.err.println(available.get(windowSystemRecommendedChoice)); } return windowSystemRecommendedChoice; } // Create score array - int[] scores = new int[available.length]; + int[] scores = new int[availnum]; int NO_SCORE = -9999999; int COLOR_MISMATCH_PENALTY_SCALE = 36; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { scores[i] = NO_SCORE; } // Compute score for each - for (int i = 0; i < scores.length; i++) { - CapabilitiesImmutable cur = available[i]; + for (int i = 0; i < availnum; i++) { + CapabilitiesImmutable cur = (CapabilitiesImmutable) available.get(i); if (cur == null) { continue; } @@ -107,7 +111,7 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser { if (DEBUG) { System.err.print("Scores: ["); - for (int i = 0; i < available.length; i++) { + for (int i = 0; i < availnum; i++) { if (i > 0) { System.err.print(","); } @@ -119,7 +123,7 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser { // Ready to select. Choose score closest to 0. int scoreClosestToZero = NO_SCORE; int chosenIndex = -1; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; @@ -138,7 +142,7 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser { if (DEBUG) { System.err.println("Chosen index: " + chosenIndex); System.err.println("Chosen capabilities:"); - System.err.println(available[chosenIndex]); + System.err.println(available.get(chosenIndex)); } return chosenIndex; diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java index 42020488c..c728c1634 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java @@ -111,4 +111,12 @@ public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphics ",\n\trequested " + capabilitiesRequested+ "]"; } + + public static String toHexString(int val) { + return "0x"+Integer.toHexString(val); + } + + public static String toHexString(long val) { + return "0x"+Long.toHexString(val); + } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java index ba047c1f6..ad1bc3634 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java @@ -68,6 +68,18 @@ public abstract class GraphicsConfigurationFactory { initialize(); } + protected static String getThreadName() { + return Thread.currentThread().getName(); + } + + protected static String toHexString(int val) { + return "0x" + Integer.toHexString(val); + } + + protected static String toHexString(long val) { + return "0x" + Long.toHexString(val); + } + /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ protected GraphicsConfigurationFactory() { diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java index 01c734702..7b5f19047 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java @@ -32,8 +32,9 @@ package javax.media.nativewindow.x11; -import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.*; + +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.nativewindow.impl.x11.XVisualInfo; /** Encapsulates a graphics configuration, or OpenGL pixel format, on diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java index 9dace822f..74186f70f 100644 --- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java @@ -34,6 +34,9 @@ package com.jogamp.newt.impl; +import java.util.ArrayList; +import java.lang.reflect.Method; + import com.jogamp.common.util.ReflectionUtil; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Display; @@ -52,8 +55,6 @@ import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.WindowUpdateEvent; -import java.util.ArrayList; -import java.lang.reflect.Method; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.CapabilitiesChooser; diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/opengl/VersionApplet.java b/src/newt/classes/com/jogamp/newt/impl/awt/opengl/VersionApplet.java index 7fb3268f9..f31d1bc0f 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/opengl/VersionApplet.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/opengl/VersionApplet.java @@ -1,27 +1,38 @@ package com.jogamp.newt.impl.awt.opengl; -import com.jogamp.common.GlueGenVersion; -import com.jogamp.common.util.VersionUtil; -import com.jogamp.nativewindow.NativeWindowVersion; -import com.jogamp.newt.NewtVersion; -import com.jogamp.opengl.JoglVersion; import java.applet.Applet; import java.awt.BorderLayout; +import java.awt.Container; import java.awt.Frame; +import java.awt.GridLayout; import java.awt.TextArea; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; + +import java.util.List; + import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; import javax.media.opengl.GL; import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.VersionUtil; +import com.jogamp.nativewindow.NativeWindowVersion; +import com.jogamp.newt.NewtVersion; +import com.jogamp.opengl.JoglVersion; + public class VersionApplet extends Applet { static { GLProfile.initSingleton(false); } - TextArea tarea; + TextArea tareaVersion; + TextArea tareaCaps; GLCanvas canvas; public static void main(String[] args) { @@ -60,33 +71,50 @@ public class VersionApplet extends Applet { private synchronized void my_init() { if(null != canvas) { return; } + GLProfile glp = GLProfile.getDefault(); + GLCapabilities glcaps = new GLCapabilities(glp); + setLayout(new BorderLayout()); String s; - tarea = new TextArea(120, 80); + tareaVersion = new TextArea(120, 60); s = VersionUtil.getPlatformInfo().toString(); System.err.println(s); - tarea.append(s); + tareaVersion.append(s); s = GlueGenVersion.getInstance().toString(); System.err.println(s); - tarea.append(s); + tareaVersion.append(s); s = NativeWindowVersion.getInstance().toString(); System.err.println(s); - tarea.append(NativeWindowVersion.getInstance().toString()); + tareaVersion.append(NativeWindowVersion.getInstance().toString()); s = JoglVersion.getInstance().toString(); System.err.println(s); - tarea.append(s); + tareaVersion.append(s); s = NewtVersion.getInstance().toString(); System.err.println(s); - tarea.append(s); + tareaVersion.append(s); + + tareaCaps = new TextArea(120, 20); + GLDrawableFactory factory = GLDrawableFactory.getFactory(glp); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + s = ((GLCapabilitiesImmutable) availCaps.get(i)).toString(); + System.err.println(s); + tareaCaps.append(s); + tareaCaps.append(Platform.getNewline()); + } - add(tarea, BorderLayout.CENTER); + Container grid = new Container(); + grid.setLayout(new GridLayout(2, 1)); + grid.add(tareaVersion); + grid.add(tareaCaps); + add(grid, BorderLayout.CENTER); - canvas = new GLCanvas(); + canvas = new GLCanvas(glcaps); canvas.addGLEventListener(new GLInfo()); canvas.setSize(10, 10); add(canvas, BorderLayout.SOUTH); @@ -98,8 +126,8 @@ public class VersionApplet extends Applet { remove(canvas); canvas.destroy(); canvas = null; - remove(tarea); - tarea=null; + remove(tareaVersion); + tareaVersion=null; } } @@ -130,7 +158,7 @@ public class VersionApplet extends Applet { GL gl = drawable.getGL(); String s = JoglVersion.getInstance().getGLInfo(gl, null).toString(); System.err.println(s); - tarea.append(s); + tareaVersion.append(s); } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 4a1855d05..6886fc71b 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -34,18 +34,22 @@ package com.jogamp.newt.opengl; +import java.util.List; + import com.jogamp.common.GlueGenVersion; import com.jogamp.common.util.VersionUtil; import com.jogamp.nativewindow.NativeWindowVersion; import com.jogamp.newt.*; import com.jogamp.newt.event.*; import com.jogamp.newt.impl.WindowImpl; + import javax.media.nativewindow.*; import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Insets; import javax.media.opengl.*; + import com.jogamp.opengl.impl.GLDrawableHelper; import com.jogamp.opengl.JoglVersion; -import javax.media.nativewindow.util.Insets; /** * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface, @@ -895,7 +899,14 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { System.err.println(NativeWindowVersion.getInstance()); System.err.println(JoglVersion.getInstance()); System.err.println(NewtVersion.getInstance()); - GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault() ); + + GLProfile glp = GLProfile.getDefault(); + GLDrawableFactory factory = GLDrawableFactory.getFactory(glp); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } + GLCapabilitiesImmutable caps = new GLCapabilities( glp ); GLWindow glWindow = GLWindow.create(caps); glWindow.setSize(128, 128); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java index 88caed357..d4f24bb19 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java @@ -28,21 +28,22 @@ package com.jogamp.opengl.test.junit.jogl.acore; -import com.jogamp.common.GlueGenVersion; -import com.jogamp.common.util.VersionUtil; -import com.jogamp.nativewindow.NativeWindowVersion; -import com.jogamp.opengl.test.junit.util.UITestCase; -import com.jogamp.opengl.test.junit.util.DumpGLInfo; +import java.io.IOException; +import java.util.List; import org.junit.Assert; import org.junit.Test; import javax.media.opengl.*; -import com.jogamp.newt.opengl.*; -import com.jogamp.newt.*; +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.util.VersionUtil; +import com.jogamp.nativewindow.NativeWindowVersion; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.DumpGLInfo; import com.jogamp.opengl.JoglVersion; -import java.io.IOException; +import com.jogamp.newt.opengl.*; +import com.jogamp.newt.*; public class TestGLProfile01NEWT extends UITestCase { @@ -53,20 +54,19 @@ public class TestGLProfile01NEWT extends UITestCase { System.err.println(NativeWindowVersion.getInstance()); System.err.println(JoglVersion.getInstance()); System.err.println(NewtVersion.getInstance()); + + GLDrawableFactory factory = GLDrawableFactory.getFactory(GLProfile.getDefault()); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } } @Test public void test01GLProfileDefault() throws InterruptedException { System.out.println("GLProfile "+GLProfile.glAvailabilityToString()); GLProfile glp = GLProfile.getDefault(); - dumpVersion(glp); - } - - @Test - public void test02GLProfileMaxFixedFunc() throws InterruptedException { - // Assuming at least one fixed profile is available - GLProfile glp = GLProfile.getMaxFixedFunc(); - System.out.println("GLProfile getMaxFixedFunc(): "+glp); + System.out.println("GLProfile.getDefault(): "+glp); if(glp.getName().equals(GLProfile.GL4bc)) { Assert.assertTrue(GLProfile.isGL4bcAvailable()); Assert.assertTrue(GLProfile.isGL3bcAvailable()); @@ -89,10 +89,16 @@ public class TestGLProfile01NEWT extends UITestCase { } @Test + public void test02GL2() throws InterruptedException { + GLProfile glp = GLProfile.get(GLProfile.GL2); + dumpVersion(glp); + } + + @Test public void test03GLProfileMaxProgrammable() throws InterruptedException { // Assuming at least one programmable profile is available GLProfile glp = GLProfile.getMaxProgrammable(); - System.out.println("GLProfile getMaxProgrammable(): "+glp); + System.out.println("GLProfile.getMaxProgrammable(): "+glp); if(glp.getName().equals(GLProfile.GL4)) { Assert.assertTrue(GLProfile.isGL4Available()); Assert.assertTrue(GLProfile.isGL3Available()); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java index 83561eb97..21e1a4aca 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java @@ -122,23 +122,11 @@ public class TestAWT01GLn extends UITestCase { } @Test - public void test03GLMaxFixed() throws InterruptedException { - GLProfile maxFixed = GLProfile.getMaxFixedFunc(); - System.out.println("GLProfile MaxFixed: "+maxFixed); - GLCapabilities caps = new GLCapabilities(maxFixed); - try { - runTestGL(caps); - } catch (Throwable t) { - // FIXME: - // Stop test and ignore if GL3bc and GL4bc - // currently this won't work on ATI! - if(maxFixed.equals(GLProfile.GL3bc) || - maxFixed.equals(GLProfile.GL4bc)) { - t.printStackTrace(); - Assume.assumeNoException(t); - } - // else .. serious unexpected exception - } + public void test02GL2() throws InterruptedException { + GLProfile glprofile = GLProfile.get(GLProfile.GL2); + System.out.println( "GLProfile GL2: " + glprofile ); + GLCapabilities caps = new GLCapabilities(glprofile); + runTestGL(caps); } public static void main(String args[]) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestSwingAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestSwingAWT01GLn.java index 8f642dfc9..779ad7666 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestSwingAWT01GLn.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestSwingAWT01GLn.java @@ -134,23 +134,11 @@ public class TestSwingAWT01GLn extends UITestCase { } @Test - public void test03GLMaxFixed() throws InterruptedException, InvocationTargetException { - GLProfile maxFixed = GLProfile.getMaxFixedFunc(); - System.out.println("GLProfile MaxFixed: "+maxFixed); - GLCapabilities caps = new GLCapabilities(maxFixed); - try { - runTestGL(caps); - } catch (Throwable t) { - // FIXME: - // Stop test and ignore if GL3bc and GL4bc - // currently this won't work on ATI! - if(maxFixed.getName().equals(GLProfile.GL3bc) || - maxFixed.getName().equals(GLProfile.GL4bc)) { - t.printStackTrace(); - assumeNoException(t); - } - // else .. serious unexpected exception - } + public void test02GL2() throws InterruptedException, InvocationTargetException { + GLProfile glprofile = GLProfile.get(GLProfile.GL2); + System.out.println( "GLProfile GL2: " + glprofile ); + GLCapabilities caps = new GLCapabilities(glprofile); + runTestGL(caps); } public static void main(String args[]) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TestAWTTextRendererUseVertexArrayBug464.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TestAWTTextRendererUseVertexArrayBug464.java new file mode 100644 index 000000000..fc19a6842 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TestAWTTextRendererUseVertexArrayBug464.java @@ -0,0 +1,155 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.awt.text; + +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.awt.GLCanvas; +import com.jogamp.opengl.util.Animator; + +import com.jogamp.opengl.test.junit.util.UITestCase; + +import java.awt.Frame; +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.Test; + +/* + * Unit tests for Bug464 + * Some ATI-Drivers crash the JVM if VBO-related glFunctions are called. This test checks + * if TextRenderer calls any of these functions while it's useVertexArray variable is set + * to false. + * 2D- and 3D-TextRendering is tested by creating a GLCanvas showing a simple line of text + * while filtering all glFunction calls by using a modified version of TraceGL2. + * VBO-related function are logged to the disallowedMethodCalls String of the GLEventListener + * instead of being executed (to prevent JVM crashes). Therefore, if the + * disallowedMethodCalls isn't an empty String after the test, the test fails. + * + * Other classes related to this test: + * TestTextRendererGLEventListener01 + * TestTextRendererTraceGL2Mock01 + */ + +public class TestAWTTextRendererUseVertexArrayBug464 extends UITestCase { + static GLProfile glp; + static GLCapabilities caps; + + private GLCanvas glCanvas; + private Frame frame; + + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(true); + glp = GLProfile.get(GLProfile.GL2); + Assert.assertNotNull(glp); + caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + } + + @Before + public void initTest() { + glCanvas = new GLCanvas(caps); + + frame = new Frame("TextRenderer Test"); + Assert.assertNotNull(frame); + frame.add(glCanvas); + frame.setSize(512, 512); + frame.setVisible(true); + + } + + @After + public void cleanupTest() { + frame.setVisible(false); + frame.remove(glCanvas); + glCanvas=null; + Assert.assertNotNull(frame); + frame.dispose(); + frame=null; + } + + @Test + public void testTextRendererDraw2D() throws InterruptedException { + + TextRendererGLEventListener01 listener = new TextRendererGLEventListener01(1); + Assert.assertNotNull(listener); + glCanvas.addGLEventListener(listener); + Animator animator = new Animator(glCanvas); + + animator.start(); + + Thread.sleep(500); // 500 ms + + animator.stop(); + + String disallowedMethods = listener.getDisallowedMethodCalls(); + if (!disallowedMethods.equals("")) { + Assert.fail("Following VBO-related glMethods have been called: "+ disallowedMethods); + } + } + + @Test + public void testTextRendererDraw3D() throws InterruptedException { + + TextRendererGLEventListener01 listener = new TextRendererGLEventListener01(2); + Assert.assertNotNull(listener); + glCanvas.addGLEventListener(listener); + Animator animator = new Animator(glCanvas); + + animator.start(); + + Thread.sleep(500); // 500 ms + + animator.stop(); + + String disallowedMethods = listener.getDisallowedMethodCalls(); + if (!disallowedMethods.equals("")) { + Assert.fail("Following VBO-related glMethods have been called: "+ disallowedMethods); + } + } + + public static void main(String args[]) throws IOException { + String tstname = TestAWTTextRendererUseVertexArrayBug464.class.getName(); + org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { + tstname, + "filtertrace=true", + "haltOnError=false", + "haltOnFailure=false", + "showoutput=true", + "outputtoformatters=true", + "logfailedtests=true", + "logtestlistenerevents=true", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererGLEventListener01.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererGLEventListener01.java new file mode 100644 index 000000000..b14704142 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererGLEventListener01.java @@ -0,0 +1,124 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.awt.text; + +import java.awt.Font; +import java.io.OutputStream; +import java.io.PrintStream; + +import com.jogamp.opengl.util.awt.TextRenderer; +import javax.media.opengl.GL2ES1; +import javax.media.opengl.GL2; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.glu.GLU; + +import org.junit.Assert; + +/* + * Unit tests for Bug464 + * GLEventListener for unit test TestAWTTextRendererUseVertexArrayBug464. The display + * method renders the String "ABC123#+?" to the lower left corner of the canvas. + * + * The testNumber variable is used to switch between 2D- and 3D-textrendering in the display + * method. + * The disallowedMethodCalls variable is used to log VBO-related glFunction calls during + * the execution of the test. + * + * Other classes related to this test: + * TestAWTTextRendererUseVertexArrayBug464 + * TextRendererTraceGL2Mock01 + */ + +public class TextRendererGLEventListener01 implements GLEventListener { + private GLU glu = new GLU(); + private TextRenderer renderer; + private String text; + private String disallowedMethodCalls; + private int testNumber; + + public TextRendererGLEventListener01(int testNumber) { + this.disallowedMethodCalls = ""; + this.testNumber = testNumber; + } + + public void init(GLAutoDrawable drawable) { + renderer = new TextRenderer(new Font("SansSerif", Font.BOLD, 36)); + renderer.setUseVertexArrays(false); + Assert.assertNotNull(renderer); + Assert.assertFalse(renderer.getUseVertexArrays()); + + text = "ABC123#+?"; + + PrintStream nullStream = new PrintStream(new OutputStream(){ public void write(int b){}}); + drawable.setGL(new TextRendererTraceGL2Mock01(drawable.getGL().getGL2(), nullStream, this)); + } + + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + GL2 gl = drawable.getGL().getGL2(); + gl.glMatrixMode(GL2ES1.GL_PROJECTION); + gl.glLoadIdentity(); + glu.gluOrtho2D(0, 1, 0, 1); + gl.glMatrixMode(GL2ES1.GL_MODELVIEW); + gl.glLoadIdentity(); + } + + public void dispose(GLAutoDrawable drawable) { + renderer.dispose(); + } + + public void display(GLAutoDrawable drawable) { + if (disallowedMethodCalls.equals("")) { + if (testNumber == 1) { + renderer.beginRendering(drawable.getWidth(), drawable.getHeight()); + renderer.setColor(1.0f, 1.0f, 1.0f, 1.0f); + renderer.draw(text, 0, 0); + renderer.endRendering(); + } + if (testNumber == 2) { + renderer.begin3DRendering(); + renderer.setColor(1.0f, 1.0f, 1.0f, 1.0f); + renderer.draw3D(text, 0, 0, 0, 0.002f); + renderer.end3DRendering(); + } + } + } + + public void disallowedMethodCalled (String method) { + if (!disallowedMethodCalls.equals("")) { + disallowedMethodCalls += ", "; + } + disallowedMethodCalls += method; + } + + public String getDisallowedMethodCalls() { + return this.disallowedMethodCalls; + } +} + diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererTraceGL2Mock01.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererTraceGL2Mock01.java new file mode 100644 index 000000000..63258a574 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererTraceGL2Mock01.java @@ -0,0 +1,137 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.awt.text; + +import java.io.PrintStream; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +import javax.media.opengl.GL2; +import javax.media.opengl.TraceGL2; + +import com.jogamp.common.nio.Buffers; + +/* + * Unit tests for Bug464 + * Modified Version of TraceGL2 for unit test TestAWTTextRendererUseVertexArrayBug464. + * This class overrides all glFunctions related to VBO's according to + * http://code.google.com/p/glextensions/wiki/GL_ARB_vertex_buffer_object: + * glBindBuffer (glBindBufferARB) + * glDeleteBuffers (glDeleteBuffersARB) + * glGenBuffers (glGenBuffersARB) + * glIsBuffer (glIsBufferARB) + * glBufferData (glBufferDataARB) + * glBufferSubData (glBufferSubDataARB) + * glGetBufferSubData (glGetBufferSubDataARB) + * glMapBuffer (glMapBufferARB) + * glUnmapBuffer (glUnmapBufferARB) + * glGetBufferParameteriv (glGetBufferParameterivARB) + * glGetBufferPointerv (glGetBufferPointervARB) + * Calls to the overridden methods are logged to the disallowedMethodCalls variable of + * the GLEventListener instead of being passed to the downstreamGL object. + * + * Other classes related to this test: + * TestAWTTextRendererUseVertexArrayBug464 + * TextRendererGLEventListener01 + */ + +public class TextRendererTraceGL2Mock01 extends TraceGL2 { + + TextRendererGLEventListener01 listener; + + public TextRendererTraceGL2Mock01(GL2 downstreamGL2, PrintStream stream, TextRendererGLEventListener01 listener) { + super(downstreamGL2, stream); + this.listener = listener; + } + + @Override + public void glGetBufferSubData(int arg0, long arg1, long arg2, Buffer arg3) { + listener.disallowedMethodCalled("glGetBufferSubData"); + } + + @Override + public ByteBuffer glMapBuffer(int arg0, int arg1) { + listener.disallowedMethodCalled("glMapBuffer"); + return Buffers.newDirectByteBuffer(0); + } + + @Override + public void glGetBufferParameteriv(int arg0, int arg1, IntBuffer arg2) { + listener.disallowedMethodCalled("glGetBufferParameteriv"); + } + + @Override + public boolean glUnmapBuffer(int arg0) { + listener.disallowedMethodCalled("glUnmapBuffer"); + return false; + } + + @Override + public void glGenBuffers(int arg0, IntBuffer arg1) { + listener.disallowedMethodCalled("glGenBuffers"); + } + + @Override + public void glGenBuffers(int arg0, int[] arg1, int arg2) { + listener.disallowedMethodCalled("glGenBuffers"); + } + + @Override + public boolean glIsBuffer(int arg0) { + listener.disallowedMethodCalled("glIsBuffer"); + return false; + } + + @Override + public void glBindBuffer(int arg0, int arg1) { + listener.disallowedMethodCalled("glBindBuffer"); + } + + @Override + public void glDeleteBuffers(int arg0, int[] arg1, int arg2) { + listener.disallowedMethodCalled("glDeleteBuffers"); + } + + @Override + public void glBufferSubData(int arg0, long arg1, long arg2, Buffer arg3) { + listener.disallowedMethodCalled("glBufferSubData"); + } + + @Override + public void glGetBufferParameteriv(int arg0, int arg1, int[] arg2, int arg3) { + listener.disallowedMethodCalled("glGetBufferParameteriv"); + } + + @Override + public void glBufferData(int arg0, long arg1, Buffer arg2, int arg3) { + listener.disallowedMethodCalled("glBufferData"); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleChooser01.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleChooser01.java index 9653038d1..c2182b8b7 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleChooser01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleChooser01.java @@ -39,16 +39,17 @@ */ package com.jogamp.opengl.test.junit.jogl.caps; +import java.util.List; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; class MultisampleChooser01 extends DefaultGLCapabilitiesChooser { - public int chooseCapabilities(GLCapabilitiesImmutable desired, GLCapabilitiesImmutable[] available, int windowSystemRecommendedChoice) { + public int chooseCapabilities(GLCapabilitiesImmutable desired, List/*<GLCapabilitiesImmutable>*/ available, int windowSystemRecommendedChoice) { boolean anyHaveSampleBuffers = false; - for (int i = 0; i < available.length; i++) { - GLCapabilitiesImmutable caps = available[i]; - if (caps != null && caps.getSampleBuffers()) { + for (int i = 0; i < available.size(); i++) { + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) available.get(i); + if ( caps.getSampleBuffers() ) { anyHaveSampleBuffers = true; break; } @@ -57,7 +58,8 @@ class MultisampleChooser01 extends DefaultGLCapabilitiesChooser { if (!anyHaveSampleBuffers) { System.err.println("WARNING: antialiasing will be disabled because none of the available pixel formats had it to offer"); } else { - if (!available[selection].getSampleBuffers()) { + GLCapabilitiesImmutable selected = (GLCapabilitiesImmutable) available.get(selection); + if (!selected.getSampleBuffers()) { System.err.println("WARNING: antialiasing will be disabled because the DefaultGLCapabilitiesChooser didn't supply it"); } } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/TestGearsGLJPanelAWTBug450.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/TestGearsGLJPanelAWTBug450.java new file mode 100644 index 000000000..cd2682541 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/TestGearsGLJPanelAWTBug450.java @@ -0,0 +1,163 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + package com.jogamp.opengl.test.junit.jogl.demos.gl2.gears; + +import javax.media.opengl.*; + +import com.jogamp.opengl.util.FPSAnimator; + +import javax.media.opengl.awt.GLJPanel; +import javax.media.opengl.glu.gl2.GLUgl2; + +import com.jogamp.opengl.test.junit.util.UITestCase; +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.lang.reflect.InvocationTargetException; +import java.nio.ByteBuffer; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.AfterClass; +import org.junit.Test; + +/** + * Test for bug 450, which causes the right part of the frame to be black + * for all x >= height. + * + * Draws the Gears demo in a window that's twice as wide than it is tall, + * and checks to see if a particular pixel in the right half of the frame + * is colored. + * + * @author Wade Walker (adapted from TestGearsGLJPanelAWT) + */ +public class TestGearsGLJPanelAWTBug450 extends UITestCase { + static GLProfile glp; + static int width, height; + /** Set this if test fails. Needed because we can't throw an exception + * all the way up the stack from where we test the pixel. */ + static boolean failed; + + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(false); + glp = GLProfile.getDefault(); + Assert.assertNotNull(glp); + width = 512; + height = 256; + } + + @AfterClass + public static void releaseClass() { + } + + protected void runTestGL(GLCapabilities caps) + throws AWTException, InterruptedException, InvocationTargetException + { + JFrame frame = new JFrame("Swing GLJPanel"); + Assert.assertNotNull(frame); + + GLJPanel glJPanel = new GLJPanel(caps); + Assert.assertNotNull(glJPanel); + glJPanel.addGLEventListener(new Gears() { + @Override + public void display(GLAutoDrawable drawable) { + super.display(drawable); + // look at one pixel at the bottom of the frame, just right of + // the center line, and make sure it's not black + GL2 gl = GLUgl2.getCurrentGL2(); + ByteBuffer bytebuffer = ByteBuffer.allocateDirect( 3 ); + gl.glReadPixels( 260, 10, 1, 1, GL2.GL_BGR, GL2.GL_UNSIGNED_BYTE, bytebuffer ); + byte byte0 = bytebuffer.get( 0 ); + byte byte1 = bytebuffer.get( 1 ); + byte byte2 = bytebuffer.get( 2 ); + if( (byte0 == 0) && (byte1 == 0) && (byte2 == 0) ) + failed = true; + } + }); + + FPSAnimator animator = new FPSAnimator(glJPanel, 60); + + final JFrame _frame = frame; + final GLJPanel _glJPanel = glJPanel; + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + _frame.getContentPane().add(_glJPanel, BorderLayout.CENTER); + _frame.setSize(width, height); + _frame.setVisible(true); + } } ) ; + + animator.start(); + Assert.assertEquals(true, animator.isAnimating()); + + while(animator.isAnimating() && animator.getDuration()<duration) { + Thread.sleep(100); + } + + Assert.assertNotNull(frame); + Assert.assertNotNull(glJPanel); + Assert.assertNotNull(animator); + + animator.stop(); + Assert.assertEquals(false, animator.isAnimating()); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + _frame.setVisible(false); + _frame.getContentPane().remove(_glJPanel); + _frame.remove(_glJPanel); + _glJPanel.destroy(); + _frame.dispose(); + } } ); + + Assert.assertFalse( failed ); + } + + @Test + public void test01() + throws AWTException, InterruptedException, InvocationTargetException + { + GLCapabilities caps = new GLCapabilities(GLProfile.getDefault()); + runTestGL(caps); + } + + static long duration = 500; // ms + + public static void main(String args[]) { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + try { + duration = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } + } + } + org.junit.runner.JUnitCore.main(TestGearsGLJPanelAWTBug450.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java new file mode 100755 index 000000000..34b30f04e --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java @@ -0,0 +1,57 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.glu; + +import javax.media.opengl.glu.GLU; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Julien Gouesse + */ +public class TestGluUnprojectDoubleNOUI { + + @Test + public void test(){ + final GLU glu = new GLU(); + final int[] pickedPoint = new int[]{400,300}; + final double pickedPointDepth = 0; + final double[] sceneModelViewValues = new double[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final double[] projectionValues = new double[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final int[] viewport = new int[]{0,0,800,600}; + final double[] objCoords = new double[]{Double.NaN,Double.NaN,Double.NaN}; + glu.gluUnProject(pickedPoint[0], pickedPoint[1], pickedPointDepth, sceneModelViewValues, 0, projectionValues, 0, viewport, 0, objCoords, 0); + Assert.assertTrue(!Double.isNaN(objCoords[0])&&!Double.isNaN(objCoords[1])&&!Double.isNaN(objCoords[2])); + } + + public static void main(String args[]) { + org.junit.runner.JUnitCore.main(TestGluUnprojectDoubleNOUI.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java new file mode 100755 index 000000000..9e48a2000 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java @@ -0,0 +1,58 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.glu; + +import javax.media.opengl.glu.GLU; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Julien Gouesse + */ +public class TestGluUnprojectFloatNOUI { + + + @Test + public void test(){ + final GLU glu = new GLU(); + final int[] pickedPoint = new int[]{400,300}; + final float pickedPointDepth = 0; + final float[] sceneModelViewValues = new float[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final float[] projectionValues = new float[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final int[] viewport = new int[]{0,0,800,600}; + final float[] objCoords = new float[]{Float.NaN,Float.NaN,Float.NaN}; + glu.gluUnProject(pickedPoint[0], pickedPoint[1], pickedPointDepth, sceneModelViewValues, 0, projectionValues, 0, viewport, 0, objCoords, 0); + Assert.assertTrue(!Double.isNaN(objCoords[0])&&!Double.isNaN(objCoords[1])&&!Double.isNaN(objCoords[2])); + } + + public static void main(String args[]) { + org.junit.runner.JUnitCore.main(TestGluUnprojectFloatNOUI.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/OneTriangle.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/OneTriangle.java new file mode 100644 index 000000000..655e590a3 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/OneTriangle.java @@ -0,0 +1,71 @@ +/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.swt;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.glu.GLU;
+
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * A utility class to encapsulate drawing a single triangle for unit tests.
+ * @author Wade Walker
+ */
+public class OneTriangle {
+
+ public static void setup( GL2 gl, Rectangle rectangle ) {
+ gl.glMatrixMode( GL2.GL_PROJECTION );
+ gl.glLoadIdentity();
+
+ // coordinate system origin at lower left with width and height same as the window
+ GLU glu = new GLU();
+ glu.gluOrtho2D( 0.0f, rectangle.width, 0.0f, rectangle.height );
+
+ gl.glMatrixMode( GL2.GL_MODELVIEW );
+ gl.glLoadIdentity();
+
+ gl.glViewport( 0, 0, rectangle.width, rectangle.height );
+ }
+
+ public static void render( GL2 gl, Rectangle rectangle ) {
+ gl.glClear( GL.GL_COLOR_BUFFER_BIT );
+
+ // draw a triangle filling the window
+ gl.glLoadIdentity();
+ gl.glBegin( GL.GL_TRIANGLES );
+ gl.glColor3f( 1, 0, 0 );
+ gl.glVertex2f( 0, 0 );
+ gl.glColor3f( 0, 1, 0 );
+ gl.glVertex2f( rectangle.width, 0 );
+ gl.glColor3f( 0, 0, 1 );
+ gl.glVertex2f( rectangle.width / 2, rectangle.height );
+ gl.glEnd();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java new file mode 100644 index 000000000..94231a88d --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java @@ -0,0 +1,184 @@ +/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.swt;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLProfile;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.opengl.GLCanvas;
+import org.eclipse.swt.opengl.GLData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests that a basic SWT app can open without crashing under different GL profiles. Uses the SWT GL canvas.
+ * @author Wade Walker
+ */
+public class TestSWT01GLn extends UITestCase {
+
+ static final int duration = 250;
+
+ Display display = null;
+ Shell shell = null;
+ Composite composite = null;
+ GLCanvas glcanvas = null;
+
+ @BeforeClass
+ public static void startup() {
+ GLProfile.initSingleton( true );
+ System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
+ }
+
+ @Before
+ public void init() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.NONE );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ }
+
+ @After
+ public void release() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ Assert.assertNotNull( glcanvas );
+ try {
+ glcanvas.dispose();
+ composite.dispose();
+ shell.dispose();
+ display.dispose();
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ glcanvas = null;
+ }
+
+ protected void runTestGL( GLProfile glprofile ) throws InterruptedException {
+ GLData gldata = new GLData();
+ gldata.doubleBuffer = true;
+ // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
+ // at the wrong times (we use glClear for this instead)
+ glcanvas = new GLCanvas( composite, SWT.NO_BACKGROUND, gldata );
+ Assert.assertNotNull( glcanvas );
+ glcanvas.setCurrent();
+ final GLContext glcontext = GLDrawableFactory.getFactory( glprofile ).createExternalGLContext();
+ Assert.assertNotNull( glcontext );
+
+ // fix the viewport when the user resizes the window
+ glcanvas.addListener( SWT.Resize, new Listener() {
+ public void handleEvent( Event event ) {
+ Rectangle rectangle = glcanvas.getClientArea();
+ glcanvas.setCurrent();
+ glcontext.makeCurrent();
+ GL2 gl = glcontext.getGL().getGL2();
+ OneTriangle.setup( gl, rectangle );
+ glcontext.release();
+ }
+ });
+
+ // draw the triangle when the OS tells us that any part of the window needs drawing
+ glcanvas.addPaintListener( new PaintListener() {
+ public void paintControl( PaintEvent paintevent ) {
+ Rectangle rectangle = glcanvas.getClientArea();
+ glcanvas.setCurrent();
+ glcontext.makeCurrent();
+ GL2 gl = glcontext.getGL().getGL2();
+ OneTriangle.render( gl, rectangle );
+ glcanvas.swapBuffers();
+ glcontext.release();
+ }
+ });
+
+ shell.setText( getClass().getName() );
+ shell.setSize( 640, 480 );
+ shell.open();
+
+ long lStartTime = System.currentTimeMillis();
+ long lEndTime = lStartTime + duration;
+ try {
+ while( (System.currentTimeMillis() < lEndTime) && !glcanvas.isDisposed() ) {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+
+ @Test
+ public void test01GLDefault() throws InterruptedException {
+ GLProfile glprofile = GLProfile.getDefault();
+ System.out.println( "GLProfile Default: " + glprofile );
+ runTestGL( glprofile );
+ }
+
+ @Test
+ public void test02GL2() throws InterruptedException {
+ GLProfile glprofile = GLProfile.get(GLProfile.GL2);
+ System.out.println( "GLProfile GL2: " + glprofile );
+ runTestGL( glprofile );
+ }
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.main(TestSWT01GLn.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java new file mode 100644 index 000000000..2ab3c96ad --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java @@ -0,0 +1,184 @@ +/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.swt;
+
+import java.awt.Frame;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.awt.SWT_AWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests that a basic SWT app can open without crashing under different GL profiles. Uses the AWT GL canvas with
+ * the SWT_AWT bridge.
+ * @author Wade Walker
+ */
+public class TestSWTAWT01GLn extends UITestCase {
+
+ static final int duration = 250;
+
+ Display display = null;
+ Shell shell = null;
+ Composite composite = null;
+ Frame frame = null;
+ GLCanvas glcanvas = null;
+
+ @BeforeClass
+ public static void startup() {
+ GLProfile.initSingleton( true );
+ System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
+ }
+
+ @Before
+ public void init() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.EMBEDDED | SWT.NO_BACKGROUND );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ frame = SWT_AWT.new_Frame( composite );
+ Assert.assertNotNull( frame );
+ }
+
+ @After
+ public void release() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ Assert.assertNotNull( glcanvas );
+ try {
+ frame.setVisible( false );
+ frame.remove( glcanvas );
+ frame.dispose();
+ composite.dispose();
+ shell.dispose();
+ display.dispose();
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ frame = null;
+ glcanvas = null;
+ }
+
+ protected void runTestGL( GLProfile glprofile ) throws InterruptedException {
+ GLCapabilities glcapabilities = new GLCapabilities( glprofile );
+ glcanvas = new GLCanvas( glcapabilities );
+ Assert.assertNotNull( glcanvas );
+ frame.add( glcanvas );
+
+ glcanvas.addGLEventListener( new GLEventListener() {
+ @Override
+ public void init( GLAutoDrawable glautodrawable ) {
+ }
+
+ @Override
+ public void dispose( GLAutoDrawable glautodrawable ) {
+ }
+
+ @Override
+ public void display( GLAutoDrawable glautodrawable ) {
+ Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
+ GL2 gl = glautodrawable.getGL().getGL2();
+ OneTriangle.render( gl, rectangle );
+ }
+
+ @Override
+ public void reshape( GLAutoDrawable glautodrawable, int x, int y, int width, int height ) {
+ Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
+ GL2 gl = glautodrawable.getGL().getGL2();
+ OneTriangle.setup( gl, rectangle );
+ }
+ });
+
+ shell.setText( getClass().getName() );
+ shell.setSize( 640, 480 );
+ shell.open();
+
+ long lStartTime = System.currentTimeMillis();
+ long lEndTime = lStartTime + duration;
+ try {
+ while( (System.currentTimeMillis() < lEndTime) && !composite.isDisposed() ) {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+
+ @Test
+ public void test01GLDefault() throws InterruptedException {
+ GLProfile glprofile = GLProfile.getDefault();
+ System.out.println( "GLProfile Default: " + glprofile );
+ runTestGL( glprofile );
+ }
+
+ @Test
+ public void test02GL2() throws InterruptedException {
+ GLProfile glprofile = GLProfile.get(GLProfile.GL2);
+ System.out.println( "GLProfile GL2: " + glprofile );
+ runTestGL( glprofile );
+ }
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.main( TestSWTAWT01GLn.class.getName() );
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/texture/TestGrayTextureFromFileAWTBug417.java b/src/test/com/jogamp/opengl/test/junit/jogl/texture/TestGrayTextureFromFileAWTBug417.java new file mode 100644 index 000000000..82cd91718 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/texture/TestGrayTextureFromFileAWTBug417.java @@ -0,0 +1,143 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.texture; + +import com.jogamp.opengl.test.junit.jogl.util.texture.gl2.TextureGL2ListenerDraw1; + +import com.jogamp.opengl.test.junit.util.UITestCase; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.awt.GLCanvas; +import com.jogamp.opengl.util.texture.TextureIO; +import com.jogamp.opengl.util.Animator; + +import java.awt.Frame; + +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Assert; +import org.junit.After; +import org.junit.Assume; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Unit test for bug 417, which shows a GLException when reading a grayscale texture. + * Couldn't duplicate the failure, so it must have been fixed unknowingly sometime + * after the bug was submitted. + * @author Wade Walker + */ +public class TestGrayTextureFromFileAWTBug417 extends UITestCase { + static GLProfile glp; + static GLCapabilities caps; + InputStream textureStream; + + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(true); + glp = GLProfile.get(GLProfile.GL2GL3); + Assert.assertNotNull(glp); + caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + } + + @Before + public void initTest() { + textureStream = TestGrayTextureFromFileAWTBug417.class.getResourceAsStream( "grayscale_texture.png" ); + Assert.assertNotNull(textureStream); + } + + @After + public void cleanupTest() { + textureStream=null; + } + + @Test + public void test1() throws InterruptedException { + GLCanvas glCanvas = new GLCanvas(caps); + + Frame frame = new Frame("Texture Test"); + Assert.assertNotNull(frame); + frame.add(glCanvas); + frame.setSize( 256, 128 ); + + // load texture from file inside current GL context to match the way + // the bug submitter was doing it + glCanvas.addGLEventListener(new TextureGL2ListenerDraw1( null ) { + @Override + public void init(GLAutoDrawable drawable) { + try { + setTexture( TextureIO.newTexture( textureStream, true, TextureIO.PNG ) ); + } + catch(GLException glexception) { + glexception.printStackTrace(); + Assume.assumeNoException(glexception); + } + catch(IOException ioexception) { + ioexception.printStackTrace(); + Assume.assumeNoException(ioexception); + } + } + }); + + Animator animator = new Animator(glCanvas); + frame.setVisible(true); + animator.start(); + + Thread.sleep(500); // 500 ms + + animator.stop(); + frame.setVisible(false); + frame.remove(glCanvas); + glCanvas=null; + Assert.assertNotNull(frame); + frame.dispose(); + frame=null; + } + + public static void main(String args[]) throws IOException { + String tstname = TestGrayTextureFromFileAWTBug417.class.getName(); + org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { + tstname, + "filtertrace=true", + "haltOnError=false", + "haltOnFailure=false", + "showoutput=true", + "outputtoformatters=true", + "logfailedtests=true", + "logtestlistenerevents=true", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/texture/grayscale_texture.png b/src/test/com/jogamp/opengl/test/junit/jogl/texture/grayscale_texture.png Binary files differnew file mode 100755 index 000000000..dac0f13de --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/texture/grayscale_texture.png diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java index b41dde645..649a3b19a 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java @@ -32,7 +32,6 @@ import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.TextureCoords; import com.jogamp.opengl.util.texture.TextureData; import com.jogamp.opengl.util.texture.TextureIO; -import javax.media.opengl.GL; import javax.media.opengl.GL2ES1; import javax.media.opengl.GL2; import javax.media.opengl.GLAutoDrawable; @@ -54,6 +53,10 @@ public class TextureGL2ListenerDraw1 implements GLEventListener { } } + public void setTexture( Texture texture ) { + this.texture = texture; + } + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL2 gl = drawable.getGL().getGL2(); gl.glMatrixMode(GL2ES1.GL_PROJECTION); |