diff options
6 files changed, 144 insertions, 54 deletions
diff --git a/make/build.xml b/make/build.xml index 1f251e82d..11269dd84 100644 --- a/make/build.xml +++ b/make/build.xml @@ -143,9 +143,6 @@ <property name="src.generated.java.cg" value="${src.generated}/classes/com/sun/opengl/cg" /> <property name="src.generated.c" value="${src.generated}/native/jogl" /> <property name="src.generated.c.cg" value="${src.generated}/native/jogl_cg" /> - <!-- The composable pipeline source files --> - <property name="src.generated.java.pipeline" - value="javax/media/opengl/DebugGL.java,javax/media/opengl/TraceGL.java" /> <!-- The compiler output directories. --> <property name="classes" value="${build}/classes" /> @@ -584,34 +581,27 @@ <!-- - Build and dependency rules for the composable pipeline --> - <target name="java.compile.composable.pipeline.check"> + <target name="java.generate.composable.pipeline.check"> <!-- Blow away the DebugGL.java and TraceGL.java sources if GL.class has changed (the uptodate element doesn't support arbitrary source and destination files) --> <dependset> <srcfilelist dir="${classes}/javax/media/opengl" files="GL.class" /> - <srcfilelist dir="${classes}/com/sun/gluegen/opengl" files="BuildComposablePipeline.class" /> <targetfileset dir="${src.generated.java}/javax/media/opengl" includes="DebugGL.java,TraceGL.java" /> </dependset> <!-- Now choose one of the two to test to see if we have to regenerate --> - <uptodate property="java.compile.composable.pipeline.skip" + <uptodate property="java.generate.composable.pipeline.skip" srcfile="${classes}/javax/media/opengl/GL.class" targetfile="${src.generated.java}/javax/media/opengl/DebugGL.java" /> </target> - <target name="java.compile.composable.pipeline" depends="java.compile.composable.pipeline.check" unless="java.compile.composable.pipeline.skip"> - <java classname="com.sun.gluegen.opengl.BuildComposablePipeline" fork="yes" failonerror="true"> + <target name="java.generate.composable.pipeline" depends="java.generate.composable.pipeline.check" unless="java.generate.composable.pipeline.skip"> + <java classname="com.sun.gluegen.opengl.BuildComposablePipeline" fork="no" failonerror="true"> <arg value="javax.media.opengl.GL" /> <arg value="${src.generated.java}/javax/media/opengl" /> <classpath refid="pipeline.classpath" /> </java> - - <!-- Perform the second pass Java compile which compiles the composable pipelines. --> - <javac destdir="${classes}" includes="${src.generated.java.pipeline}" source="1.4" debug="true" debuglevel="source,lines"> - <src path="${src.java}" /> - <src path="${src.generated.java}" /> - </javac> </target> <!-- ================================================================== --> @@ -619,18 +609,27 @@ - Compile the original and generated source. The composable pipelines - will be generated. --> - <target name="java.compile" depends="java.generate,java.generate.cg"> + <target name="java.compile.firstpass" depends="java.generate,java.generate.cg"> <!-- Perform the first pass Java compile. --> + <javac srcdir="${src.generated.java}" + destdir="${classes}" + includes="javax/media/opengl/GL.java" + source="1.4" debug="true" debuglevel="source,lines"> + </javac> + </target> + + <target name="java.compile.secondpass" depends="java.generate.composable.pipeline"> + <!-- Perform the second pass Java compile; everything. --> <javac destdir="${classes}" excludes="${java.excludes.platform},com/sun/opengl/impl/nurbs/**" source="1.4" debug="true" debuglevel="source,lines"> <src path="${src.java}" /> <src path="${src.generated.java}" /> </javac> - - <!-- Generate and build the composable pipeline Java source. --> - <antcall target="java.compile.composable.pipeline" inheritRefs="true" /> </target> + + <target name="java.compile" depends="java.compile.firstpass,java.compile.secondpass" /> + <!-- ================================================================== --> <!-- - Compile the native C code for JOGL (and optionally the Cg binding). diff --git a/src/classes/com/sun/opengl/impl/GLContextImpl.java b/src/classes/com/sun/opengl/impl/GLContextImpl.java index 0910fe250..5f945a334 100644 --- a/src/classes/com/sun/opengl/impl/GLContextImpl.java +++ b/src/classes/com/sun/opengl/impl/GLContextImpl.java @@ -64,9 +64,16 @@ public abstract class GLContextImpl extends GLContext { protected GL gl; public GLContextImpl(GLContext shareWith) { + this(shareWith, false); + } + + public GLContextImpl(GLContext shareWith, boolean dontShareWithJava2D) { setGL(createGL()); functionAvailability = new FunctionAvailabilityCache(this); - GLContext shareContext = Java2D.filterShareContext(shareWith); + GLContext shareContext = shareWith; + if (!dontShareWithJava2D) { + shareContext = Java2D.filterShareContext(shareWith); + } if (shareContext != null) { GLContextShareSet.registerSharing(this, shareContext); } diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsDummyGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/WindowsDummyGLDrawable.java index e4d4d26d0..a307493d7 100644 --- a/src/classes/com/sun/opengl/impl/windows/WindowsDummyGLDrawable.java +++ b/src/classes/com/sun/opengl/impl/windows/WindowsDummyGLDrawable.java @@ -80,7 +80,7 @@ public class WindowsDummyGLDrawable extends WindowsGLDrawable { // Construction failed return null; } - return new WindowsGLContext(this, shareWith); + return new WindowsGLContext(this, shareWith, true); } public void destroy() { diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java b/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java index c56614599..cd51f4eb1 100755 --- a/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java +++ b/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java @@ -49,7 +49,7 @@ public class WindowsExternalGLContext extends WindowsGLContext { private boolean created = true; public WindowsExternalGLContext() { - super(null, null); + super(null, null, true); hglrc = WGL.wglGetCurrentContext(); if (hglrc == 0) { throw new GLException("Error: attempted to make an external GLContext without a drawable/context current"); diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsGLContext.java b/src/classes/com/sun/opengl/impl/windows/WindowsGLContext.java index e93c7fb3b..7a827854c 100644 --- a/src/classes/com/sun/opengl/impl/windows/WindowsGLContext.java +++ b/src/classes/com/sun/opengl/impl/windows/WindowsGLContext.java @@ -68,7 +68,13 @@ public class WindowsGLContext extends GLContextImpl { public WindowsGLContext(WindowsGLDrawable drawable, GLContext shareWith) { - super(shareWith); + this(drawable, shareWith, false); + } + + public WindowsGLContext(WindowsGLDrawable drawable, + GLContext shareWith, + boolean dontShareWithJava2D) { + super(shareWith, dontShareWithJava2D); this.drawable = drawable; } diff --git a/src/classes/javax/media/opengl/GLJPanel.java b/src/classes/javax/media/opengl/GLJPanel.java index 929975f13..6d4d1af2b 100644 --- a/src/classes/javax/media/opengl/GLJPanel.java +++ b/src/classes/javax/media/opengl/GLJPanel.java @@ -82,10 +82,6 @@ public class GLJPanel extends JPanel implements GLAutoDrawable { private static final boolean DEBUG = Debug.debug("GLJPanel"); private static final boolean VERBOSE = Debug.verbose(); - // FIXME: remove these once debugging is done - private static final boolean HACK1 = Debug.debug("GLJPanel.hack1"); - private static final boolean HACK2 = Debug.debug("GLJPanel.hack2"); - private GLDrawableHelper drawableHelper = new GLDrawableHelper(); private volatile boolean isInitialized; private volatile boolean shouldInitialize = false; @@ -168,6 +164,16 @@ public class GLJPanel extends JPanel implements GLAutoDrawable { // This is required when the FBO option of the Java2D / OpenGL // pipeline is active private int[] frameBuffer = new int[1]; + // We apparently also need to track the attachment points of the + // framebuffer + // Because it looks like this might be just a bug, controlling it + // under a flag for now + private boolean frameBufferAttachmentWorkaround = !Debug.isPropertyDefined("jogl.gljpanel.fbobject.noworkaround"); + private boolean frameBufferDepthBufferWorkaround = !Debug.isPropertyDefined("jogl.gljpanel.fbobject.nodepthworkaround"); + private int[] frameBufferDepthBuffer = new int[1]; + private int[] frameBufferTexture = new int[1]; + private boolean createNewDepthBuffer = false; + // These are always set to (0, 0) except when the Java2D / OpenGL // pipeline is active private int viewportX; @@ -244,13 +250,30 @@ public class GLJPanel extends JPanel implements GLAutoDrawable { if (Java2D.isFBOEnabled() && Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) { if (DEBUG && VERBOSE) { - System.err.println("-- Fetching GL_FRAMEBUFFER_BINDING_EXT"); + System.err.println("GLJPanel: Fetching GL_FRAMEBUFFER_BINDING_EXT"); } gl.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING_EXT, frameBuffer, 0); - // Unbind the framebuffer from this context before attempting to - // bind it to ours (may not be necessary) - // gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0); + if (frameBufferAttachmentWorkaround) { + // Query the framebuffer for its color and depth buffers so we + // can hook them up (unclear how this is supposed to work + // according to the spec -- hope we don't damage Java2D's + // attachments) + gl.glGetFramebufferAttachmentParameterivEXT(GL.GL_FRAMEBUFFER_EXT, + GL.GL_COLOR_ATTACHMENT0_EXT, + GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, + frameBufferTexture, 0); + if (!frameBufferDepthBufferWorkaround) { + gl.glGetFramebufferAttachmentParameterivEXT(GL.GL_FRAMEBUFFER_EXT, + GL.GL_DEPTH_ATTACHMENT_EXT, + GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, + frameBufferDepthBuffer, 0); + } + if (DEBUG && VERBOSE) { + System.err.println("GLJPanel: FBO COLOR_ATTACHMENT0: " + frameBufferTexture[0]); + System.err.println("GLJPanel: FBO DEPTH_ATTACHMENT : " + frameBufferDepthBuffer[0]); + } + } } } @@ -260,8 +283,15 @@ public class GLJPanel extends JPanel implements GLAutoDrawable { gl.glEnable(GL.GL_SCISSOR_TEST); Rectangle r = Java2D.getOGLScissorBox(g); if (r == null) { + if (DEBUG && VERBOSE) { + System.err.println("Java2D.getOGLScissorBox() returned null"); + } return false; } + if (DEBUG && VERBOSE) { + System.err.println("GLJPanel: gl.glScissor(" + r.x + ", " + r.y + ", " + r.width + ", " + r.height + ")"); + } + gl.glScissor(r.x, r.y, r.width, r.height); Rectangle oglViewport = Java2D.getOGLViewport(g, panelWidth, panelHeight); // If the viewport X or Y changes, in addition to the panel's @@ -286,16 +316,72 @@ public class GLJPanel extends JPanel implements GLAutoDrawable { if (Java2D.isFBOEnabled() && Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) { if (DEBUG && VERBOSE) { - System.err.println("Binding to framebuffer object " + frameBuffer[0]); + System.err.println("GLJPanel: Binding to framebuffer object " + frameBuffer[0]); + } + + if (frameBufferAttachmentWorkaround && + frameBufferDepthBufferWorkaround && + createNewDepthBuffer) { + // Create our own depth renderbuffer and associated storage + // If we have an old one, delete it + if (frameBufferDepthBuffer[0] != 0) { + gl.glDeleteRenderbuffersEXT(1, frameBufferDepthBuffer, 0); + frameBufferDepthBuffer[0] = 0; + } + + gl.glBindTexture(GL.GL_TEXTURE_2D, frameBufferTexture[0]); + int[] width = new int[1]; + int[] height = new int[1]; + gl.glGetTexLevelParameteriv(GL.GL_TEXTURE_2D, 0, GL.GL_TEXTURE_WIDTH, width, 0); + gl.glGetTexLevelParameteriv(GL.GL_TEXTURE_2D, 0, GL.GL_TEXTURE_HEIGHT, height, 0); + + gl.glGenRenderbuffersEXT(1, frameBufferDepthBuffer, 0); + if (DEBUG) { + System.err.println("GLJPanel: Generated frameBufferDepthBuffer " + frameBufferDepthBuffer[0] + + " with width " + width[0] + ", height " + height[0]); + } + + gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, frameBufferDepthBuffer[0]); + // FIXME: may need a loop here like in Java2D + gl.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT, GL.GL_DEPTH_COMPONENT24, width[0], height[0]); + + gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, 0); + createNewDepthBuffer = false; } gl.glBindTexture(GL.GL_TEXTURE_2D, 0); gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBuffer[0]); - // FIXME: do we need to do anything else? Bind Texture2D state - // or something else? + + if (frameBufferAttachmentWorkaround) { + // Hook up the color and depth buffer attachment points for this framebuffer + + // (FIXME: thought this would be automatic due to the fact that + // the framebuffer is shared between contexts, but apparently not -- + // hope we don't damage Java2D's notion of the attachment points) + gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, + GL.GL_COLOR_ATTACHMENT0_EXT, + GL.GL_TEXTURE_2D, + frameBufferTexture[0], + 0); + if (DEBUG && VERBOSE) { + System.err.println("GLJPanel: frameBufferDepthBuffer: " + frameBufferDepthBuffer[0]); + } + gl.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT, + GL.GL_DEPTH_ATTACHMENT_EXT, + GL.GL_RENDERBUFFER_EXT, + frameBufferDepthBuffer[0]); + } + + if (DEBUG) { + int status = gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT); + if (status != GL.GL_FRAMEBUFFER_COMPLETE_EXT) { + throw new GLException("Error: framebuffer was incomplete: status = 0x" + + Integer.toHexString(status)); + } + } } else { if (DEBUG && VERBOSE) { - System.err.println("Setting up drawBuffer " + drawBuffer[0] + + System.err.println("GLJPanel: Setting up drawBuffer " + drawBuffer[0] + " and readBuffer " + readBuffer[0]); } @@ -338,6 +424,9 @@ public class GLJPanel extends JPanel implements GLAutoDrawable { // Create no-op context representing Java2D context if (j2dContext == null) { j2dContext = GLDrawableFactory.getFactory().createExternalGLContext(); + if (DEBUG) { + j2dContext.setGL(new DebugGL(j2dContext.getGL())); + } // Check to see whether we can support the requested // capabilities or need to fall back to a pbuffer @@ -399,27 +488,16 @@ public class GLJPanel extends JPanel implements GLAutoDrawable { if (joglContext == null) { joglDrawable = GLDrawableFactory.getFactory().createExternalGLDrawable(); joglContext = joglDrawable.createContext(shareWith); - } + if (DEBUG) { + joglContext.setGL(new DebugGL(joglContext.getGL())); + } - // FIXME: remove these once debugging is done - if (HACK1) { - // Skip all GLContext manipulation This fixes the - // display of the icons and text (done with Java2D) - // in the JGears demo when FBO is active - return; - } - if (HACK2) { - // Do a little GLContext manipulation but skip all - // FBO-related manipulation and other stuff (as well - // as the user rendering). - - // Note that the icons and text in the JGears demo - // disappear when this flag is used, so clearly any - // OpenGL context manipulation is messing up the - // Java2D context state when FBO is active. - joglContext.makeCurrent(); - joglContext.release(); - return; + if (Java2D.isFBOEnabled() && + Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT && + frameBufferAttachmentWorkaround && + frameBufferDepthBufferWorkaround) { + createNewDepthBuffer = true; + } } drawableHelper.invokeGL(joglDrawable, joglContext, displayAction, initAction); |