# HG changeset patch # User Sam Lantinga # Date 1058886606 0 # Node ID 9c42ee1b7d77db65c56fa34bc5e959a25ab0d5fb # Parent e92bcf2573cb0304ff7d4264c474a64de5d1f707 Date: Thu, 24 Apr 2003 15:13:47 -0400 From: Shawn Kirst Subject: SDL-1.2.5 patch to add ARB_multisample support Attached is a patch I have written for SDL-1.2.5 that adds ARB_multisample support. I only have the X11 and Win32 video patched. The Win32 patch also adds support for WGL_ARB_pixel_format, as it was required for getting a multisample capable pixel format. No additional GL header files are required to compile on either platform (though you need an up-to-date glx.h for X11). Requesting a multisample pixel format is made possible using SDL_GL_SetAttribute with the two new SDL_GLattr's I've added (SDL_GL_SAMPLE_BUFFERS and SDL_GL_SAMPLES). I've been using SDL in my projects for quite a while now, so I am happy to contribute back to the project. Now you can have and control FSAA in your SDL/GL apps at the application level! diff -r e92bcf2573cb -r 9c42ee1b7d77 WhatsNew --- a/WhatsNew Tue Jul 22 14:01:21 2003 +0000 +++ b/WhatsNew Tue Jul 22 15:10:06 2003 +0000 @@ -6,6 +6,8 @@ 1.2.6: Added SDL_LoadObject(), SDL_LoadFunction(), and SDL_UnloadObject() + Added SDL_GL_SAMPLE_BUFFERS and SDL_GL_SAMPLES for FSAA support + 1.2.5: Added SDL_BUTTON_WHEELUP (4) and SDL_BUTTON_WHEELDOWN (5) diff -r e92bcf2573cb -r 9c42ee1b7d77 include/SDL_video.h --- a/include/SDL_video.h Tue Jul 22 14:01:21 2003 +0000 +++ b/include/SDL_video.h Tue Jul 22 15:10:06 2003 +0000 @@ -217,7 +217,9 @@ SDL_GL_ACCUM_GREEN_SIZE, SDL_GL_ACCUM_BLUE_SIZE, SDL_GL_ACCUM_ALPHA_SIZE, - SDL_GL_STEREO + SDL_GL_STEREO, + SDL_GL_SAMPLE_BUFFERS, + SDL_GL_SAMPLES } SDL_GLattr; /* flags for SDL_SetPalette() */ diff -r e92bcf2573cb -r 9c42ee1b7d77 src/video/SDL_sysvideo.h --- a/src/video/SDL_sysvideo.h Tue Jul 22 14:01:21 2003 +0000 +++ b/src/video/SDL_sysvideo.h Tue Jul 22 15:10:06 2003 +0000 @@ -304,6 +304,8 @@ int accum_blue_size; int accum_alpha_size; int stereo; + int sample_buffers; + int samples; int driver_loaded; char driver_path[256]; void* dll_handle; diff -r e92bcf2573cb -r 9c42ee1b7d77 src/video/SDL_video.c --- a/src/video/SDL_video.c Tue Jul 22 14:01:21 2003 +0000 +++ b/src/video/SDL_video.c Tue Jul 22 15:10:06 2003 +0000 @@ -233,6 +233,8 @@ video->gl_config.accum_blue_size = 0; video->gl_config.accum_alpha_size = 0; video->gl_config.stereo = 0; + video->gl_config.sample_buffers = 0; + video->gl_config.samples = 0; /* Initialize the video subsystem */ memset(&vformat, 0, sizeof(vformat)); @@ -1420,6 +1422,12 @@ case SDL_GL_STEREO: video->gl_config.stereo = value; break; + case SDL_GL_SAMPLE_BUFFERS: + video->gl_config.sample_buffers = value; + break; + case SDL_GL_SAMPLES: + video->gl_config.samples = value; + break; default: SDL_SetError("Unknown OpenGL attribute"); retval = -1; diff -r e92bcf2573cb -r 9c42ee1b7d77 src/video/wincommon/SDL_wingl.c --- a/src/video/wincommon/SDL_wingl.c Tue Jul 22 14:01:21 2003 +0000 +++ b/src/video/wincommon/SDL_wingl.c Tue Jul 22 15:10:06 2003 +0000 @@ -25,6 +25,8 @@ "@(#) $Id$"; #endif +#include + /* WGL implementation of SDL OpenGL support */ #ifdef HAVE_OPENGL @@ -77,12 +79,60 @@ return(status); } +static int Init_WGL_ARB_extensions(_THIS) +{ + HWND hwnd; + HDC hdc; + HGLRC hglrc; + int pformat; + const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0; + + hwnd = CreateWindow(NULL, "PFormat", WS_POPUP | WS_DISABLED, + 0, 0, 10, 10, + NULL, NULL, SDL_Instance,NULL); + hdc = GetDC(hwnd); + + pformat = ChoosePixelFormat(hdc, &GL_pfd); + SetPixelFormat(hdc, pformat, &GL_pfd); + + hglrc = this->gl_data->wglCreateContext(hdc); + this->gl_data->wglMakeCurrent(hdc, hglrc); + + wglGetExtensionsStringARB = (const char * (WINAPI *)(HDC)) + this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB"); + + if(wglGetExtensionsStringARB && strstr(wglGetExtensionsStringARB(hdc),"WGL_ARB_pixel_format")) { + this->gl_data->wglChoosePixelFormatARB = + (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) + this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB"); + this->gl_data->wglGetPixelFormatAttribivARB = + (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) + this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB"); + + if( (this->gl_data->wglChoosePixelFormatARB != NULL) && + (this->gl_data->wglGetPixelFormatAttribivARB != NULL) ) + this->gl_data->wgl_arb_pixel_format = 1; + else + this->gl_data->wgl_arb_pixel_format = 0; + } else { + this->gl_data->wgl_arb_pixel_format = 0; + } + + this->gl_data->wglMakeCurrent(NULL, NULL); + this->gl_data->wglDeleteContext(hglrc); + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); +} + int WIN_GL_SetupWindow(_THIS) { int retval; #ifdef HAVE_OPENGL int i; - int pixel_format; + unsigned int matching; + int iAttribs[64]; + int *iAttr; + float fAttribs[1] = { 0 }; /* load the gl driver from a default path */ if ( ! this->gl_config.driver_loaded ) { @@ -127,13 +177,90 @@ GL_pfd.cDepthBits = this->gl_config.depth_size; GL_pfd.cStencilBits = this->gl_config.stencil_size; + /* initialize WGL_ARB_pixel_format */ + Init_WGL_ARB_extensions(this); + + /* setup WGL_ARB_pixel_format attribs */ + iAttr = &iAttribs[0]; + + *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; + *iAttr++ = GL_TRUE; + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = WGL_FULL_ACCELERATION_ARB; + *iAttr++ = WGL_RED_BITS_ARB; + *iAttr++ = this->gl_config.red_size; + *iAttr++ = WGL_GREEN_BITS_ARB; + *iAttr++ = this->gl_config.green_size; + *iAttr++ = WGL_BLUE_BITS_ARB; + *iAttr++ = this->gl_config.blue_size; + + if ( this->gl_config.alpha_size ) { + *iAttr++ = WGL_ALPHA_BITS_ARB; + *iAttr++ = this->gl_config.alpha_size; + } + + if ( this->gl_config.double_buffer ) { + *iAttr ++ = WGL_DOUBLE_BUFFER_ARB; + *iAttr ++ = GL_TRUE; + } + + *iAttr++ = WGL_DEPTH_BITS_ARB; + *iAttr++ = this->gl_config.depth_size; + + if ( this->gl_config.stencil_size ) { + *iAttr++ = WGL_STENCIL_BITS_ARB; + *iAttr++ = this->gl_config.stencil_size; + } + + if ( this->gl_config.accum_red_size ) { + *iAttr++ = WGL_ACCUM_RED_BITS_ARB; + *iAttr++ = this->gl_config.accum_red_size; + } + + if ( this->gl_config.accum_green_size ) { + *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; + *iAttr++ = this->gl_config.accum_green_size; + } + + if ( this->gl_config.accum_blue_size ) { + *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; + *iAttr++ = this->gl_config.accum_blue_size; + } + + if ( this->gl_config.accum_alpha_size ) { + *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; + *iAttr++ = this->gl_config.accum_alpha_size; + } + + if ( this->gl_config.stereo ) { + *iAttr++ = WGL_STEREO_ARB; + *iAttr++ = this->gl_config.stereo; + } + + if ( this->gl_config.sample_buffers ) { + *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; + *iAttr++ = this->gl_config.sample_buffers; + } + + if ( this->gl_config.samples ) { + *iAttr++ = WGL_SAMPLES_ARB; + *iAttr++ = this->gl_config.samples; + } + + *iAttr = 0; + /* Choose and set the closest available pixel format */ - pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); + if ( !this->gl_data->wgl_arb_pixel_format || + !this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs, fAttribs, 1, &pixel_format, &matching) || + !matching ) { + pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); + this->gl_data->wgl_arb_pixel_format = 0; + } if ( !pixel_format ) { SDL_SetError("No matching GL pixel format available"); return(-1); } - if( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) { + if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) { if ( i == 0 ) { /* First time through, try resetting the window */ if ( WIN_GL_ResetWindow(this) < 0 ) { @@ -150,7 +277,7 @@ DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd); GL_hrc = this->gl_data->wglCreateContext(GL_hdc); - if( GL_hrc == NULL ) { + if ( GL_hrc == NULL ) { SDL_SetError("Unable to create GL context"); return(-1); } @@ -204,9 +331,66 @@ int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) { int retval; + + if ( this->gl_data->wgl_arb_pixel_format ) { + int wgl_attrib; + + switch(attrib) { + case SDL_GL_RED_SIZE: + wgl_attrib = WGL_RED_BITS_ARB; + break; + case SDL_GL_GREEN_SIZE: + wgl_attrib = WGL_GREEN_BITS_ARB; + break; + case SDL_GL_BLUE_SIZE: + wgl_attrib = WGL_BLUE_BITS_ARB; + break; + case SDL_GL_ALPHA_SIZE: + wgl_attrib = WGL_ALPHA_BITS_ARB; + break; + case SDL_GL_DOUBLEBUFFER: + wgl_attrib = WGL_DOUBLE_BUFFER_ARB; + break; + case SDL_GL_BUFFER_SIZE: + wgl_attrib = WGL_COLOR_BITS_ARB; + break; + case SDL_GL_DEPTH_SIZE: + wgl_attrib = WGL_DEPTH_BITS_ARB; + break; + case SDL_GL_STENCIL_SIZE: + wgl_attrib = WGL_STENCIL_BITS_ARB; + break; + case SDL_GL_ACCUM_RED_SIZE: + wgl_attrib = WGL_ACCUM_RED_BITS_ARB; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB; + break; + case SDL_GL_STEREO: + wgl_attrib = WGL_STEREO_ARB; + break; + case SDL_GL_SAMPLE_BUFFERS: + wgl_attrib = WGL_SAMPLE_BUFFERS_ARB; + break; + case SDL_GL_SAMPLES: + wgl_attrib = WGL_SAMPLES_ARB; + break; + default: + return(-1); + } + this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value); + + return 0; + } retval = 0; - switch( attrib ) { + switch ( attrib ) { case SDL_GL_RED_SIZE: *value = GL_pfd.cRedBits; break; @@ -275,6 +459,8 @@ this->gl_data->wglCreateContext = NULL; this->gl_data->wglDeleteContext = NULL; this->gl_data->wglMakeCurrent = NULL; + this->gl_data->wglChoosePixelFormatARB = NULL; + this->gl_data->wglGetPixelFormatAttribivARB = NULL; this->gl_config.dll_handle = NULL; this->gl_config.driver_loaded = 0; @@ -304,6 +490,7 @@ WIN_GL_UnloadLibrary(this); /* Load new function pointers */ + memset(this->gl_data, 0, sizeof(*this->gl_data)); this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *)) GetProcAddress(handle, "wglGetProcAddress"); this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC)) diff -r e92bcf2573cb -r 9c42ee1b7d77 src/video/wincommon/SDL_wingl_c.h --- a/src/video/wincommon/SDL_wingl_c.h Tue Jul 22 14:01:21 2003 +0000 +++ b/src/video/wincommon/SDL_wingl_c.h Tue Jul 22 15:10:06 2003 +0000 @@ -37,6 +37,8 @@ PIXELFORMATDESCRIPTOR GL_pfd; HDC GL_hdc; HGLRC GL_hrc; + int pixel_format; + int wgl_arb_pixel_format; void * (WINAPI *wglGetProcAddress)(const char *proc); @@ -45,7 +47,16 @@ BOOL (WINAPI *wglDeleteContext)(HGLRC hglrc); BOOL (WINAPI *wglMakeCurrent)(HDC hdc, HGLRC hglrc); - + + BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, + const FLOAT *pfAttribFList, + UINT nMaxFormats, int *piFormats, + UINT *nNumFormats); + BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + int *piValues); #endif /* HAVE_OPENGL */ }; @@ -54,6 +65,7 @@ #define GL_pfd (this->gl_data->GL_pfd) #define GL_hdc (this->gl_data->GL_hdc) #define GL_hrc (this->gl_data->GL_hrc) +#define pixel_format (this->gl_data->pixel_format) /* OpenGL functions */ extern int WIN_GL_SetupWindow(_THIS); @@ -67,3 +79,63 @@ extern void *WIN_GL_GetProcAddress(_THIS, const char* proc); #endif +#ifdef HAVE_OPENGL + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#endif diff -r e92bcf2573cb -r 9c42ee1b7d77 src/video/x11/SDL_x11gl.c --- a/src/video/x11/SDL_x11gl.c Tue Jul 22 14:01:21 2003 +0000 +++ b/src/video/x11/SDL_x11gl.c Tue Jul 22 15:10:06 2003 +0000 @@ -122,6 +122,16 @@ attribs[i++] = GLX_STEREO; attribs[i++] = this->gl_config.stereo; } + + if( this->gl_config.sample_buffers ) { + attribs[i++] = GLX_SAMPLE_BUFFERS_ARB; + attribs[i++] = this->gl_config.sample_buffers; + } + + if( this->gl_config.samples ) { + attribs[i++] = GLX_SAMPLES_ARB; + attribs[i++] = this->gl_config.samples; + } #ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */ attribs[i++] = GLX_X_VISUAL_TYPE; @@ -229,7 +239,7 @@ #ifdef HAVE_OPENGL -static int ExtensionSupported(const char *extension, const char *all_extensions) +static int ExtensionSupported(const char *extension) { const GLubyte *extensions = NULL; const GLubyte *start; @@ -266,7 +276,6 @@ int X11_GL_MakeCurrent(_THIS) { int retval; - const char *glx_extensions; retval = 0; if ( ! this->gl_data->glXMakeCurrent(GFX_Display, @@ -276,7 +285,6 @@ } XSync( GFX_Display, False ); - /* * The context is now current, check for glXReleaseBuffersMESA() * extension. If extension is _not_ supported, destroy the pointer @@ -296,10 +304,10 @@ * */ - glx_extensions = this->gl_data->glXQueryExtensionsString(GFX_Display, SDL_Screen); - if (!ExtensionSupported("glXReleaseBuffersMESA", glx_extensions)) this->gl_data->glXReleaseBuffersMESA = NULL; - - + if ( ! ExtensionSupported("glXReleaseBuffersMESA") ) { + this->gl_data->glXReleaseBuffersMESA = NULL; + } + /* More Voodoo X server workarounds... Grr... */ SDL_Lock_EventThread(); X11_CheckDGAMouse(this); @@ -354,6 +362,12 @@ case SDL_GL_STEREO: glx_attrib = GLX_STEREO; break; + case SDL_GL_SAMPLE_BUFFERS: + glx_attrib = GLX_SAMPLE_BUFFERS_ARB; + break; + case SDL_GL_SAMPLES: + glx_attrib = GLX_SAMPLES_ARB; + break; default: return(-1); } diff -r e92bcf2573cb -r 9c42ee1b7d77 test/testgl.c --- a/test/testgl.c Tue Jul 22 14:01:21 2003 +0000 +++ b/test/testgl.c Tue Jul 22 15:10:06 2003 +0000 @@ -393,7 +393,7 @@ } int RunGLTest( int argc, char* argv[], - int logo, int slowly, int bpp, float gamma, int noframe ) + int logo, int slowly, int bpp, float gamma, int noframe, int fsaa ) { int i; int rgb_size[3]; @@ -475,6 +475,10 @@ SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + if ( fsaa ) { + SDL_GL_SetAttribute( SDL_GL_SAMPLE_BUFFERS, 1 ); + SDL_GL_SetAttribute( SDL_GL_SAMPLES, fsaa ); + } if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) { fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError()); SDL_Quit(); @@ -499,6 +503,12 @@ printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value ); SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value ); printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value ); + if ( fsaa ) { + SDL_GL_GetAttribute( SDL_GL_SAMPLE_BUFFERS, &value ); + printf( "SDL_GL_SAMPLE_BUFFERS: requested 1, got %d\n", value ); + SDL_GL_GetAttribute( SDL_GL_SAMPLES, &value ); + printf( "SDL_GL_SAMPLES: requested %d, got %d\n", fsaa, value ); + } /* Set the window manager title bar */ SDL_WM_SetCaption( "SDL GL test", "testgl" ); @@ -700,6 +710,7 @@ int slowly; float gamma = 0.0; int noframe = 0; + int fsaa = 0; logo = 0; slowly = 0; @@ -728,15 +739,18 @@ if ( strcmp(argv[i], "-noframe") == 0 ) { noframe = 1; } + if ( strcmp(argv[i], "-fsaa") == 0 ) { + ++fsaa; + } if ( strncmp(argv[i], "-h", 2) == 0 ) { printf( -"Usage: %s [-twice] [-logo] [-slow] [-bpp n] [-gamma n] [-noframe]\n", +"Usage: %s [-twice] [-logo] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa]\n", argv[0]); exit(0); } } for ( i=0; i