diff options
author | Kenneth Russel <[email protected]> | 2005-05-20 23:07:59 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2005-05-20 23:07:59 +0000 |
commit | 5f51f9c91e021c1fd1202899b531541b48cc97b9 (patch) | |
tree | f1f5dac20737e9af2d13d49c7225a964e3b51218 | |
parent | bea9f9567ca5892813b308bf92eab96166248afe (diff) |
Attempt to make floating-point pbuffers portable
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@277 232f8b59-042b-4e1e-8c03-345bb8c30851
6 files changed, 113 insertions, 13 deletions
diff --git a/src/net/java/games/jogl/GLPbuffer.java b/src/net/java/games/jogl/GLPbuffer.java index fe2c19974..849200e75 100644 --- a/src/net/java/games/jogl/GLPbuffer.java +++ b/src/net/java/games/jogl/GLPbuffer.java @@ -46,6 +46,15 @@ package net.java.games.jogl; may be removed in a future release. */ public interface GLPbuffer extends GLDrawable { + /** Indicates the GL_APPLE_float extension is being used for this pbuffer. */ + public static final int APPLE_FLOAT = 1; + + /** Indicates the GL_ATI_texture_float extension is being used for this pbuffer. */ + public static final int ATI_FLOAT = 2; + + /** Indicates the GL_NV_float_buffer extension is being used for this pbuffer. */ + public static final int NV_FLOAT = 3; + /** Binds this pbuffer to its internal texture target. Only valid to call if offscreen render-to-texture has been specified in the GLCapabilities for this GLPbuffer. If the @@ -68,4 +77,13 @@ public interface GLPbuffer extends GLDrawable { is not valid to call display() or any other routines on this pbuffer after it has been destroyed. */ public void destroy(); + + /** Indicates which vendor's extension is being used to support + floating point channels in this pbuffer if that capability was + requested in the GLCapabilities during pbuffer creation. Returns + one of NV_FLOAT, ATI_FLOAT or APPLE_FLOAT, or throws GLException + if floating-point channels were not requested for this pbuffer. + This function may only be called once the init method for this + pbuffer's GLEventListener has been called. */ + public int getFloatingPointMode(); } diff --git a/src/net/java/games/jogl/impl/GLContext.java b/src/net/java/games/jogl/impl/GLContext.java index e2f591278..4efa6d9f4 100644 --- a/src/net/java/games/jogl/impl/GLContext.java +++ b/src/net/java/games/jogl/impl/GLContext.java @@ -472,6 +472,13 @@ public abstract class GLContext { pendingOffscreenHeight = newHeight; } + /** Indicates which floating-point pbuffer implementation is in + use. Returns one of GLPbuffer.APPLE_FLOAT, GLPbuffer.ATI_FLOAT, + or GLPbuffer.NV_FLOAT. */ + public int getFloatingPointMode() throws GLException { + throw new GLException("Not supported on non-pbuffer contexts"); + } + /** Returns a non-null (but possibly empty) string containing the space-separated list of available platform-dependent (e.g., WGL, GLX) extensions. Can only be called while this context is diff --git a/src/net/java/games/jogl/impl/GLPbufferImpl.java b/src/net/java/games/jogl/impl/GLPbufferImpl.java index be0f23398..9ddb8d1da 100644 --- a/src/net/java/games/jogl/impl/GLPbufferImpl.java +++ b/src/net/java/games/jogl/impl/GLPbufferImpl.java @@ -56,6 +56,7 @@ public class GLPbufferImpl implements GLPbuffer { private GLContext context; private GLDrawableHelper drawableHelper = new GLDrawableHelper(); private boolean isInitialized=false; + private int floatMode; public GLPbufferImpl(GLContext context) { this.context = context; @@ -207,6 +208,13 @@ public class GLPbufferImpl implements GLPbuffer { context.destroy(); } + public int getFloatingPointMode() { + if (floatMode == 0) { + throw new GLException("Pbuffer not initialized, or floating-point support not requested"); + } + return floatMode; + } + //---------------------------------------------------------------------- // Internals only below this point // @@ -237,8 +245,9 @@ public class GLPbufferImpl implements GLPbuffer { class InitAction implements Runnable { public void run() { - drawableHelper.init(GLPbufferImpl.this); isInitialized=true; + floatMode = context.getFloatingPointMode(); + drawableHelper.init(GLPbufferImpl.this); } } private InitAction initAction = new InitAction(); diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java index d374230d9..33658957d 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java @@ -153,6 +153,10 @@ public class MacOSXPbufferGLContext extends MacOSXGLContext { // FIXME: do we need to do anything if the pbuffer is double-buffered? } + public int getFloatingPointMode() { + return GLPbuffer.APPLE_FLOAT; + } + private int getNextPowerOf2(int number) { if (((number-1) & number) == 0) { //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0 diff --git a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java index b0a164f26..b171bd209 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java @@ -66,6 +66,7 @@ public class WindowsPbufferGLContext extends WindowsGLContext { private boolean rect; // render-to-texture-rectangle? private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV private int texture; // actual texture object + private int floatMode; public WindowsPbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) { super(null, capabilities, null, null); @@ -145,18 +146,54 @@ public class WindowsPbufferGLContext extends WindowsGLContext { rtt = capabilities.getOffscreenRenderToTexture(); rect = capabilities.getOffscreenRenderToTextureRectangle(); boolean useFloat = capabilities.getOffscreenFloatingPointBuffers(); + boolean ati = false; // Since we are trying to create a pbuffer, the pixel format we // request (and subsequently use) must be "p-buffer capable". iattributes[niattribs++] = GL.WGL_DRAW_TO_PBUFFER_ARB; iattributes[niattribs++] = GL.GL_TRUE; - if (!rtt) { - // Currently we don't support non-truecolor visuals in the - // GLCapabilities, so we don't offer the option of making - // color-index pbuffers. - iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = GL.WGL_TYPE_RGBA_ARB; + if (rtt && !rect) { + throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified"); + } + + if (rect) { + if (!gl.isExtensionAvailable("GL_NV_texture_rectangle")) { + throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension"); + } + } + + if (useFloat) { + if (!gl.isExtensionAvailable("WGL_ATI_pixel_format_float") && + !gl.isExtensionAvailable("WGL_NV_float_buffer")) { + throw new GLException("Floating-point pbuffers not supported by this hardware"); + } + + // Prefer NVidia extension over ATI + if (gl.isExtensionAvailable("WGL_NV_float_buffer")) { + ati = false; + floatMode = GLPbuffer.NV_FLOAT; + } else { + ati = true; + floatMode = GLPbuffer.ATI_FLOAT; + } + } + + if (useFloat && ati) { + if (rtt) { + throw new GLException("Render-to-floating-point-texture not supported on ATI hardware"); + } else { + iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB; + iattributes[niattribs++] = GL.WGL_TYPE_RGBA_FLOAT_ATI; + } + } else { + if (!rtt) { + // Currently we don't support non-truecolor visuals in the + // GLCapabilities, so we don't offer the option of making + // color-index pbuffers. + iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB; + iattributes[niattribs++] = GL.WGL_TYPE_RGBA_ARB; + } } iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB; @@ -195,15 +232,17 @@ public class WindowsPbufferGLContext extends WindowsGLContext { iattributes[niattribs++] = GL.GL_TRUE; } - // FIXME: using NVidia-specific extensions and enums, as well as - // confusing render-to-texture with render-to-texture-rectangle - if (useFloat) { + if (useFloat && !ati) { iattributes[niattribs++] = GL.WGL_FLOAT_COMPONENTS_NV; iattributes[niattribs++] = GL.GL_TRUE; } if (rtt) { if (useFloat) { + assert(!ati); + if (!rect) { + throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle"); + } iattributes[niattribs++] = GL.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV; iattributes[niattribs++] = GL.GL_TRUE; } else { @@ -239,7 +278,7 @@ public class WindowsPbufferGLContext extends WindowsGLContext { iattributes[2] = GL.WGL_BLUE_BITS_ARB; iattributes[3] = GL.WGL_ALPHA_BITS_ARB; iattributes[4] = GL.WGL_DEPTH_BITS_ARB; - iattributes[5] = GL.WGL_FLOAT_COMPONENTS_NV; + iattributes[5] = (useFloat ? (ati ? GL.WGL_PIXEL_TYPE_ARB : GL.WGL_FLOAT_COMPONENTS_NV) : GL.WGL_RED_BITS_ARB); iattributes[6] = GL.WGL_SAMPLE_BUFFERS_EXT; iattributes[7] = GL.WGL_SAMPLES_EXT; iattributes[8] = GL.WGL_DRAW_TO_PBUFFER_ARB; @@ -257,9 +296,20 @@ public class WindowsPbufferGLContext extends WindowsGLContext { System.err.print(" depth: " + ivalues[4]); System.err.print(" multisample: " + ivalues[6]); System.err.print(" samples: " + ivalues[7]); - if (ivalues[5] != 0) { - System.err.print(" [float]"); + if (useFloat) { + if (ati) { + if (ivalues[5] == GL.WGL_TYPE_RGBA_FLOAT_ATI) { + System.err.print(" [ati float]"); + } else if (ivalues[5] != GL.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]"); } @@ -460,6 +510,10 @@ public class WindowsPbufferGLContext extends WindowsGLContext { } } + public int getFloatingPointMode() { + return floatMode; + } + private String wglGetLastError() { int err = WGL.GetLastError(); String detail = null; diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java index fcc03aa68..ba3b60845 100644 --- a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java @@ -159,6 +159,9 @@ public class X11PbufferGLContext extends X11GLContext { } if (capabilities.getOffscreenFloatingPointBuffers()) { + if (!gl.isExtensionAvailable("GLX_NV_float_buffer")) { + throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware"); + } iattributes[niattribs++] = GLX.GLX_FLOAT_COMPONENTS_NV; iattributes[niattribs++] = GL.GL_TRUE; } @@ -329,6 +332,11 @@ public class X11PbufferGLContext extends X11GLContext { // FIXME: do we need to do anything if the pbuffer is double-buffered? } + public int getFloatingPointMode() { + // Floating-point pbuffers currently require NVidia hardware on X11 + return GLPbuffer.NV_FLOAT; + } + private int queryFBConfig(long display, GLXFBConfig fbConfig, int attrib) { int[] tmp = new int[1]; if (GLX.glXGetFBConfigAttrib(display, fbConfig, attrib, tmp) != 0) { |