Mercurial > sdl-ios-xcode
changeset 1942:4371d679ee12
Hopefully glSDL has been superceded by the OpenGL render driver.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 26 Jul 2006 03:12:05 +0000 |
parents | bf09d535e014 |
children | 7d642361ef0f |
files | configure.in include/SDL_config.h.in include/SDL_config_amiga.h include/SDL_config_dreamcast.h include/SDL_config_macos.h src/video/SDL_sysvideo.h src/video/SDL_video.c src/video/glsdl/SDL_glsdl.c src/video/glsdl/SDL_glsdl.h |
diffstat | 9 files changed, 0 insertions(+), 2534 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Wed Jul 26 03:08:25 2006 +0000 +++ b/configure.in Wed Jul 26 03:12:05 2006 +0000 @@ -1486,20 +1486,6 @@ fi } -dnl Find glSDL -CheckglSDL() -{ - AC_ARG_ENABLE(video-glsdl, -[ --enable-video-glsdl use glSDL video driver [default=yes]], - , enable_video_glsdl=yes) - AC_MSG_CHECKING(for glSDL support) - AC_MSG_RESULT($video_opengl) - if test x$video_opengl = xyes -a x$enable_video_glsdl = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_GLSDL) - SOURCES="$SOURCES $srcdir/src/video/glsdl/*.c" - fi -} - dnl Check for Mesa offscreen rendering CheckAtariOSMesa() { @@ -2106,7 +2092,6 @@ CheckQtopia CheckPicoGUI CheckOpenGLX11 - CheckglSDL CheckInputEvents CheckTslib CheckUSBHID @@ -2205,7 +2190,6 @@ CheckPHOTON CheckX11 CheckOpenGLX11 - CheckglSDL CheckPTHREAD # Set up files for the audio library if test x$enable_audio = xyes; then @@ -2243,7 +2227,6 @@ CheckDummyAudio CheckWIN32 CheckWIN32GL - CheckglSDL CheckDIRECTX CheckNASM # Set up files for the video library @@ -2328,7 +2311,6 @@ CheckNASM CheckBWINDOW CheckBeGL - CheckglSDL # Set up files for the audio library if test x$enable_audio = xyes; then AC_DEFINE(SDL_AUDIO_DRIVER_BAUDIO) @@ -2409,7 +2391,6 @@ CheckX11 CheckMacGL CheckOpenGLX11 - CheckglSDL CheckPTHREAD CheckAltivec @@ -2463,7 +2444,6 @@ CheckAtariAudio CheckAtariLdg CheckAtariOSMesa - CheckglSDL CheckPTH # Set up files for the audio library if test x$enable_threads = xyes -a x$enable_pth = xyes; then
--- a/include/SDL_config.h.in Wed Jul 26 03:08:25 2006 +0000 +++ b/include/SDL_config.h.in Wed Jul 26 03:12:05 2006 +0000 @@ -262,7 +262,6 @@ #undef SDL_VIDEO_DRIVER_GAPI #undef SDL_VIDEO_DRIVER_GEM #undef SDL_VIDEO_DRIVER_GGI -#undef SDL_VIDEO_DRIVER_GLSDL #undef SDL_VIDEO_DRIVER_IPOD #undef SDL_VIDEO_DRIVER_NANOX #undef SDL_VIDEO_DRIVER_OS2FS
--- a/include/SDL_config_amiga.h Wed Jul 26 03:08:25 2006 +0000 +++ b/include/SDL_config_amiga.h Wed Jul 26 03:12:05 2006 +0000 @@ -73,7 +73,6 @@ /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_CYBERGRAPHICS 1 #define SDL_VIDEO_DRIVER_DUMMY 1 -#define SDL_VIDEO_DRIVER_GLSDL 1 /* Enable OpenGL support */ #define SDL_VIDEO_OPENGL 1
--- a/include/SDL_config_dreamcast.h Wed Jul 26 03:08:25 2006 +0000 +++ b/include/SDL_config_dreamcast.h Wed Jul 26 03:12:05 2006 +0000 @@ -102,6 +102,5 @@ /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_DC 1 #define SDL_VIDEO_DRIVER_DUMMY 1 -#define SDL_VIDEO_DRIVER_GLSDL 1 #endif /* _SDL_config_dreamcast_h */
--- a/include/SDL_config_macos.h Wed Jul 26 03:08:25 2006 +0000 +++ b/include/SDL_config_macos.h Wed Jul 26 03:12:05 2006 +0000 @@ -104,7 +104,6 @@ /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_DUMMY 1 #define SDL_VIDEO_DRIVER_DRAWSPROCKET 1 -#define SDL_VIDEO_DRIVER_GLSDL 1 #define SDL_VIDEO_DRIVER_TOOLBOX 1 /* Enable OpenGL support */
--- a/src/video/SDL_sysvideo.h Wed Jul 26 03:08:25 2006 +0000 +++ b/src/video/SDL_sysvideo.h Wed Jul 26 03:12:05 2006 +0000 @@ -378,9 +378,6 @@ #if SDL_VIDEO_DRIVER_DUMMY extern VideoBootStrap DUMMY_bootstrap; #endif -#if SDL_VIDEO_DRIVER_GLSDL -extern VideoBootStrap glSDL_bootstrap; -#endif #define SDL_CurrentDisplay (_this->displays[_this->current_display])
--- a/src/video/SDL_video.c Wed Jul 26 03:08:25 2006 +0000 +++ b/src/video/SDL_video.c Wed Jul 26 03:12:05 2006 +0000 @@ -127,9 +127,6 @@ #if SDL_VIDEO_DRIVER_DUMMY &DUMMY_bootstrap, #endif -#if SDL_VIDEO_DRIVER_GLSDL - &glSDL_bootstrap, -#endif NULL };
--- a/src/video/glsdl/SDL_glsdl.c Wed Jul 26 03:08:25 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2465 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - * glSDL "SDL-over-OpenGL" video driver implemented by - * David Olofson <david@olofson.net> and - * Stephane Marchesin <stephane.marchesin@wanadoo.fr> - */ -#include <math.h> - -#include "SDL.h" -#include "SDL_error.h" -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" - -#include "SDL_glsdl.h" - -#undef DEBUG_GLSDL -#undef DEBUG_GLSDL_CHOP -#define FAKE_MAXTEXSIZE 256 -#undef GLSDL_GRAPHICAL_DEBUG - -/* Initialization/Query functions */ - -/* Hardware surface functions */ -static int glSDL_SetColors(_THIS, int firstcolor, int ncolors, - SDL_Color * colors); -static int glSDL_AllocHWSurface(_THIS, SDL_Surface * surface); -static int glSDL_LockHWSurface(_THIS, SDL_Surface * surface); -static int glSDL_FlipHWSurface(_THIS, SDL_Surface * surface); -static void glSDL_UnlockHWSurface(_THIS, SDL_Surface * surface); -static void glSDL_FreeHWSurface(_THIS, SDL_Surface * surface); -static int glSDL_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * rect, - Uint32 color); -static int glSDL_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst); -static int glSDL_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key); -static int glSDL_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha); -static int glSDL_VideoInit(_THIS, SDL_PixelFormat * vformat); -static SDL_Rect **glSDL_ListModes(_THIS, SDL_PixelFormat * format, - Uint32 flags); -static void glSDL_VideoQuit(_THIS); -static void glSDL_UpdateRects(_THIS, int numrects, SDL_Rect * rects); -static SDL_Surface *glSDL_SetVideoMode(_THIS, SDL_Surface * current, - int width, int height, int bpp, - Uint32 flags); - -#define IS_GLSDL_SURFACE(s) ((s) && glSDL_GetTexInfo(s)) - -#define LOGIC_W(s) ( IS_GLSDL_SURFACE(this,s) ? TEXINFO(s)->lw : (s)->w ) -#define LOGIC_H(s) ( IS_GLSDL_SURFACE(this,s) ? TEXINFO(s)->lh : (s)->h ) - -#define GLSDL_NOTEX (~0) - -/* - * Special version for glSDL, which ignores the fake SDL_HWSURFACE - * flags, so we don't have SDL calling us back whenever we want to - * do some internal blitting... - */ -static void -glSDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) -{ - SDL_BlitInfo info; - - if (srcrect) - if (!srcrect->w || !srcrect->h) - return; - - /* Check to make sure the blit mapping is valid */ - if ((src->map->dst != dst) || - (src->map->dst->format_version != src->map->format_version)) - if (SDL_MapSurface(src, dst) < 0) - return; - - /* Set up the blit information */ - if (srcrect) { - info.s_pixels = (Uint8 *) src->pixels + - (Uint16) srcrect->y * src->pitch + - (Uint16) srcrect->x * src->format->BytesPerPixel; - info.s_width = srcrect->w; - info.s_height = srcrect->h; - } else { - info.s_pixels = (Uint8 *) src->pixels; - info.s_width = src->w; - info.s_height = src->h; - } - info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel; - if (dstrect) { - info.d_pixels = (Uint8 *) dst->pixels + - (Uint16) dstrect->y * dst->pitch + - (Uint16) dstrect->x * dst->format->BytesPerPixel; - /* - * NOTE: SDL_SoftBlit() uses the 'dstrect' for this! - * This version is more like SDL_BlitSurface(). - */ - info.d_width = srcrect->w; - info.d_height = srcrect->h; - } else { - info.d_pixels = (Uint8 *) dst->pixels; - info.d_width = dst->w; - info.d_height = dst->h; - } - info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel; - info.aux_data = src->map->sw_data->aux_data; - info.src = src->format; - info.table = src->map->table; - info.dst = dst->format; - - src->map->sw_data->blit(&info); -} - - -/* - * Another special version. Doesn't lock/unlock, and doesn't mess - * with flags and stuff. It just converts the surface, period. - * Does not convert into palletized formats. - */ -static SDL_Surface * -glSDL_ConvertSurface(SDL_Surface * surface, - SDL_PixelFormat * format, Uint32 flags) -{ - SDL_Surface *convert; - Uint32 colorkey = 0; - Uint8 alpha = 0; - Uint32 surface_flags; - SDL_Rect bounds; - - /* Create a new surface with the desired format */ - convert = SDL_CreateRGBSurface(flags, - surface->w, surface->h, - format->BitsPerPixel, format->Rmask, - format->Gmask, format->Bmask, - format->Amask); - if (convert == NULL) { - return (NULL); - } - - /* Save the original surface color key and alpha */ - surface_flags = surface->flags; - if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { - /* Convert colourkeyed surfaces to RGBA if requested */ - if ((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY && format->Amask) { - surface_flags &= ~SDL_SRCCOLORKEY; - } else { - colorkey = surface->format->colorkey; - SDL_SetColorKey(surface, 0, 0); - } - } - if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { - /* Copy over the alpha channel to RGBA if requested */ - if (format->Amask) { - surface->flags &= ~SDL_SRCALPHA; - } else { - alpha = surface->format->alpha; - SDL_SetAlpha(surface, 0, 0); - } - } - - /* Copy over the image data */ - bounds.x = 0; - bounds.y = 0; - bounds.w = surface->w; - bounds.h = surface->h; - glSDL_SoftBlit(surface, &bounds, convert, &bounds); - - /* Clean up the original surface, and update converted surface */ - if (convert != NULL) { - SDL_SetClipRect(convert, &surface->clip_rect); - } - if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { - Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK); - if (convert != NULL) { - Uint8 keyR, keyG, keyB; - - SDL_GetRGB(colorkey, surface->format, &keyR, &keyG, &keyB); - SDL_SetColorKey(convert, cflags | (flags & SDL_RLEACCELOK), - SDL_MapRGB(convert->format, keyR, keyG, keyB)); - } - SDL_SetColorKey(surface, cflags, colorkey); - } - if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { - Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); - if (convert != NULL) { - SDL_SetAlpha(convert, aflags | (flags & SDL_RLEACCELOK), alpha); - } - if (format->Amask) { - surface->flags |= SDL_SRCALPHA; - } else { - SDL_SetAlpha(surface, aflags, alpha); - } - } - - /* We're ready to go! */ - return (convert); -} - - -/*---------------------------------------------------------- - Some OpenGL function wrappers - ----------------------------------------------------------*/ - -static struct -{ - int do_blend; - int do_texture; - GLuint texture; - GLenum sfactor, dfactor; -} glstate; - -static void -glSDL_reset(void) -{ - glstate.do_blend = -1; - glstate.do_blend = -1; - glstate.texture = GLSDL_NOTEX; - glstate.sfactor = 0xffffffff; - glstate.dfactor = 0xffffffff; -} - -static __inline__ void -glSDL_do_blend(_THIS, int on) -{ - if (glstate.do_blend == on) - return; - - if (on) - this->glEnable(GL_BLEND); - else - this->glDisable(GL_BLEND); - glstate.do_blend = on; -} - -static __inline__ void -glSDL_do_texture(_THIS, int on) -{ - if (glstate.do_texture == on) - return; - - if (on) - this->glEnable(GL_TEXTURE_2D); - else - this->glDisable(GL_TEXTURE_2D); - glstate.do_texture = on; -} - -static __inline__ void -glSDL_blendfunc(_THIS, GLenum sfactor, GLenum dfactor) -{ - if ((sfactor == glstate.sfactor) && (dfactor == glstate.dfactor)) - return; - - this->glBlendFunc(sfactor, dfactor); - - glstate.sfactor = sfactor; - glstate.dfactor = dfactor; -} - -static __inline__ void -glSDL_texture(_THIS, GLuint tx) -{ - if (tx == glstate.texture) - return; - - this->glBindTexture(GL_TEXTURE_2D, tx); - glstate.texture = tx; -} - - - - -/*---------------------------------------------------------- - glSDL specific data types - ----------------------------------------------------------*/ - -typedef enum -{ - GLSDL_TM_SINGLE, - GLSDL_TM_HORIZONTAL, - GLSDL_TM_VERTICAL, - GLSDL_TM_HUGE -} GLSDL_TileModes; - - -typedef struct private_hwdata -{ - /* Size of surface in logic screen pixels */ - int lw, lh; - - int textures; - GLuint *texture; - int texsize; /* width/height of OpenGL texture */ - GLSDL_TileModes tilemode; - int tilew, tileh; /* At least one must equal texsize! */ - int tilespertex; - SDL_Rect virt; /* Total size of assembled surface */ - - /* Area of surface to upload when/after unlocking */ - SDL_Rect invalid_area; - - int temporary; /* Throw away after one use. */ - - SDL_Surface *next; /* The next Surface in our linked list of hardware surfaces ; == NULL if first surface */ - SDL_Surface *prev; /* The prev Surface in our linked list of hardware surfaces ; == NULL if last surface */ -} private_hwdata; - -/* some function prototypes */ -static void glSDL_Invalidate(SDL_Surface * surface, SDL_Rect * area); -static void glSDL_SetLogicSize(_THIS, SDL_Surface * surface, int w, int h); -static private_hwdata *glSDL_UploadSurface(_THIS, SDL_Surface * surface); -static private_hwdata *glSDL_GetTexInfo(SDL_Surface * surface); -static void glSDL_init_formats(_THIS); -static private_hwdata *glSDL_AddTexInfo(_THIS, SDL_Surface * surface); -static void glSDL_RemoveTexInfo(_THIS, SDL_Surface * surface); -static void glSDL_UnloadTexture(_THIS, private_hwdata * txi); -static int glSDL_BlitGL(_THIS, SDL_Surface * src, - SDL_Rect * srcrect, SDL_Rect * dstrect); - -/* some variables */ -static GLint maxtexsize = -1; -static SDL_PixelFormat *RGBfmt = NULL; -static SDL_PixelFormat *RGBAfmt = NULL; -static void *mirrorbuf = NULL; -/* the raw 888 opengl surface, hidden from the application */ -SDL_Surface *OpenGL_Surface; - -/* pointer to the beggining of the list used for memory allocation */ -SDL_Surface *first = NULL; - -#ifdef DEBUG_GLSDL -static __inline__ int -GLERET(const char *txt) -{ - fprintf(stderr, "glSDL ERROR: '%s'\n", txt); - return -1; -} -static __inline__ void -GLERR(const char *txt) -{ - fprintf(stderr, "glSDL ERROR: '%s'\n", txt); -} -#else -#define GLERET(x) (-1) -#define GLERR(x) -#endif - -static SDL_VideoDevice underlying_device; -static int old_screen_flags; - -/* - * List of video drivers known to support OpenGL - * The purpose of this is to make glSDL "portable" across - * all video backends that support OpenGL - */ -static VideoBootStrap *opengl_bootstrap = -#if SDL_VIDEO_DRIVER_QUARTZ - &QZ_bootstrap; -#elif SDL_VIDEO_DRIVER_X11 - &X11_bootstrap; -#elif SDL_VIDEO_DRIVER_WINDIB - &WINDIB_bootstrap; -#elif SDL_VIDEO_DRIVER_BWINDOW - &BWINDOW_bootstrap; -#elif SDL_VIDEO_DRIVER_TOOLBOX - &TOOLBOX_bootstrap; -#elif SDL_VIDEO_DRIVER_CYBERGRAPHICS - &CGX_bootstrap; -#elif SDL_VIDEO_DRIVER_PHOTON - &ph_bootstrap; -#elif SDL_VIDEO_DRIVER_DC - &DC_bootstrap; -#else - NULL; -#endif - -static int -glSDL_Available(void) -{ -#ifdef DEBUG_GLSDL - fprintf(stderr, "available\n"); -#endif - if (opengl_bootstrap == NULL) - return 0; - return (opengl_bootstrap->available()); -} - -static void -glSDL_DeleteDevice(SDL_VideoDevice * device) -{ - SDL_free(device->hidden); - SDL_free(device); -} - -/* Create a glSDL device */ -static SDL_VideoDevice * -glSDL_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; -#ifdef DEBUG_GLSDL - fprintf(stderr, "entering createdevice\n"); -#endif - - /* Create the device with the underlying driver */ - device = opengl_bootstrap->create(devindex); - - /* Save the video device contents for future use */ - SDL_memcpy(&underlying_device, device, sizeof(SDL_VideoDevice)); - - /* Hook glSDL on the video device */ - device->VideoInit = glSDL_VideoInit; - device->ListModes = glSDL_ListModes; - device->VideoQuit = glSDL_VideoQuit; - device->UpdateRects = glSDL_UpdateRects; - device->FillHWRect = glSDL_FillHWRect; - device->SetHWColorKey = glSDL_SetHWColorKey; - device->SetHWAlpha = glSDL_SetHWAlpha; - device->AllocHWSurface = glSDL_AllocHWSurface; - device->LockHWSurface = glSDL_LockHWSurface; - device->UnlockHWSurface = glSDL_UnlockHWSurface; - device->FlipHWSurface = glSDL_FlipHWSurface; - device->FreeHWSurface = glSDL_FreeHWSurface; - device->CheckHWBlit = glSDL_CheckHWBlit; - device->SetColors = glSDL_SetColors; - device->SetVideoMode = glSDL_SetVideoMode; - device->info.hw_available = 1; - device->info.blit_hw = 1; - device->info.blit_hw_CC = 1; - device->info.blit_hw_A = 1; - device->info.blit_sw = 1; - device->info.blit_sw_CC = 1; - device->info.blit_sw_A = 1; - device->info.blit_fill = 1; - - /* These functions are not supported by glSDL, so we NULLify them */ - device->SetGamma = NULL; - device->GetGamma = NULL; - device->SetGammaRamp = NULL; - device->GetGammaRamp = NULL; - device->ToggleFullScreen = NULL; - - device->free = glSDL_DeleteDevice; - -#ifdef DEBUG_GLSDL - fprintf(stderr, "leaving createdevice\n"); -#endif - - return device; -} - -/* Our bootstraping structure */ -VideoBootStrap glSDL_bootstrap = { - "glSDL", "glSDL - SDL over OpenGL", - glSDL_Available, glSDL_CreateDevice -}; - -static int -glSDL_VideoInit(_THIS, SDL_PixelFormat * vformat) -{ - int r; - printf("glSDL videoinit\n"); -#ifdef DEBUG_GLSDL - fprintf(stderr, "videoinit\n"); -#endif - r = underlying_device.VideoInit(this, vformat); - this->info.hw_available = 1; - this->info.blit_hw = 1; - this->info.blit_hw_CC = 1; - this->info.blit_hw_A = 1; - this->info.blit_sw = 1; - this->info.blit_sw_CC = 1; - this->info.blit_sw_A = 1; - this->info.blit_fill = 1; - - return r; -} - -SDL_Rect ** -glSDL_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags) -{ - return ((SDL_Rect **) - 1); -} - -static void -glSDL_VideoQuit(_THIS) -{ - SDL_Surface *scr; - - /* free all hwdata structures */ - while (first != NULL) - glSDL_RemoveTexInfo(this, first); - - SDL_free(mirrorbuf); - mirrorbuf = NULL; - - SDL_FreeFormat(RGBfmt); - SDL_FreeFormat(RGBAfmt); - RGBfmt = RGBAfmt = NULL; - - SDL_FreeFormat(this->displayformatalphapixel); - this->displayformatalphapixel = NULL; - - SDL_FreeSurface(OpenGL_Surface); - OpenGL_Surface = NULL; - - /* restore the flags to gracefully exit from fullscreen */ - this->screen->flags = old_screen_flags; - - /* keep the screen */ - scr = this->screen; - - /* we cleaned up our stuff, now restore the underlying video driver */ - SDL_memcpy(this, &underlying_device, sizeof(SDL_VideoDevice)); - - this->screen = scr; - - /* call the underlying video driver's VideoQuit function */ - this->VideoQuit(this); -} - -static SDL_Surface * -glSDL_SetVideoMode(_THIS, SDL_Surface * current, int width, int height, - int bpp, Uint32 flags) -{ - SDL_Surface *hooked_screen; - int i; - int flag_doublebuf = 0; - - if (opengl_bootstrap == NULL) { - GLERR("No bootstrap for glSDL compiled in !\n"); - return NULL; - } - - /* we don't have OpenGL */ - if ((flags & SDL_INTERNALOPENGL) == SDL_INTERNALOPENGL) { - GLERR("OpenGL video modes are not supported by glSDL !\n"); - return (NULL); - } - - /* - * Adjust the flags - */ - flags &= ~SDL_HWPALETTE; - flags |= SDL_INTERNALOPENGL; - - /* remember whether the user requested DOUBLEBUF */ - - if (flags & SDL_DOUBLEBUF) { - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - flag_doublebuf = 1; - } else { - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); - flag_doublebuf = 0; - } - - hooked_screen = - underlying_device.SetVideoMode(this, current, width, height, 0, - flags); - - if (!hooked_screen) { - GLERR("Unable to open an OpenGL window !\n"); - return (NULL); - } - - /* save the screen flags for restore time */ - old_screen_flags = hooked_screen->flags; - -#ifdef DEBUG_GLSDL - fprintf(stderr, "got %d bpp\n", bpp); -#endif - - /* setup the public surface format - * glSDL always returns the bpp its asked - */ - switch (bpp) { - case 32: - this->is_32bit = 1; - this->screen = SDL_CreateRGBSurface(flags, width, height, bpp, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x00FF0000, - 0x0000FF00, 0x000000FF, 0x00000000 -#else - 0x0000FF00, - 0x00FF0000, 0xFF000000, 0x00000000 -#endif - ); - break; - case 24: - this->is_32bit = 0; - this->screen = SDL_CreateRGBSurface(flags, width, height, bpp, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x00FF0000, - 0x0000FF00, 0x000000FF, 0x00000000 -#else - 0x0000FF00, - 0x00FF0000, 0xFF000000, 0x00000000 -#endif - ); - break; - case 16: - this->is_32bit = 0; - this->screen = SDL_CreateRGBSurface(flags, width, height, bpp, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x0000F800, - 0x000007E0, 0x0000001F, 0x00000000 -#else - 0x0000001F, - 0x000007E0, 0x0000F800, 0x00000000 -#endif - ); - break; - case 15: - this->is_32bit = 0; - this->screen = SDL_CreateRGBSurface(flags, width, height, bpp, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x00007C00, - 0x000003E0, 0x0000001F, 0x00000000 -#else - 0x0000001F, - 0x000003E0, 0x00007C00, 0x00000000 -#endif - ); - break; - case 8: - default: - this->is_32bit = 0; - this->screen = - SDL_CreateRGBSurface(flags, width, height, bpp, 0, 0, 0, 0); - /* give it a default palette if 8 bpp - * note : SDL already takes care of the palette for 4 bits & 1 bit surfaces - */ -/* if (bpp==8) - { - this->screen->format->palette->ncolors=255; - SDL_DitherColors(this->screen->format->palette->colors,bpp); - }*/ - break; - } - - /* also, we add SDL_HWSURFACE all the time, and let SDL create a shadow surface accordingly */ - this->screen->flags = - hooked_screen->flags | SDL_HWSURFACE | SDL_INTERNALOPENGL; - /* add SDL_DOUBLEBUF if it was requested */ - if (flag_doublebuf) - this->screen->flags |= SDL_DOUBLEBUF; - - /* Tell SDL the alpha pixel format we'd like to have */ - this->displayformatalphapixel = SDL_AllocFormat(32, -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - 0xFF000000, - 0x00FF0000, - 0x0000FF00, 0x000000FF -#else - 0x000000FF, - 0x0000FF00, - 0x00FF0000, 0xFF000000 -#endif - ); - - /* Now create the raw OpenGL surface */ - OpenGL_Surface = SDL_CreateRGBSurface(flags, width, height, 24, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x000000FF, - 0x0000FF00, 0x00FF0000, 0x00000000 -#else - 0xFF000000, - 0x00FF0000, 0x0000FF00, 0x00000000 -#endif - ); - - /* Here we have to setup OpenGL funcs ourselves */ -#ifndef __QNXNTO__ -#define SDL_PROC(ret,func,params) \ - do { \ - this->func = SDL_GL_GetProcAddress(#func); \ - if ( ! this->func ) { \ - SDL_SetError("Couldn't load GL function: %s\n", #func); \ - return(NULL); \ - } \ - } while ( 0 ); -#else -#define SDL_PROC(ret,func,params) this->func=func; -#endif /* __QNXNTO__ */ -#include "../SDL_glfuncs.h" -#undef SDL_PROC - - if (this->GL_MakeCurrent(this) < 0) - return (NULL); -#define SDL_PROC(ret,func,params) \ - do { \ - this->func = SDL_GL_GetProcAddress(#func); \ - if ( ! this->func ) { \ - SDL_SetError("Couldn't load GL function: %s\n", #func); \ - return(NULL); \ - } \ - } while ( 0 ); -#include "../SDL_glfuncs.h" -#undef SDL_PROC - - -#ifdef FAKE_MAXTEXSIZE - maxtexsize = FAKE_MAXTEXSIZE; -#else - this->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize); -#endif -#ifdef DEBUG_GLSDL - fprintf(stderr, "glSDL: Max texture size: %d\n", maxtexsize); -#endif - - glSDL_init_formats(this); - - if (flag_doublebuf) - this->glDrawBuffer(GL_BACK); - else - this->glDrawBuffer(GL_FRONT); - - this->glDisable(GL_DITHER); - - if (glSDL_AddTexInfo(this, this->screen) < 0) { - GLERR("HookDevice() failed to add info to screen surface!"); - return NULL; - } - - glSDL_SetLogicSize(this, this->screen, this->screen->w, this->screen->h); - - glSDL_do_texture(this, 0); - glSDL_do_blend(this, 0); - - for (i = 0; i < 1 + flag_doublebuf; ++i) { - this->glBegin(GL_TRIANGLE_FAN); - this->glColor3ub(0, 0, 0); - this->glVertex2i(0, 0); - this->glVertex2i(this->screen->w, 0); - this->glVertex2i(this->screen->w, this->screen->h); - this->glVertex2i(0, this->screen->h); - this->glEnd(); - if (!i) - this->GL_SwapBuffers(this); - } - - mirrorbuf = SDL_malloc(this->screen->h * this->screen->pitch); - if (!mirrorbuf) { - GLERR("HookDevice() failed to allocate temp buffer for mirroring!"); - return NULL; - } - - return this->screen; -} - -static int -glSDL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors) -{ - /* We don't need to fill this one */ - return 0; -} - - -#ifdef DEBUG_GLSDL -static void -glSDL_print_glerror(_THIS, int point) -{ - const char *err = "<unknown>"; - switch (this->glGetError()) { - case GL_NO_ERROR: - return; - case GL_INVALID_ENUM: - err = "GL_INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - err = "GL_INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - err = "GL_INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - err = "GL_STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - err = "GL_STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - err = "GL_OUT_OF_MEMORY"; - default: - break; - } - fprintf(stderr, "OpenGL error \"%s\" at point %d.\n", err, point); -} -#endif - -/* Get texinfo for a surface. */ -static __inline__ private_hwdata * -glSDL_GetTexInfo(SDL_Surface * surface) -{ - if (!surface) - return NULL; - return surface->hwdata; -} - - -/* Allocate a "blank" texinfo for a suface. */ -static private_hwdata * -glSDL_AllocTexInfo(SDL_Surface * surface) -{ - private_hwdata *txi; - if (!surface) - return NULL; - - txi = glSDL_GetTexInfo(surface); - if (txi) - return txi; /* There already is one! --> */ - - /* ...and hook a new texinfo struct up to it. */ - txi = (private_hwdata *) SDL_calloc(1, sizeof(private_hwdata)); - if (!txi) { - GLERR("AllocTexInfo(): Failed allocating TexInfo struct!"); - return NULL; - } - txi->temporary = 1; -#ifdef DEBUG_GLSDL - fprintf(stderr, "glSDL: Allocated TexInfo %p.\n", txi); -#endif - return txi; -} - - -static void -glSDL_FreeTexInfo(_THIS, private_hwdata * txi) -{ - if (!txi) - return; - - glSDL_UnloadTexture(this, txi); - SDL_free(txi->texture); - SDL_free(txi); -#ifdef DEBUG_GLSDL - fprintf(stderr, "glSDL: Freed TexInfo %p.\n", txi); -#endif -} - - -/* Detach and free the texinfo of a surface. */ -static void -glSDL_RemoveTexInfo(_THIS, SDL_Surface * surface) -{ - SDL_Surface *next, *prev; - if (!glSDL_GetTexInfo(surface)) - return; - - /* maintain our doubly linked list */ - next = surface->hwdata->next; - prev = surface->hwdata->prev; - if (prev != NULL) { - prev->hwdata->next = next; - } else { - first = next; - } - if (next != NULL) { - next->hwdata->prev = prev; - } - - glSDL_FreeTexInfo(this, surface->hwdata); - surface->hwdata = NULL; -} - - -/* - * Calculate chopping/tiling of a surface to - * fit it into the smallest possible OpenGL - * texture. - */ -static int -glSDL_CalcChop(private_hwdata * txi) -{ - int rows, vw, vh; - int vertical = 0; - int texsize; - int lastw, lasth, minsize; - - vw = txi->virt.w; - vh = txi->virt.h; - -#ifdef DEBUG_GLSDL_CHOP - fprintf(stderr, "w=%d, h=%d ", vw, vh); -#endif - if (vh > vw) { - int t = vw; - vw = vh; - vh = t; - vertical = 1; -#ifdef DEBUG_GLSDL_CHOP - fprintf(stderr, "(vertical) \t"); -#endif - } - - /* - * Check whether this is a "huge" surface - at least one dimension - * must be <= than the maximum texture size, or we'll have to chop - * in both directions. - */ -#ifdef DEBUG_GLSDL - if (maxtexsize < 0) - return GLERET("glSDL_CalcChop() called before OpenGL init!"); -#endif - if (vh > maxtexsize) { - /* - * Very simple hack for now; we just tile - * both ways with maximum size textures. - */ - texsize = maxtexsize; - - txi->tilemode = GLSDL_TM_HUGE; - txi->texsize = texsize; - txi->tilew = texsize; - txi->tileh = texsize; - txi->tilespertex = 1; - - /* Calculate number of textures needed */ - txi->textures = (vw + texsize - 1) / texsize; - txi->textures *= (vh + texsize - 1) / texsize; - txi->texture = SDL_malloc(txi->textures * sizeof(int)); - SDL_memset(txi->texture, -1, txi->textures * sizeof(int)); -#ifdef DEBUG_GLSDL - fprintf(stderr, "two-way tiling; textures=%d\n", txi->textures); -#endif - if (!txi->texture) { - fprintf(stderr, "glSDL: INTERNAL ERROR: Failed to allocate" - " texture name table!\n"); - return -3; - } - return 0; - } - - /* Calculate minimum size */ - rows = 1; - lastw = vw; - lasth = vh; - minsize = lastw > lasth ? lastw : lasth; - while (1) { - int w, h, size; - ++rows; - w = vw / rows; - h = rows * vh; - size = w > h ? w : h; - if (size >= minsize) { - --rows; - break; - } - lastw = w; - lasth = h; - minsize = size; - } - if (minsize > maxtexsize) { - /* Handle multiple textures for very wide/tall surfaces. */ - minsize = maxtexsize; - rows = (vw + minsize - 1) / minsize; - } -#ifdef DEBUG_GLSDL_CHOP - fprintf(stderr, "==> minsize=%d ", minsize); - fprintf(stderr, "(rows=%d) \t", rows); -#endif - - /* Recalculate with nearest higher power-of-2 width. */ - for (texsize = 1; texsize < minsize; texsize <<= 1); - txi->texsize = texsize; - rows = (vw + texsize - 1) / texsize; -#ifdef DEBUG_GLSDL_CHOP - fprintf(stderr, "==> texsize=%d (rows=%d) \t", texsize, rows); -#endif - - /* Calculate number of tiles per texture */ - txi->tilespertex = txi->texsize / vh; -#ifdef DEBUG_GLSDL_CHOP - fprintf(stderr, "tilespertex=%d \t", txi->tilespertex); -#endif - - /* Calculate number of textures needed */ - txi->textures = (rows + txi->tilespertex - 1) / txi->tilespertex; - txi->texture = (GLuint *) SDL_malloc(txi->textures * sizeof(GLuint)); - SDL_memset(txi->texture, GLSDL_NOTEX, txi->textures * sizeof(GLuint)); -#ifdef DEBUG_GLSDL_CHOP - fprintf(stderr, "textures=%d, ", txi->textures); -#endif - if (!txi->texture) - return GLERET("Failed to allocate texture name table!"); - - /* Set up tile size. (Only one axis supported here!) */ - if (1 == rows) { - txi->tilemode = GLSDL_TM_SINGLE; - if (vertical) { - txi->tilew = vh; - txi->tileh = vw; - } else { - txi->tilew = vw; - txi->tileh = vh; - } - } else if (vertical) { - txi->tilemode = GLSDL_TM_VERTICAL; - txi->tilew = vh; - txi->tileh = texsize; - } else { - txi->tilemode = GLSDL_TM_HORIZONTAL; - txi->tilew = texsize; - txi->tileh = vh; - } - -#ifdef DEBUG_GLSDL_CHOP - fprintf(stderr, "tilew=%d, tileh=%d\n", txi->tilew, txi->tileh); -#endif - return 0; -} - - -/* Create a temporary TexInfo struct for an SDL_Surface */ -static private_hwdata * -glSDL_CreateTempTexInfo(_THIS, SDL_Surface * surface) -{ - private_hwdata *txi; - if (!surface) { - GLERR("CreateTempTexInfo(); no surface!"); - return NULL; - } - if (IS_GLSDL_SURFACE(surface)) - return glSDL_GetTexInfo(surface); /* Do nothing */ - - txi = glSDL_AllocTexInfo(surface); - if (!txi) { - GLERR("CreateTempTexInfo(); Could not alloc TexInfo!"); - return NULL; - } - txi->virt.w = txi->lw = surface->w; - txi->virt.h = txi->lh = surface->h; - - if (glSDL_CalcChop(txi) < 0) { - glSDL_FreeTexInfo(this, txi); - GLERR("CreateTempTexInfo(); CalcChop() failed!"); - return NULL; - } - - return txi; -} - -/* Add a glSDL_TexInfo struct to an SDL_Surface */ -static private_hwdata * -glSDL_AddTexInfo(_THIS, SDL_Surface * surface) -{ - private_hwdata *txi = glSDL_CreateTempTexInfo(this, surface); - if (!txi) - return NULL; - - /* Connect the surface to the new TexInfo. */ - txi->temporary = 0; - surface->hwdata = txi; - - /* add this new surface in front of the list of hw surfaces */ - txi->next = first; - txi->prev = NULL; - first = surface; - if (txi->next != NULL) { - txi->next->hwdata->prev = surface; - } - - SDL_SetClipRect(surface, &txi->virt); - return txi; -} - - -/* Create a surface of the prefered OpenGL RGB texture format */ -/*static SDL_Surface *glSDL_CreateRGBSurface(int w, int h) -{ - SDL_Surface *s; - Uint32 rmask, gmask, bmask; - int bits = 24; -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - rmask = 0x000000FF; - gmask = 0x0000FF00; - bmask = 0x00FF0000; -#else - rmask = 0x00FF0000; - gmask = 0x0000FF00; - bmask = 0x000000FF; -#endif - s = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, - bits, rmask, gmask, bmask, 0); - if(s) - s->flags |= SDL_HWACCEL; - - return s; -} -*/ - -/* Create a surface of the prefered OpenGL RGBA texture format */ -static SDL_Surface * -glSDL_CreateRGBASurface(int w, int h) -{ - SDL_Surface *s; - Uint32 rmask, gmask, bmask, amask; - int bits = 32; -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - rmask = 0x000000FF; - gmask = 0x0000FF00; - bmask = 0x00FF0000; - amask = 0xFF000000; -#else - rmask = 0xFF000000; - gmask = 0x00FF0000; - bmask = 0x0000FF00; - amask = 0x000000FF; -#endif - s = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, - bits, rmask, gmask, bmask, amask); - if (s) - s->flags |= SDL_HWACCEL; - - return s; -} - - -static void -glSDL_init_formats(_THIS) -{ - RGBfmt = SDL_AllocFormat(24, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x000000FF, 0x0000FF00, 0x00FF0000, 0); -#else - 0x00FF0000, 0x0000FF00, 0x000000FF, 0); -#endif - RGBAfmt = SDL_AllocFormat(32, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); -#else - 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); -#endif -} - - -static int -glSDL_FormatIsOk(SDL_Surface * surface) -{ - SDL_PixelFormat *pf; - if (!surface) - return 1; /* Well, there ain't much we can do anyway... */ - - pf = surface->format; - - /* Colorkeying requires an alpha channel! */ - if (surface->flags & SDL_SRCCOLORKEY) - if (!pf->Amask) - return 0; - - /* We need pitch == (width * BytesPerPixel) for glTex[Sub]Image2D() */ - if (surface->pitch != (surface->w * pf->BytesPerPixel)) - return 0; - - if (pf->Amask) { - if (pf->BytesPerPixel != RGBAfmt->BytesPerPixel) - return 0; - if (pf->Rmask != RGBAfmt->Rmask) - return 0; - if (pf->Gmask != RGBAfmt->Gmask) - return 0; - if (pf->Bmask != RGBAfmt->Bmask) - return 0; - if (pf->Amask != RGBAfmt->Amask) - return 0; - } else { - if (pf->BytesPerPixel != RGBfmt->BytesPerPixel) - return 0; - if (pf->Rmask != RGBfmt->Rmask) - return 0; - if (pf->Gmask != RGBfmt->Gmask) - return 0; - if (pf->Bmask != RGBfmt->Bmask) - return 0; - } - return 1; -} - -static void -glSDL_key2alpha(SDL_Surface * surface) -{ - int x, y; - Uint32 ckey = surface->format->colorkey; - -#ifdef DEBUG_GLSDL - fprintf(stderr, "glSDL_key2alpha()\n"); -#endif - for (y = 0; y < surface->h; ++y) { - Uint32 *px = - (Uint32 *) ((char *) surface->pixels + y * surface->pitch); - for (x = 0; x < surface->w; ++x) - if (px[x] == ckey) - px[x] = 0; - } -} - - - -/*---------------------------------------------------------- - SDL style API - ----------------------------------------------------------*/ - -static int -glSDL_FlipHWSurface(_THIS, SDL_Surface * surface) -{ -#ifdef GLSDL_GRAPHICAL_DEBUG - this->glDisable(GL_TEXTURE_2D); - this->glBegin(GL_LINE_LOOP); - this->glColor4ub(0, 0, 255, 128); - this->glVertex2i(0, 0); - this->glVertex2i(surface->w, 0); - this->glVertex2i(surface->w, surface->h); - this->glVertex2i(0, surface->h); - this->glEnd(); - this->glEnable(GL_TEXTURE_2D); -#endif - if (this->screen->flags & SDL_DOUBLEBUF) - this->GL_SwapBuffers(this); - else - this->glFinish(); - return 0; -} - - -static void -glSDL_UpdateRects(_THIS, int numrects, SDL_Rect * rects) -{ -#ifdef GLSDL_GRAPHICAL_DEBUG - int i; - this->glDisable(GL_TEXTURE_2D); - for (i = 0; i < numrects; i++) { - this->glColor4ub(255, 0, 0, 128); - this->glBegin(GL_LINE_LOOP); - this->glVertex2i(rects[i].x, rects[i].y); - this->glVertex2i(rects[i].x + rects[i].w, rects[i].y); - this->glVertex2i(rects[i].x + rects[i].w, rects[i].y + rects[i].h); - this->glVertex2i(rects[i].x, rects[i].y + rects[i].h); - this->glEnd(); - } - this->glEnable(GL_TEXTURE_2D); -#endif - if (this->screen->flags & SDL_DOUBLEBUF) - this->GL_SwapBuffers(this); - else - this->glFinish(); -} - - -static int -glSDL_AllocHWSurface(_THIS, SDL_Surface * surface) -{ - surface->flags |= (SDL_HWSURFACE | SDL_HWACCEL); - - surface->pixels = SDL_malloc(surface->h * surface->pitch); - if (surface->pixels == NULL) { - SDL_FreeSurface(surface); - SDL_OutOfMemory(); - return (-1); - } - SDL_memset(surface->pixels, 0, surface->h * surface->pitch); - return 0; -} - - -static void -glSDL_FreeHWSurface(_THIS, SDL_Surface * surface) -{ - if (!surface) - return; - glSDL_RemoveTexInfo(this, surface); -} - - -static int -glSDL_LockHWSurface(_THIS, SDL_Surface * surface) -{ - int y; - - if (!surface) - return -1; - -#ifdef DEBUG_GLSDL - fprintf(stderr, "glSDL: Lock Surface.\n"); -#endif - - if (SDL_VideoSurface == surface) { - glSDL_Invalidate(surface, NULL); - this->glPixelStorei(GL_UNPACK_ROW_LENGTH, - surface->pitch / surface->format->BytesPerPixel); - this->glReadPixels(0, 0, OpenGL_Surface->w, OpenGL_Surface->h, - GL_RGB, GL_UNSIGNED_BYTE, OpenGL_Surface->pixels); - for (y = 0; y < OpenGL_Surface->h / 2; ++y) { - void *upper = (Uint8 *) OpenGL_Surface->pixels + - OpenGL_Surface->pitch * y; - void *lower = (Uint8 *) OpenGL_Surface->pixels + - OpenGL_Surface->pitch * (OpenGL_Surface->h - y - 1); - SDL_memcpy(mirrorbuf, upper, OpenGL_Surface->pitch); - SDL_memcpy(upper, lower, OpenGL_Surface->pitch); - SDL_memcpy(lower, mirrorbuf, OpenGL_Surface->pitch); - } - /* the mapping has to be invalidated on 8bpp video surfaces in case of a hw palette change. - * Now if someone could tell me why this is not handled by SDL... */ - if (SDL_VideoSurface->format->BitsPerPixel == 8) - SDL_InvalidateMap(OpenGL_Surface->map); - - /* convert this raw surface to the application-requested format - * FIXME this is sometimes overkill, we could use glPixelStore smartly - * But this would be slow anyway :) */ - - glSDL_SoftBlit(OpenGL_Surface, NULL, SDL_VideoSurface, NULL); - } else - glSDL_Invalidate(surface, NULL); - - return 0; -} - - -static void -glSDL_UnlockHWSurface(_THIS, SDL_Surface * surface) -{ - private_hwdata *txi; - - if (!surface) - return; - - /* upload this surface ONLY if this is a glSDL surface - * because sometimes (during displayformating for ex.) surfaces are unlocked that aren't glSDL - */ - if (!IS_GLSDL_SURFACE(surface)) - return; - -#ifdef DEBUG_GLSDL - fprintf(stderr, "glSDL: Unlock Surface.\n"); -#endif - - txi = glSDL_UploadSurface(this, surface); - - if (!txi) { - GLERR("glSDL_UnlockHWSurface() failed to upload surface!"); - return; - } - if (txi->temporary) { - GLERR - ("Weirdness... glSDL_UnlockHWSurface() got a temporary TexInfo."); - return; - } - if (surface == SDL_VideoSurface) - glSDL_BlitGL(this, SDL_VideoSurface, NULL, NULL); -} - - -static int -glSDL_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key) -{ - /* - * If an application does this *after* SDL_DisplayFormat, - * we're basically screwed, unless we want to do an - * in-place surface conversion hack here. - * - * What we do is just kill the glSDL texinfo... No big - * deal in most cases, as glSDL only converts once anyway, - * *unless* you keep modifying the surface. - */ - if (IS_GLSDL_SURFACE(surface)) - glSDL_RemoveTexInfo(this, surface); - return 0; -} - - -static int -glSDL_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha) -{ - /* - * If an application does this *after* SDL_DisplayFormat, - * we're basically screwed, unless we want to do an - * in-place surface conversion hack here. - * - * What we do is just kill the glSDL texinfo... No big - * deal in most cases, as glSDL only converts once anyway, - * *unless* you keep modifying the surface. - */ - if (IS_GLSDL_SURFACE(surface)) - glSDL_RemoveTexInfo(this, surface); - return 0; -} - -static SDL_bool -glSDL_SetClipRect(_THIS, SDL_Surface * surface, SDL_Rect * rect) -{ - SDL_bool res; - if (!surface) - return SDL_FALSE; - - res = SDL_SetClipRect(surface, rect); - if (!res) - return SDL_FALSE; - - rect = &surface->clip_rect; - - if (surface == SDL_VideoSurface) { - SDL_Rect r; - float xscale, yscale; - private_hwdata *txi; - - r.x = rect->x; - r.y = rect->y; - r.w = rect->w; - r.h = rect->h; - SDL_SetClipRect(surface, rect); - - txi = glSDL_GetTexInfo(surface); - if (!txi) - return GLERET("SetClipRect(): Could not get TexInfo!"); - - this->glViewport(rect->x, - surface->h - (rect->y + rect->h), rect->w, rect->h); - /* - * Note that this projection is upside down in - * relation to the OpenGL coordinate system. - */ - this->glMatrixMode(GL_PROJECTION); - this->glLoadIdentity(); - xscale = (float) txi->lw / (float) surface->w; - yscale = (float) txi->lh / (float) surface->h; - this->glOrtho(xscale * (float) rect->x, - xscale * (float) (rect->w + rect->x), - yscale * (float) (rect->h + rect->y), - yscale * (float) rect->y, -1.0, 1.0); - return SDL_TRUE; - } - return res; -} - -static int -glSDL_BlitFromGL(_THIS, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) -{ - SDL_Rect sr, dr; - - /* In case the destination has an OpenGL texture... */ - glSDL_Invalidate(dst, dstrect); - - /* Abuse the fake screen buffer a little. */ - this->glPixelStorei(GL_UNPACK_ROW_LENGTH, SDL_VideoSurface->pitch / - SDL_VideoSurface->format->BytesPerPixel); - if (srcrect) - this->glReadPixels(srcrect->x, - OpenGL_Surface->h - (srcrect->y + srcrect->h - 1), - srcrect->w, srcrect->h, GL_RGB, GL_UNSIGNED_BYTE, - OpenGL_Surface->pixels); - else - this->glReadPixels(0, 0, OpenGL_Surface->w, OpenGL_Surface->h, - GL_RGB, GL_UNSIGNED_BYTE, OpenGL_Surface->pixels); - sr = *srcrect; - dr = *dstrect; - glSDL_SoftBlit(OpenGL_Surface, &sr, dst, &dr); - return 0; -} - -static __inline__ void -glSDL_BlitGL_single(_THIS, private_hwdata * txi, - float sx1, float sy1, SDL_Rect * dst, unsigned char alpha) -{ - float sx2, sy2, texscale; - if (!txi->textures) - return; - if (-1 == txi->texture[0]) - return; - glSDL_texture(this, txi->texture[0]); - - texscale = 1.0 / (float) txi->texsize; - sx2 = (sx1 + (float) dst->w) * texscale; - sy2 = (sy1 + (float) dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - -#ifdef GLSDL_GRAPHICAL_DEBUG - this->glDisable(GL_TEXTURE_2D); - this->glBegin(GL_LINE_LOOP); - this->glColor4ub(0, 255, 0, 128); - this->glVertex2i(dst->x, dst->y); - this->glVertex2i(dst->x + dst->w, dst->y); - this->glVertex2i(dst->x + dst->w, dst->y + dst->h); - this->glVertex2i(dst->x, dst->y + dst->h); - this->glEnd(); - this->glEnable(GL_TEXTURE_2D); -#endif - - this->glBegin(GL_TRIANGLE_FAN); - this->glColor4ub(255, 255, 255, alpha); - this->glTexCoord2f(sx1, sy1); - this->glVertex2i(dst->x, dst->y); - this->glTexCoord2f(sx2, sy1); - this->glVertex2i(dst->x + dst->w, dst->y); - this->glTexCoord2f(sx2, sy2); - this->glVertex2i(dst->x + dst->w, dst->y + dst->h); - this->glTexCoord2f(sx1, sy2); - this->glVertex2i(dst->x, dst->y + dst->h); - this->glEnd(); -} - - -static void -glSDL_BlitGL_htile(_THIS, private_hwdata * txi, - float sx1, float sy1, SDL_Rect * dst, unsigned char alpha) -{ - int tex; - float tile, sx2, sy2, yo; - float texscale = 1.0 / (float) txi->texsize; - float tileh = (float) txi->tileh * texscale; - sx2 = (sx1 + (float) dst->w) * texscale; - sy2 = (sy1 + (float) dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - tile = floor(sx1); - tex = (int) tile / txi->tilespertex; - yo = ((int) tile % txi->tilespertex) * tileh; - - if (tex >= txi->textures) - return; - if (-1 == txi->texture[tex]) - return; - glSDL_texture(this, txi->texture[tex]); - - while (tile < sx2) { - int tdx1 = dst->x; - int tdx2 = dst->x + dst->w; - float tsx1 = sx1 - tile; - float tsx2 = sx2 - tile; - - /* Clip to current tile */ - if (tsx1 < 0.0) { - tdx1 -= tsx1 * txi->texsize; - tsx1 = 0.0; - } - if (tsx2 > 1.0) { - tdx2 -= (tsx2 - 1.0) * txi->texsize; - tsx2 = 1.0; - } - - /* Maybe select next texture? */ - if (yo + tileh > 1.0) { - ++tex; - if (tex >= txi->textures) - return; - if (-1 == txi->texture[tex]) - return; - glSDL_texture(this, txi->texture[tex]); - yo = 0.0; - } -#ifdef GLSDL_GRAPHICAL_DEBUG - this->glDisable(GL_TEXTURE_2D); - this->glBegin(GL_LINE_LOOP); - this->glColor4ub(0, 255, 0, 128); - this->glVertex2i(tdx1, dst->y); - this->glVertex2i(tdx2, dst->y); - this->glVertex2i(tdx2, dst->y + dst->h); - this->glVertex2i(tdx1, dst->y + dst->h); - this->glEnd(); - this->glEnable(GL_TEXTURE_2D); -#endif - - this->glBegin(GL_TRIANGLE_FAN); - this->glColor4ub(255, 255, 255, alpha); - this->glTexCoord2f(tsx1, yo + sy1); - this->glVertex2i(tdx1, dst->y); - this->glTexCoord2f(tsx2, yo + sy1); - this->glVertex2i(tdx2, dst->y); - this->glTexCoord2f(tsx2, yo + sy2); - this->glVertex2i(tdx2, dst->y + dst->h); - this->glTexCoord2f(tsx1, yo + sy2); - this->glVertex2i(tdx1, dst->y + dst->h); - this->glEnd(); - tile += 1.0; - yo += tileh; - } -} - - -static void -glSDL_BlitGL_vtile(_THIS, private_hwdata * txi, - float sx1, float sy1, SDL_Rect * dst, unsigned char alpha) -{ - int tex; - float tile, sx2, sy2, xo; - float texscale = 1.0 / (float) txi->texsize; - float tilew = (float) txi->tilew * texscale; - sx2 = (sx1 + (float) dst->w) * texscale; - sy2 = (sy1 + (float) dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - tile = floor(sy1); - tex = (int) tile / txi->tilespertex; - xo = ((int) tile % txi->tilespertex) * tilew; - - if (tex >= txi->textures) - return; - if (-1 == txi->texture[tex]) - return; - glSDL_texture(this, txi->texture[tex]); - - while (tile < sy2) { - int tdy1 = dst->y; - int tdy2 = dst->y + dst->h; - float tsy1 = sy1 - tile; - float tsy2 = sy2 - tile; - - /* Clip to current tile */ - if (tsy1 < 0.0) { - tdy1 -= tsy1 * txi->texsize; - tsy1 = 0.0; - } - if (tsy2 > 1.0) { - tdy2 -= (tsy2 - 1.0) * txi->texsize; - tsy2 = 1.0; - } - - /* Maybe select next texture? */ - if (xo + tilew > 1.0) { - ++tex; - if (tex >= txi->textures) - return; - if (-1 == txi->texture[tex]) - return; - glSDL_texture(this, txi->texture[tex]); - xo = 0.0; - } -#ifdef GLSDL_GRAPHICAL_DEBUG - this->glDisable(GL_TEXTURE_2D); - this->glBegin(GL_LINE_LOOP); - this->glColor4ub(0, 255, 0, 128); - this->glVertex2i(dst->x, tdy1); - this->glVertex2i(dst->x + dst->w, tdy1); - this->glVertex2i(dst->x + dst->w, tdy2); - this->glVertex2i(dst->x, tdy2); - this->glEnd(); - this->glEnable(GL_TEXTURE_2D); -#endif - - this->glBegin(GL_TRIANGLE_FAN); - this->glColor4ub(255, 255, 255, alpha); - this->glTexCoord2f(xo + sx1, tsy1); - this->glVertex2i(dst->x, tdy1); - this->glTexCoord2f(xo + sx2, tsy1); - this->glVertex2i(dst->x + dst->w, tdy1); - this->glTexCoord2f(xo + sx2, tsy2); - this->glVertex2i(dst->x + dst->w, tdy2); - this->glTexCoord2f(xo + sx1, tsy2); - this->glVertex2i(dst->x, tdy2); - this->glEnd(); - - tile += 1.0; - xo += tilew; - } -} - - -static void -glSDL_BlitGL_hvtile(_THIS, SDL_Surface * src, private_hwdata * txi, - float sx1, float sy1, SDL_Rect * dst, unsigned char alpha) -{ - int x, y, last_tex, tex; - float sx2, sy2; - float texscale = 1.0 / (float) txi->texsize; - int tilesperrow = (src->w + txi->tilew - 1) / txi->tilew; - sx2 = (sx1 + (float) dst->w) * texscale; - sy2 = (sy1 + (float) dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - - last_tex = tex = floor(sy1) * tilesperrow + floor(sx1); - if (tex >= txi->textures) - return; - if (-1 == txi->texture[tex]) - return; - glSDL_texture(this, txi->texture[tex]); - - for (y = floor(sy1); y < sy2; ++y) { - int tdy1 = dst->y; - int tdy2 = dst->y + dst->h; - float tsy1 = sy1 - y; - float tsy2 = sy2 - y; - - /* Clip to current tile */ - if (tsy1 < 0.0) { - tdy1 -= tsy1 * txi->texsize; - tsy1 = 0.0; - } - if (tsy2 > 1.0) { - tdy2 -= (tsy2 - 1.0) * txi->texsize; - tsy2 = 1.0; - } - for (x = floor(sx1); x < sx2; ++x) { - int tdx1 = dst->x; - int tdx2 = dst->x + dst->w; - float tsx1 = sx1 - x; - float tsx2 = sx2 - x; - - /* Clip to current tile */ - if (tsx1 < 0.0) { - tdx1 -= tsx1 * txi->texsize; - tsx1 = 0.0; - } - if (tsx2 > 1.0) { - tdx2 -= (tsx2 - 1.0) * txi->texsize; - tsx2 = 1.0; - } - - /* Select texture */ - tex = y * tilesperrow + x; - if (tex != last_tex) { - if (tex >= txi->textures) - return; - if (-1 == txi->texture[tex]) - return; - glSDL_texture(this, txi->texture[tex]); - last_tex = tex; - } -#ifdef GLSDL_GRAPHICAL_DEBUG - this->glDisable(GL_TEXTURE_2D); - this->glBegin(GL_LINE_LOOP); - this->glColor4ub(0, 255, 0, 128); - this->glVertex2i(tdx1, tdy1); - this->glVertex2i(tdx2, tdy1); - this->glVertex2i(tdx2, tdy2); - this->glVertex2i(tdx1, tdy2); - this->glEnd(); - this->glEnable(GL_TEXTURE_2D); -#endif - - this->glBegin(GL_TRIANGLE_FAN); - this->glColor4ub(255, 255, 255, alpha); - this->glTexCoord2f(tsx1, tsy1); - this->glVertex2i(tdx1, tdy1); - this->glTexCoord2f(tsx2, tsy1); - this->glVertex2i(tdx2, tdy1); - this->glTexCoord2f(tsx2, tsy2); - this->glVertex2i(tdx2, tdy2); - this->glTexCoord2f(tsx1, tsy2); - this->glVertex2i(tdx1, tdy2); - this->glEnd(); - } - } -} - -/* - * Calculate the actual blit rectangle and source offset - * for a blit from a rectangle in a surface with specified - * size to a surface with a cliprect. - * - * In: rect source rectangle - * w, h source surface size - * (x, y) destination coordinate - * clip destination clip rectangle - * - * Out: (x, y) source top-left offset - * rect destination rectangle - * - * Returns 1 if the result is visible, otherwise 0. - */ -static __inline__ int -blitclip(SDL_Rect * rect, int w, int h, int *x, int *y, SDL_Rect * clip) -{ - int sx1, sy1, sx2, sy2; - int dx1, dy1, dx2, dy2; - - /* Get source and destination coordinates */ - sx1 = rect->x; - sy1 = rect->y; - sx2 = sx1 + rect->w; - sy2 = sy1 + rect->h; - dx1 = *x; - dy1 = *y; - - /* Keep source rect inside source surface */ - if (sx1 < 0) { - dx1 -= sx1; - sx1 = 0; - } - if (sy1 < 0) { - dy1 -= sy1; - sy1 = 0; - } - if (sx2 > w) - sx2 = w; - if (sy2 > h) - sy2 = h; - - /* Cull blits from void space */ - if (sx1 >= sx2 || sy1 >= sy2) - return 0; - - /* Calculate destination lower-right */ - dx2 = dx1 + (sx2 - sx1); - dy2 = dy1 + (sy2 - sy1); - - /* Clip to destination cliprect */ - if (dx1 < clip->x) { - sx1 += clip->x - dx1; - dx1 = clip->x; - } - if (dy1 < clip->y) { - sy1 += clip->y - dy1; - dy1 = clip->y; - } - if (dx2 > clip->x + clip->w) - dx2 = clip->x + clip->w; - if (dy2 > clip->y + clip->h) - dy2 = clip->y + clip->h; - - /* Cull nop/off-screen blits */ - if (dx1 >= dx2 || dy1 >= dy2) - return 0; - - *x = sx1; - *y = sy1; - rect->x = dx1; - rect->y = dy1; - rect->w = dx2 - dx1; - rect->h = dy2 - dy1; - return 1; -} - -static int -glSDL_BlitGL(_THIS, SDL_Surface * src, SDL_Rect * srcrect, SDL_Rect * dstrect) -{ - private_hwdata *txi; - float x1, y1; - unsigned char alpha; - SDL_Rect d; - int x, y; - SDL_Rect r; - - if (!src) - return GLERET("BlitGL(): No src surface!"); - - /* Get source and destination coordinates */ - if (srcrect) - r = *srcrect; - else { - r.x = r.y = 0; - r.w = src->w; - r.h = src->h; - } - if (dstrect) { - x = dstrect->x; - y = dstrect->y; - } else - x = y = 0; - - /* Clip! */ - if (!blitclip(&r, src->w, src->h, &x, &y, &this->screen->clip_rect)) { - if (dstrect) - dstrect->w = dstrect->h = 0; - return 0; - } - - /* Write back the resulting cliprect */ - if (dstrect) - *dstrect = r; - - /* Make sure we have a source with a valid texture */ - txi = glSDL_UploadSurface(this, src); - if (!txi) - return GLERET("BlitGL(): Could not get a TexInfo!"); - - /* Set up blending */ - if (src->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY)) { - glSDL_blendfunc(this, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glSDL_do_blend(this, 1); - } else - glSDL_do_blend(this, 0); - - /* Enable texturing */ - glSDL_do_texture(this, 1); - - /* Calculate texcoords */ - if (!srcrect) - srcrect = &txi->virt; - x1 = (float) srcrect->x; - y1 = (float) srcrect->y; - - /* Calculate screen coords. */ - if (dstrect) { - d.x = dstrect->x; - d.y = dstrect->y; - d.w = (int) (srcrect->w * (float) txi->lw / (float) txi->virt.w); - d.h = (int) (srcrect->h * (float) txi->lh / (float) txi->virt.h); - } else { - d.x = 0; - d.y = 0; - d.w = (int) (srcrect->w * (float) txi->lw / (float) txi->virt.w); - d.h = (int) (srcrect->h * (float) txi->lh / (float) txi->virt.h); - } - - /* - * Note that we actually *prevent* the use of "full surface alpha" - * and alpha channel in combination - to stay SDL 2D compatible. - */ - if ((src->flags & SDL_SRCALPHA) && (src->format->Amask)) - alpha = 255; - else - alpha = src->format->alpha; - - /* Render! */ - switch (txi->tilemode) { - case GLSDL_TM_SINGLE: - glSDL_BlitGL_single(this, txi, x1, y1, &d, alpha); - break; - case GLSDL_TM_HORIZONTAL: - glSDL_BlitGL_htile(this, txi, x1, y1, &d, alpha); - break; - case GLSDL_TM_VERTICAL: - glSDL_BlitGL_vtile(this, txi, x1, y1, &d, alpha); - break; - case GLSDL_TM_HUGE: - glSDL_BlitGL_hvtile(this, src, txi, x1, y1, &d, alpha); - break; - } - - if (txi->temporary) - glSDL_FreeTexInfo(this, txi); - - return 0; -} - - -static int -glSDL_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) -{ - SDL_Surface *vs; - - if (!src) - return GLERET("HWAccelBlit(): No src surface!"); - if (!dst) - return GLERET("HWAccelBlit(): No dst surface!"); - - /* - * Figure out what to do: - * screen->screen: glSDL_BlitFromGL() + glSDL_BlitGL() - * surface->screen: glSDL_BlitGL() - * screen->surface: glSDL_BlitFromGL() - * surface->surface: glSDL_SoftBlit() - */ - vs = SDL_VideoSurface; - if (src == vs) { - if (dst == vs) { - /* - FIXME: Try glCopyPixels() instead... - */ - glSDL_BlitFromGL(current_video, srcrect, vs, dstrect); - return glSDL_BlitGL(current_video, vs, srcrect, dstrect); - } else { - return glSDL_BlitFromGL(current_video, srcrect, dst, dstrect); - } - } else { - if (dst == vs) { - return glSDL_BlitGL(current_video, src, srcrect, dstrect); - } else { - glSDL_Invalidate(dst, dstrect); - glSDL_SoftBlit(src, srcrect, dst, dstrect); - return 0; - } - } -} - - -static int -glSDL_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color) -{ - SDL_Surface *vs = SDL_VideoSurface; - int dx1, dy1, dx2, dy2; - Uint32 r, g, b; - Uint8 br, bg, bb; - - /* - * Some ugly reverse conversion for compatibility... - * (We must do this before losing the dst pointer, - * as the pixel formats of the screen and - * SDL_VideoSurface may differ!) - */ - - if (dst->format->palette) { - /* this a paletted color */ - SDL_GetRGB(color, dst->format, &br, &bg, &bb); - } else { - /* this a RGB color */ - r = color & dst->format->Rmask; - r = r >> dst->format->Rshift; - r = r << dst->format->Rloss; - br = r; - - g = color & dst->format->Gmask; - g = g >> dst->format->Gshift; - g = g << dst->format->Gloss; - bg = g; - - b = color & dst->format->Bmask; - b = b >> dst->format->Bshift; - b = b << dst->format->Bloss; - bb = b; - } - - if (vs != dst) { - /* draw a rect offscreen */ - glSDL_Invalidate(dst, dstrect); - /* software-fill the surface by faking it as a SW_SURFACE */ - dst->flags &= ~SDL_HWSURFACE; - SDL_FillRect(dst, dstrect, color); - dst->flags |= SDL_HWSURFACE; - } else { - /* draw a rect onscreen */ - glSDL_do_texture(this, 0); - glSDL_do_blend(this, 0); - - dx1 = dstrect->x; - dy1 = dstrect->y; - dx2 = dx1 + dstrect->w; - dy2 = dy1 + dstrect->h; - - this->glBegin(GL_TRIANGLE_FAN); - this->glColor3ub(br, bg, bb); - this->glVertex2i(dx1, dy1); - this->glVertex2i(dx2, dy1); - this->glVertex2i(dx2, dy2); - this->glVertex2i(dx1, dy2); - this->glEnd(); - } - return 0; -} - -static int -glSDL_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst) -{ - src->flags |= SDL_HWACCEL; - src->map->hw_blit = glSDL_HWAccelBlit; - return 1; -} - - -static SDL_Surface * -glSDL_DisplayFormat(SDL_Surface * surface) -{ - SDL_Surface *tmp; - int use_rgba = (surface->flags & SDL_SRCCOLORKEY) || - ((surface->flags & SDL_SRCALPHA) && surface->format->Amask); -#ifdef DEBUG_GLSDL - fprintf(stderr, "#### glSDL_DisplayFormat()\n"); -#endif - if (use_rgba) - tmp = glSDL_ConvertSurface(surface, RGBAfmt, SDL_SWSURFACE); - else - tmp = glSDL_ConvertSurface(surface, RGBfmt, SDL_SWSURFACE); - if (!tmp) { - GLERR("glSDL_DisplayFormat() could not convert surface!"); - return NULL; - } - SDL_SetAlpha(tmp, 0, 0); - - if (surface->flags & SDL_SRCCOLORKEY) { - /* - * We drop colorkey data here, but we have to, - * or we'll run into trouble when converting, - * in particular from indexed color formats. - */ - SDL_SetColorKey(tmp, SDL_SRCCOLORKEY, surface->format->colorkey); - glSDL_key2alpha(tmp); - SDL_SetColorKey(tmp, 0, 0); - } - - return tmp; -} - - -static SDL_Surface * -glSDL_DisplayFormatAlpha(SDL_Surface * surface) -{ - SDL_Surface *s, *tmp; - tmp = glSDL_ConvertSurface(surface, RGBAfmt, SDL_SWSURFACE); -#ifdef DEBUG_GLSDL - fprintf(stderr, "#### glSDL_DisplayFormatAlpha()\n"); -#endif - if (!tmp) - return NULL; - - SDL_SetAlpha(tmp, 0, 0); - SDL_SetColorKey(tmp, 0, 0); - s = glSDL_CreateRGBASurface(surface->w, surface->h); - if (!s) { - SDL_FreeSurface(tmp); - return NULL; - } - glSDL_SoftBlit(tmp, NULL, s, NULL); - SDL_FreeSurface(tmp); - - if (surface->flags & SDL_SRCCOLORKEY) { - SDL_SetColorKey(s, SDL_SRCCOLORKEY, surface->format->colorkey); - glSDL_key2alpha(s); - SDL_SetColorKey(s, 0, 0); - } - - if (surface->flags & SDL_SRCALPHA) - SDL_SetAlpha(s, SDL_SRCALPHA, surface->format->alpha); - return s; -} - - -/*---------------------------------------------------------- - glSDL specific API extensions - ----------------------------------------------------------*/ - -static void -glSDL_Invalidate(SDL_Surface * surface, SDL_Rect * area) -{ - private_hwdata *txi; - if (!surface) - return; - txi = glSDL_GetTexInfo(surface); - if (!txi) - return; - if (!area) { - txi->invalid_area.x = 0; - txi->invalid_area.y = 0; - txi->invalid_area.w = surface->w; - txi->invalid_area.h = surface->h; - return; - } - txi->invalid_area = *area; -} - - -static void -glSDL_SetLogicSize(_THIS, SDL_Surface * surface, int w, int h) -{ - SDL_Rect r; - private_hwdata *txi; - if (!IS_GLSDL_SURFACE(surface)) - return; - - txi = glSDL_GetTexInfo(surface); - - txi->lw = w; - txi->lh = h; - - if (SDL_VideoSurface != surface) - return; - - r.x = r.y = 0; - r.w = w; - r.h = h; - glSDL_SetClipRect(this, surface, &r); - - this->glMatrixMode(GL_MODELVIEW); - this->glLoadIdentity(); - this->glTranslated(0.0f, 0.0f, 0.0f); - - this->glDisable(GL_DEPTH_TEST); - this->glDisable(GL_CULL_FACE); - - glSDL_reset(); -} - -static int -glSDL_InitTexture(_THIS, SDL_Surface * datasurf, private_hwdata * txi, - int tex) -{ - this->glGenTextures(1, (GLuint *) & txi->texture[tex]); - this->glBindTexture(GL_TEXTURE_2D, txi->texture[tex]); - glstate.texture = txi->texture[tex]; - this->glPixelStorei(GL_UNPACK_ROW_LENGTH, datasurf->pitch / - datasurf->format->BytesPerPixel); - this->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - this->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - this->glTexImage2D(GL_TEXTURE_2D, 0, - datasurf->format->Amask ? GL_RGBA8 : GL_RGB8, - txi->texsize, txi->texsize, 0, - datasurf->format->Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, NULL); -#ifdef DEBUG_GLSDL - glSDL_print_glerror(this, 1); -#endif - return 0; -} - - -/* Image tiled horizontally (wide surface), or not at all */ -static int -glSDL_UploadHoriz(_THIS, SDL_Surface * datasurf, private_hwdata * txi) -{ - int bpp = datasurf->format->BytesPerPixel; - int res; - int tex = 0; - int fromx = 0; - int toy = txi->texsize; /* To init first texture */ - while (1) { - int thistw = datasurf->w - fromx; - if (thistw > txi->tilew) - thistw = txi->tilew; - else if (thistw <= 0) - break; - if (toy + txi->tileh > txi->texsize) { - toy = 0; - res = glSDL_InitTexture(this, datasurf, txi, tex); - if (res < 0) - return res; - ++tex; - } - this->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, toy, - thistw, txi->tileh, - datasurf->format->Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, - (char *) datasurf->pixels + bpp * fromx); -#ifdef DEBUG_GLSDL - glSDL_print_glerror(this, 2); -#endif - fromx += txi->tilew; - toy += txi->tileh; - } - return 0; -} - - -/* Image tiled vertically (tall surface) */ -static int -glSDL_UploadVert(_THIS, SDL_Surface * datasurf, private_hwdata * txi) -{ - int res; - int tex = 0; - int fromy = 0; - int tox = txi->texsize; /* To init first texture */ - while (1) { - int thisth = datasurf->h - fromy; - if (thisth > txi->tileh) - thisth = txi->tileh; - else if (thisth <= 0) - break; - if (tox + txi->tilew > txi->texsize) { - tox = 0; - res = glSDL_InitTexture(this, datasurf, txi, tex); - if (res < 0) - return res; - ++tex; - } - this->glTexSubImage2D(GL_TEXTURE_2D, 0, tox, 0, - txi->tilew, thisth, - datasurf->format->Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, - (char *) datasurf->pixels + - datasurf->pitch * fromy); -#ifdef DEBUG_GLSDL - glSDL_print_glerror(this, 3); -#endif - fromy += txi->tileh; - tox += txi->tilew; - } - return 0; -} - - -/* Image tiled two-way (huge surface) */ -static int -glSDL_UploadHuge(_THIS, SDL_Surface * datasurf, private_hwdata * txi) -{ - int bpp = datasurf->format->BytesPerPixel; - int res; - int tex = 0; - int y = 0; - while (y < datasurf->h) { - int x; - int thisth = datasurf->h - y; - if (thisth > txi->tileh) - thisth = txi->tileh; - x = 0; - while (x < datasurf->w) { - int thistw = datasurf->w - x; - if (thistw > txi->tilew) - thistw = txi->tilew; - res = glSDL_InitTexture(this, datasurf, txi, tex++); - if (res < 0) - return res; - this->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - thistw, thisth, - datasurf->format-> - Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, - (char *) datasurf->pixels + - datasurf->pitch * y + bpp * x); -#ifdef DEBUG_GLSDL - fprintf(stderr, - "glTexSubImage(x = %d, y = %d, w = %d, h = %d)\n", x, - y, thistw, thisth); - glSDL_print_glerror(this, 4); -#endif - x += txi->tilew; - } - y += txi->tileh; - } - return 0; -} - - -/* Upload all textures for a surface. */ -static int -glSDL_UploadTextures(_THIS, SDL_Surface * datasurf, private_hwdata * txi) -{ - switch (txi->tilemode) { - case GLSDL_TM_SINGLE: - case GLSDL_TM_HORIZONTAL: - glSDL_UploadHoriz(this, datasurf, txi); - break; - case GLSDL_TM_VERTICAL: - glSDL_UploadVert(this, datasurf, txi); - break; - case GLSDL_TM_HUGE: - glSDL_UploadHuge(this, datasurf, txi); - break; - } - return 0; -} - - -/* - * IMPORTANT: - * This function will try various ways of giving you - * a TexInfo, and will succeed most of the time. - * - * However, the TexInfo returned may be temporary, - * (as opposed to connected to 'surface'). A temporary - * TexInfo must be used only once and then thrown away, - * since it means that glSDL cannot track changes in - * the pixel data of 'texture'. - */ -static private_hwdata * -glSDL_UploadSurface(_THIS, SDL_Surface * surface) -{ - int i; - int converted = 0; - private_hwdata *txi = glSDL_GetTexInfo(surface); - - if (IS_GLSDL_SURFACE(surface)) { - /* - * Ok, this is a glSDL surface, and it *might* be - * in texture memory already. If so, it may need - * an update. - */ - if (txi->invalid_area.w) { - glSDL_UnloadTexture(this, txi); - } else { - int missing = 0; - if (txi->textures) { - for (i = 0; i < txi->textures; ++i) - if (GLSDL_NOTEX == txi->texture[i]) { - missing = 1; - break; - } - if (!missing) - return txi; /* They're already there! */ - } - } - } else { - /* - * Nope, this isn't (yet) a glSDL surface. Let's - * try to either make it one, or set up a temporary - * TexInfo for it, valid for only one blit. - */ - if ((surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { - txi = glSDL_AddTexInfo(this, surface); - if (!txi) { - GLERR("UploadSurface(): Could not add TexInfo!"); - return NULL; - } - surface->flags |= SDL_HWSURFACE; - surface->flags |= SDL_HWACCEL; - } else { - /* - * FIXME - * here if the surface is small enough, it's a good - * candidate for a blit using glDrawPixels instead - * of a texture blit - */ - txi = glSDL_CreateTempTexInfo(this, surface); - if (!txi) { - GLERR("UploadSurface(): Could not create temp TexInfo!"); - return NULL; - } - } - } - - if (txi->texsize > maxtexsize) { - /* This surface wasn't tiled properly... */ - if (txi->temporary) - glSDL_FreeTexInfo(this, txi); - GLERR("UploadSurface(): Too large texture!"); - return NULL; - } - - /* - * Kludge: Convert if not of preferred RGB or RGBA format. - * - * Conversion should only be done when *really* needed. - * That is, it should rarely have to be done with OpenGL - * 1.2+. - * - * Besides, any surface that's been SDL_DisplayFormat()ed - * should already be in the best known OpenGL format - - * preferably one that makes DMA w/o conversion possible. - */ - if (!glSDL_FormatIsOk(surface)) { -#ifdef DEBUG_GLSDL - fprintf(stderr, "glSDL: WARNING: On-the-fly conversion performed!\n"); -#endif - converted = 1; - /* NOTE: We forget about the original surface here. */ - if (surface->format->Amask) - surface = glSDL_DisplayFormatAlpha(surface); - else - surface = glSDL_DisplayFormat(surface); - if (!surface) { - GLERR("UploadSurface(): Could not convert surface!"); - if (txi->temporary) - glSDL_FreeTexInfo(this, txi); - return NULL; - } - } - - glSDL_UploadTextures(this, surface, txi); - - if (converted) - SDL_FreeSurface(surface); - - return txi; -} - - -static void -glSDL_UnloadTexture(_THIS, private_hwdata * txi) -{ - int i; - for (i = 0; i < txi->textures; ++i) - if (txi->texture[i] != GLSDL_NOTEX) - this->glDeleteTextures(1, &txi->texture[i]); - SDL_memset(&txi->invalid_area, 0, sizeof(txi->invalid_area)); -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/glsdl/SDL_glsdl.h Wed Jul 26 03:08:25 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - * glSDL "SDL-over-OpenGL" video driver implemented by - * David Olofson <david@olofson.net> and - * Stephane Marchesin <stephane.marchesin@wanadoo.fr> - */ - -#ifndef _SDL_gl_h -#define _SDL_gl_h - -#include "../SDL_sysvideo.h" - -/* Hidden "this" pointer for the video functions */ -#define _THIS SDL_VideoDevice *this - -#endif /* _SDL_gl_h */ -/* vi: set ts=4 sw=4 expandtab: */