From c1e65970a2f1229522623e8af8a68e66590a7ab8 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 12 Jun 2006 13:01:05 +0000 Subject: [PATCH] Added floating point format to PixelFormat. Linux implementation --- src/java/org/lwjgl/opengl/PixelFormat.java | 17 ++++++++++++++--- src/native/linux/context.c | 9 ++++++++- src/native/linux/extgl_glx.c | 1 + src/native/linux/extgl_glx.h | 5 +++++ ...rg_lwjgl_opengl_LinuxContextImplementation.c | 10 ++++++++-- 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/java/org/lwjgl/opengl/PixelFormat.java b/src/java/org/lwjgl/opengl/PixelFormat.java index 15595132..70a6f900 100644 --- a/src/java/org/lwjgl/opengl/PixelFormat.java +++ b/src/java/org/lwjgl/opengl/PixelFormat.java @@ -33,8 +33,8 @@ package org.lwjgl.opengl; /** * This class describes pixel format properties for an OpenGL context. Instances - * of this class is used as arguments to Display.create() and Pbuffer.create(), to - * indicate minimum required properties. + * of this class is used as arguments to Display.create(), Pbuffer.create() and + * AWTGLCanvas, to indicate minimum required properties. * * WARNING: Some pixel formats are known to cause troubles on certain buggy drivers. * Example: Under Windows, specifying samples != 0 will enable the ARB @@ -67,8 +67,10 @@ public final class PixelFormat { private final int accum_bpp; /** The number of alpha bits in the accumulation buffer */ private final int accum_alpha; - /** Whether this format represents a stereo buffer or not */ + /** Whether this format requires a stereo buffer */ private final boolean stereo; + /** Whether this format specifies a floating point format */ + private final boolean floating_point; /** * Default pixel format is minimum 8 bits depth, and no alpha @@ -91,6 +93,10 @@ public final class PixelFormat { } public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo) { + this(bpp, alpha, depth, stencil, samples, num_aux_buffers, accum_bpp, accum_alpha, stereo, false); + } + + public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo, boolean floating_point) { this.bpp = bpp; this.alpha = alpha; this.depth = depth; @@ -100,6 +106,7 @@ public final class PixelFormat { this.accum_bpp = accum_bpp; this.accum_alpha = accum_alpha; this.stereo = stereo; + this.floating_point = floating_point; } public int getBitsPerPixel() { @@ -137,4 +144,8 @@ public final class PixelFormat { public boolean isStereo() { return stereo; } + + public boolean isFloatingPoint() { + return floating_point; + } } diff --git a/src/native/linux/context.c b/src/native/linux/context.c index a758f7c4..aa7e40eb 100644 --- a/src/native/linux/context.c +++ b/src/native/linux/context.c @@ -123,12 +123,14 @@ static GLXFBConfig *chooseVisualGLX13FromBPP(JNIEnv *env, Display *disp, int scr int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); bool stereo = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); + bool floating_point = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "floating_point", "Z")); int bpe = convertToBPE(bpp); int accum_bpe = convertToBPE(accum_bpp); attrib_list_t attrib_list; initAttribList(&attrib_list); - putAttrib(&attrib_list, GLX_RENDER_TYPE); putAttrib(&attrib_list, GLX_RGBA_BIT); + int render_type = floating_point ? GLX_RGBA_FLOAT_BIT : GLX_RGBA_BIT; + putAttrib(&attrib_list, GLX_RENDER_TYPE); putAttrib(&attrib_list, render_type); putAttrib(&attrib_list, GLX_DOUBLEBUFFER); putAttrib(&attrib_list, double_buffer ? True : False); putAttrib(&attrib_list, GLX_DRAWABLE_TYPE); putAttrib(&attrib_list, drawable_type); putAttrib(&attrib_list, GLX_DEPTH_SIZE); putAttrib(&attrib_list, depth); @@ -269,6 +271,11 @@ bool initPeerInfo(JNIEnv *env, jobject peer_info_handle, Display *display, int s throwException(env, "Samples > 0 specified but there's no support for GLX_ARB_multisample"); return false; } + bool floating_point = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "floating_point", "Z")); + if (floating_point && !extension_flags.GLX_ARB_fbconfig_float) { + throwException(env, "Floating point specified but there's no support for GLX_ARB_fbconfig_float"); + return false; + } peer_info->glx13 = extension_flags.GLX13; if (peer_info->glx13) { GLXFBConfig *configs = chooseVisualGLX13(env, display, screen, pixel_format, use_display_bpp, drawable_type, double_buffered); diff --git a/src/native/linux/extgl_glx.c b/src/native/linux/extgl_glx.c index 58cd5cd6..c0958d67 100644 --- a/src/native/linux/extgl_glx.c +++ b/src/native/linux/extgl_glx.c @@ -147,6 +147,7 @@ static void extgl_InitGLXSupportedExtensions(Display *disp, int screen, GLXExten extension_flags.GLX_EXT_visual_rating = GLXQueryExtension(disp, screen, "GLX_EXT_visual_rating");*/ extension_flags->GLX_SGI_swap_control = symbols_flags.GLX_SGI_swap_control && GLXQueryExtension(disp, screen, "GLX_SGI_swap_control"); extension_flags->GLX_ARB_multisample = GLXQueryExtension(disp, screen, "GLX_ARB_multisample"); + extension_flags->GLX_ARB_fbconfig_float = GLXQueryExtension(disp, screen, "GLX_ARB_fbconfig_float"); } bool extgl_Open(JNIEnv *env) { diff --git a/src/native/linux/extgl_glx.h b/src/native/linux/extgl_glx.h index 2f294028..9c25c80c 100644 --- a/src/native/linux/extgl_glx.h +++ b/src/native/linux/extgl_glx.h @@ -252,6 +252,10 @@ /* NV_float_buffer */ #define GLX_FLOAT_COMPONENTS_NV 0x20B0 +/* GLX_ARB_fbconfig_float */ +#define GLX_RGBA_FLOAT_TYPE 0x20B9 +#define GLX_RGBA_FLOAT_BIT 0x0004 + typedef XID GLXContextID; typedef XID GLXPixmap; typedef XID GLXDrawable; @@ -319,6 +323,7 @@ typedef struct { bool GLX_EXT_visual_rating;*/ bool GLX_SGI_swap_control; bool GLX_ARB_multisample; + bool GLX_ARB_fbconfig_float; } GLXExtensions; /* Add _ to global symbols to avoid symbol clash with the OpenGL library */ diff --git a/src/native/linux/org_lwjgl_opengl_LinuxContextImplementation.c b/src/native/linux/org_lwjgl_opengl_LinuxContextImplementation.c index d3e6f4c1..08cdd919 100644 --- a/src/native/linux/org_lwjgl_opengl_LinuxContextImplementation.c +++ b/src/native/linux/org_lwjgl_opengl_LinuxContextImplementation.c @@ -60,7 +60,7 @@ static bool checkContext(JNIEnv *env, Display *display, GLXContext context) { /* * Ditched the requirement that contexts have to be direct. It was * never true that all accelerated contexts are direct, but it - * was a reasonable test until the appearance of Xgl and friends. + * was a reasonable test until the appearance of Xgl and AIGLX. * Now the test is at best useless, and at worst wrong, * in case the current X server accelerates indirect rendering. */ @@ -77,7 +77,13 @@ static void createContextGLX13(JNIEnv *env, X11PeerInfo *peer_info, X11Context * GLXFBConfig *config = getFBConfigFromPeerInfo(env, peer_info); if (config == NULL) return; - GLXContext context = lwjgl_glXCreateNewContext(peer_info->display, *config, GLX_RGBA_TYPE, shared_context, True); + int render_type; + if (lwjgl_glXGetFBConfigAttrib(peer_info->display, *config, GLX_RENDER_TYPE, &render_type) != 0) { + throwException(env, "Could not get GLX_RENDER_TYPE attribute"); + return; + } + int context_render_type = (render_type & GLX_RGBA_FLOAT_BIT) != 0 ? GLX_RGBA_FLOAT_TYPE : GLX_RGBA_TYPE; + GLXContext context = lwjgl_glXCreateNewContext(peer_info->display, *config, context_render_type, shared_context, True); XFree(config); if (!checkContext(env, peer_info->display, context)) return;