diff -ur SDL-1.3.old/include/SDL_video.h SDL-1.3.new/include/SDL_video.h --- SDL-1.3.old/include/SDL_video.h 2004-12-01 02:52:46.000000000 +0800 +++ SDL-1.3.new/include/SDL_video.h 2005-02-12 03:58:37.000000000 +0800 @@ -219,7 +219,8 @@ SDL_GL_ACCUM_ALPHA_SIZE, SDL_GL_STEREO, SDL_GL_MULTISAMPLEBUFFERS, - SDL_GL_MULTISAMPLESAMPLES + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_FLOATBUFFER } SDL_GLattr; /* flags for SDL_SetPalette() */ diff -ur SDL-1.3.old/src/video/SDL_sysvideo.h SDL-1.3.new/src/video/SDL_sysvideo.h --- SDL-1.3.old/src/video/SDL_sysvideo.h 2004-02-23 12:53:48.000000000 +0800 +++ SDL-1.3.new/src/video/SDL_sysvideo.h 2005-02-12 06:28:40.000000000 +0800 @@ -319,6 +319,7 @@ int stereo; int multisamplebuffers; int multisamplesamples; + int floatbuffer; int driver_loaded; char driver_path[256]; void* dll_handle; diff -ur SDL-1.3.old/src/video/SDL_video.c SDL-1.3.new/src/video/SDL_video.c --- SDL-1.3.old/src/video/SDL_video.c 2004-12-01 03:02:03.000000000 +0800 +++ SDL-1.3.new/src/video/SDL_video.c 2005-05-16 13:58:18.078125000 +0800 @@ -139,6 +139,15 @@ #endif +/* Defines needed for floating-point buffer support */ +#ifndef GL_ARB_texture_float +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#endif + + /* * Initialize the video and event subsystems -- determine native pixel format */ @@ -235,6 +244,7 @@ video->gl_config.stereo = 0; video->gl_config.multisamplebuffers = 0; video->gl_config.multisamplesamples = 0; + video->gl_config.floatbuffer = 0; /* Initialize the video subsystem */ memset(&vformat, 0, sizeof(vformat)); @@ -1463,6 +1473,9 @@ case SDL_GL_MULTISAMPLESAMPLES: video->gl_config.multisamplesamples = value; break; + case SDL_GL_FLOATBUFFER: + video->gl_config.floatbuffer = value; + break; default: SDL_SetError("Unknown OpenGL attribute"); retval = -1; @@ -1670,6 +1683,9 @@ SDL_GL_ACCUM_BLUE_SIZE, 0, SDL_GL_ACCUM_ALPHA_SIZE, 0, SDL_GL_STEREO, 0, + SDL_GL_MULTISAMPLEBUFFERS, 0, + SDL_GL_MULTISAMPLESAMPLES, 0, + SDL_GL_FLOATBUFFER, 0, 0 }; @@ -1698,6 +1714,9 @@ complete_attrib[2*SDL_GL_ACCUM_BLUE_SIZE+1] = video->gl_config.accum_blue_size; complete_attrib[2*SDL_GL_ACCUM_ALPHA_SIZE+1] = video->gl_config.accum_alpha_size; complete_attrib[2*SDL_GL_STEREO+1] = video->gl_config.stereo; + complete_attrib[2*SDL_GL_MULTISAMPLEBUFFERS+1] = video->gl_config.multisamplebuffers; + complete_attrib[2*SDL_GL_MULTISAMPLESAMPLES+1] = video->gl_config.multisamplesamples; + complete_attrib[2*SDL_GL_FLOATBUFFER+1] = video->gl_config.floatbuffer; #if 0 /* FIXME - we need to use a separate context for this to work */ /* Double buffer and stereo probably aren't what we want for a * pbuffer, even if the window is using them, and possibly are @@ -1707,12 +1726,18 @@ #endif /* Copy attribute information from the parameters */ + /* NOTE: It is assumed that attrib contains at least one SDL_GL attribute + * and that the values are ordered the same as in the enum + */ if ( attrib ) { int i, j; - for ( i = 0; attrib[i]; i += 2 ) { - for ( j = 0; complete_attrib[j]; j += 2 ) { + /* If attrib[i] == 0, either we have SDL_GL_RED_SIZE or the end of + the array; if it is the first element then we can safely assume + it is SDL_GL_RED_SIZE */ + for ( i = 0; attrib[i] || i == 0; i += 2 ) { + for ( j = 0; complete_attrib[j] || j == 0; j += 2 ) { if ( attrib[i] == complete_attrib[j] ) { - complete_attrib[i+1] = attrib[j+1]; + complete_attrib[j+1] = attrib[i+1]; break; } } @@ -1760,6 +1785,36 @@ void SDL_GL_BindRenderTarget(SDL_RenderTarget *target, unsigned int texture) { SDL_VideoDevice *video = current_video; + int is_float_buffer; + int red_size; + int alpha_size; + GLint internal_format; + + /* Determine required internal format from render target's attributes */ + SDL_GL_GetRenderTargetAttribute(target, SDL_GL_FLOATBUFFER, + &is_float_buffer); + SDL_GL_GetRenderTargetAttribute(target, SDL_GL_RED_SIZE, + &red_size); + SDL_GL_GetRenderTargetAttribute(target, SDL_GL_ALPHA_SIZE, + &alpha_size); + if (is_float_buffer) { + if (red_size < 32) { + if (alpha_size > 0) + internal_format = GL_RGBA16F_ARB; + else + internal_format = GL_RGB16F_ARB; + } else { + if (alpha_size > 0) + internal_format = GL_RGBA32F_ARB; + else + internal_format = GL_RGB32F_ARB; + } + } else { + if (alpha_size > 0) + internal_format = GL_RGBA; + else + internal_format = GL_RGB; + } /* !!! FIXME: Apple's pbuffer extension can't use a texture that's * !!! FIXME: previously been used for regular stuff (like TexImage2D). @@ -1768,11 +1823,11 @@ video->glBindTexture(GL_TEXTURE_2D, texture); video->glTexImage2D(GL_TEXTURE_2D, 0, - target->format, + internal_format, target->w, target->h, 0, - GL_RGB, - GL_UNSIGNED_BYTE, + internal_format, + is_float_buffer ? GL_FLOAT : GL_UNSIGNED_BYTE, NULL); #endif target->texture = texture; diff -ur SDL-1.3.old/src/video/wincommon/SDL_wingl.c SDL-1.3.new/src/video/wincommon/SDL_wingl.c --- SDL-1.3.old/src/video/wincommon/SDL_wingl.c 2004-12-01 02:52:52.000000000 +0800 +++ SDL-1.3.new/src/video/wincommon/SDL_wingl.c 2005-02-12 06:21:02.000000000 +0800 @@ -227,7 +227,6 @@ ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); } -#endif /* !HAVE_OPENGL */ #endif /* HAVE_OPENGL */ @@ -352,6 +351,11 @@ *iAttr++ = this->gl_config.multisamplesamples; } + if ( this->gl_config.floatbuffer ) { + *iAttr++ = WGL_PIXEL_TYPE_ARB; + *iAttr++ = WGL_TYPE_RGBA_FLOAT_ARB; + } + *iAttr = 0; /* Choose and set the closest available pixel format */ @@ -486,11 +490,19 @@ case SDL_GL_MULTISAMPLESAMPLES: wgl_attrib = WGL_SAMPLES_ARB; break; + case SDL_GL_FLOATBUFFER: + wgl_attrib = WGL_PIXEL_TYPE_ARB; + break; default: return(-1); } this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value); + /* When querying for SDL_GL_FLOATBUFFER, we were actually getting the + WGL_PIXEL_TYPE_ARB variable; check if it is a floating-point buffer */ + if ( attrib == SDL_GL_FLOATBUFFER ) + *value = (*value == WGL_TYPE_RGBA_FLOAT_ARB); + return 0; } @@ -690,6 +702,21 @@ attribs[i++] = GL_TRUE; } + if ( attrib[2*SDL_GL_MULTISAMPLEBUFFERS+1] ) { + attribs[i++] = WGL_SAMPLE_BUFFERS_ARB; + attribs[i++] = attrib[2*SDL_GL_MULTISAMPLEBUFFERS+1]; + } + + if ( attrib[2*SDL_GL_MULTISAMPLESAMPLES+1] ) { + attribs[i++] = WGL_SAMPLES_ARB; + attribs[i++] = attrib[2*SDL_GL_MULTISAMPLESAMPLES+1]; + } + + if ( attrib[2*SDL_GL_FLOATBUFFER+1] ) { + attribs[i++] = WGL_PIXEL_TYPE_ARB; + attribs[i++] = WGL_TYPE_RGBA_FLOAT_ARB; + } + attribs[i++] = 0; /* Choose and set the closest available pixel format. Try to @@ -761,11 +788,25 @@ case SDL_GL_STEREO: wgl_attrib = WGL_STEREO_ARB; break; + case SDL_GL_MULTISAMPLEBUFFERS: + wgl_attrib = WGL_SAMPLE_BUFFERS_ARB; + break; + case SDL_GL_MULTISAMPLESAMPLES: + wgl_attrib = WGL_SAMPLES_ARB; + break; + case SDL_GL_FLOATBUFFER: + wgl_attrib = WGL_PIXEL_TYPE_ARB; + break; default: return(-1); } this->gl_data->wglGetPixelFormatAttribivARB(render_target->hPbufferDC, render_target->format, 0, 1, &wgl_attrib, value); + /* When querying for SDL_GL_FLOATBUFFER, we were actually getting the + WGL_PIXEL_TYPE_ARB variable; check if it is a floating-point buffer */ + if ( attrib == SDL_GL_FLOATBUFFER ) + *value = (*value == WGL_TYPE_RGBA_FLOAT_ARB); + return 0; } diff -ur SDL-1.3.old/src/video/wincommon/SDL_wingl_c.h SDL-1.3.new/src/video/wincommon/SDL_wingl_c.h --- SDL-1.3.old/src/video/wincommon/SDL_wingl_c.h 2004-02-23 12:53:53.000000000 +0800 +++ SDL-1.3.new/src/video/wincommon/SDL_wingl_c.h 2005-02-12 05:57:40.000000000 +0800 @@ -156,6 +156,10 @@ #define WGL_TYPE_COLORINDEX_ARB 0x202C #endif +#ifndef WGL_ARB_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif + #ifndef WGL_ARB_multisample #define WGL_SAMPLE_BUFFERS_ARB 0x2041 #define WGL_SAMPLES_ARB 0x2042 diff -ur SDL-1.3.old/src/video/x11/SDL_x11gl.c SDL-1.3.new/src/video/x11/SDL_x11gl.c --- SDL-1.3.old/src/video/x11/SDL_x11gl.c 2004-12-01 02:52:53.000000000 +0800 +++ SDL-1.3.new/src/video/x11/SDL_x11gl.c 2005-02-12 06:35:05.000000000 +0800 @@ -143,6 +143,10 @@ attribs[i++] = this->gl_config.multisamplesamples; } + /* NOTE: We currently ignore SDL_GL_FLOATBUFFER for the primary + render surface because the current X11 extension only allows + it for pbuffers */ + #ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */ if( !getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { attribs[i++] = GLX_X_VISUAL_TYPE; @@ -427,12 +431,20 @@ case SDL_GL_MULTISAMPLESAMPLES: glx_attrib = GLX_SAMPLES_ARB; break; + case SDL_GL_FLOATBUFFER: + glx_attrib = GLX_RENDER_TYPE_SGIX; + break; default: return(-1); } retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value); + /* When querying for SDL_GL_FLOATBUFFER, we were actually getting the + GLX_RENDER_TYPE variable; we need to mask out the bits we don't need */ + if ( attrib == SDL_GL_FLOATBUFFER ) + *value = ((*value) & GLX_RGBA_FLOAT_BIT) ? 1 : 0; + return retval; } @@ -509,6 +521,7 @@ printf("\n"); printf(" Render Types: "); if (renderType & GLX_RGBA_BIT_SGIX) printf("RGBA "); + if (renderType & GLX_RGBA_FLOAT_BIT) printf("RGBAfloat "); if (renderType & GLX_COLOR_INDEX_BIT_SGIX) printf("CI "); printf("\n"); printf(" X Renderable: %s\n", xRenderable ? "yes" : "no"); @@ -546,7 +559,11 @@ /* Setup our GLX attributes */ i = 0; attribs[i++] = GLX_RENDER_TYPE_SGIX; - attribs[i++] = GLX_RGBA_BIT_SGIX; + if ( attrib[2*SDL_GL_FLOATBUFFER+1] ) { + attribs[i++] = GLX_RGBA_FLOAT_BIT; + } else { + attribs[i++] = GLX_RGBA_BIT_SGIX; + } attribs[i++] = GLX_DRAWABLE_TYPE_SGIX; attribs[i++] = GLX_PBUFFER_BIT_SGIX; attribs[i++] = GLX_RED_SIZE; @@ -575,6 +592,10 @@ attribs[i++] = attrib[2*SDL_GL_ACCUM_ALPHA_SIZE+1]; attribs[i++] = GLX_STEREO; attribs[i++] = attrib[2*SDL_GL_STEREO+1]; + attribs[i++] = GLX_SAMPLE_BUFFERS_ARB; + attribs[i++] = attrib[2*SDL_GL_MULTISAMPLEBUFFERS+1]; + attribs[i++] = GLX_SAMPLES_ARB; + attribs[i++] = attrib[2*SDL_GL_MULTISAMPLESAMPLES+1]; attribs[i++] = None; /* Loop through available configs trying to create a pbuffer */ @@ -658,12 +679,26 @@ case SDL_GL_STEREO: glx_attrib = GLX_STEREO; break; + case SDL_GL_MULTISAMPLEBUFFERS: + glx_attrib = GLX_SAMPLE_BUFFERS_ARB; + break; + case SDL_GL_MULTISAMPLESAMPLES: + glx_attrib = GLX_SAMPLES_ARB; + break; + case SDL_GL_FLOATBUFFER: + glx_attrib = GLX_RENDER_TYPE_SGIX; + break; default: return(-1); } retval = this->gl_data->glXGetFBConfigAttribSGIX(GFX_Display, render_target->config, glx_attrib, value); + /* When querying for SDL_GL_FLOATBUFFER, we were actually getting the + GLX_RENDER_TYPE variable; we need to mask out the bits we don't need */ + if ( attrib == SDL_GL_FLOATBUFFER ) + *value = ((*value) & GLX_RGBA_FLOAT_BIT) ? 1 : 0; + return retval; } diff -ur SDL-1.3.old/src/video/x11/SDL_x11gl_c.h SDL-1.3.new/src/video/x11/SDL_x11gl_c.h --- SDL-1.3.old/src/video/x11/SDL_x11gl_c.h 2004-02-23 12:53:54.000000000 +0800 +++ SDL-1.3.new/src/video/x11/SDL_x11gl_c.h 2005-02-12 03:28:22.000000000 +0800 @@ -175,6 +175,10 @@ #define GLX_FBCONFIG_ID_SGIX 0x8013 #endif +#ifndef GLX_ARB_fbconfig_float +#define GLX_RGBA_FLOAT_BIT 0x00000004 +#endif + #ifndef GLX_SGIX_pbuffer #define GLX_PBUFFER_BIT_SGIX 0x00000004 #define GLX_PRESERVED_CONTENTS_SGIX 0x801B