X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=contrib%2Fsupertux-nogl.diff;h=99fb95a30a4fa024695aac1206574f7fa4345f59;hb=6835b0b10756e978f568dbb32f3c8ca0a615ecf1;hp=733921ede05b6b90db7158d70847fe9a9ffc30f6;hpb=d532debd4ab145b7d1fccd9245e21948cd5f0436;p=supertux.git diff --git a/contrib/supertux-nogl.diff b/contrib/supertux-nogl.diff index 733921ede..99fb95a30 100644 --- a/contrib/supertux-nogl.diff +++ b/contrib/supertux-nogl.diff @@ -24,358 +24,130 @@ # with SDL functions only. Many features are removed from the video engine, # so don't expect much. # -# Note that the patched sources will need an additional library, SDL_gfx, to -# compile. -# # Installing the patch should be pretty straightforward. Simply run the # following command prior to running autogen.sh and configure: # -# patch -p1 < contrib/supertux-nogl.diff +# patch -p0 < contrib/supertux-nogl.diff # -# This patch works for revision 3294. It may break for later revisions. +# This patch works for revision 5072. It may break for later revisions. # # ----------------------------------------------------------------------------- -diff -Naur supertux/INSTALL supertux-nogl/INSTALL ---- supertux/INSTALL 2006-03-03 21:49:07.000000000 +0100 -+++ supertux-nogl/INSTALL 2006-04-07 04:13:00.000000000 +0200 -@@ -1,7 +1,7 @@ - - Install instructions for SuperTux - - http://supertux.berlios.de/ - --Last update: October 11, 2005 by Ondra Hosek -+Last update: March 4, 2006 by Christoph Sommer - - BINARIES - -------- -@@ -34,17 +34,15 @@ - Download: ftp://ftp.perforce.com/pub/jam - Homepage: http://www.perforce.com/jam/jam.html - --* OpenGL headers and libraries -- opengl libraries and headers are specific to your graphics card. Make sure -- that you have hardware accelerated opengl drivers installed. Software -- renderers like Mesa will make supertux unplayable slow. -- - * SDL 1.2.5 or later (1.2.8 is recommended on MacOS/X) - http://www.libsdl.org - - * SDL_image (any version) - http://www.libsdl.org/projects/SDL_image - -+* SDL_gfx (2.0.13 or later) -+ http://www.ferzkopp.net/Software/SDL_gfx-2.0/ -+ - * PhysicsFS (1.0.0, the development branch 1.1.x is buggy and does not work, - 1.2.0 and later should work when it is released) - http://www.icculus.org/physfs -diff -Naur supertux/README supertux-nogl/README ---- supertux/README 2006-03-03 20:43:38.000000000 +0100 -+++ supertux-nogl/README 2006-04-07 04:13:00.000000000 +0200 -@@ -2,7 +2,7 @@ - - An introduction for SuperTux - - http://supertux.berlios.de/ - --Last update: October 13, 2005 -+Last update: March 4, 2006 by Christoph Sommer - - DESCRIPTION - ----------- -@@ -75,10 +75,9 @@ - Also, notice that SuperTux saves the options, so it's often enough to - specify them once. - -- The game uses OpenGL to render the graphics. You will either need a CPU -- with about 10 GHz or an accelerated video card with the vendor's drivers. -- (On Linux, the team recommends using cards from NVidia with the proprietary -- drivers, but ATI or another verndor should do.) -+ The game uses SDL to render the graphics. You will either need a CPU -+ with about 1 GHz or go get the original version of SuperTux which uses -+ OpenGL. - - - PLAYING THE GAME -diff -Naur supertux/configure.ac supertux-nogl/configure.ac ---- supertux/configure.ac 2006-03-03 20:43:38.000000000 +0100 -+++ supertux-nogl/configure.ac 2006-04-07 04:13:00.000000000 +0200 -@@ -11,7 +11,7 @@ - - dnl Process this file with autoconf to produce a configure script. - AC_PREREQ([2.54]) --AC_INIT(supertux, 0.2-svn) -+AC_INIT(supertux, 0.2-nogl-svn) - AC_CONFIG_SRCDIR([src/main.cpp]) - AC_CONFIG_AUX_DIR([mk/autoconf]) - AC_CANONICAL_TARGET -@@ -105,6 +105,14 @@ - [AC_MSG_ERROR([Please install SDLImage >= 1.2.1])], - [$SDL_CFLAGS], [$SDL_LIBS]) - -+dnl FIXME: This is far from perfect -+NP_FINDLIB([SDLGFX], [SDL_gfx], [SDL_gfx >= 2.0.13], -+ NP_LANG_PROGRAM([#include ], [0;]), -+ [], [-lSDL_gfx], -+ [], -+ [AC_MSG_ERROR([Please install SDL_gfx >= 2.0.13])], -+ [$SDL_CFLAGS], [$SDL_LIBS]) +Index: src/gameconfig.hpp +=================================================================== +--- src/gameconfig.hpp (revision 5071) ++++ src/gameconfig.hpp (working copy) +@@ -19,6 +19,8 @@ + #ifndef SUPERTUX_CONFIG_H + #define SUPERTUX_CONFIG_H + ++#include + - NP_FINDLIB([PHYSFS], [physfs], [physfs >= 1.0.0], - NP_LANG_PROGRAM([ - #include -@@ -124,11 +132,6 @@ - [AC_MSG_ERROR([Please intall OpenAL])], - [], []) - --AX_CHECK_GL --if test "$no_gl" = "yes"; then -- AC_MSG_ERROR([Please install opengl libraries and headers]) --fi -- - dnl Checks for library functions. - AC_CHECK_FUNCS(mkdir strdup strstr) - -diff -Naur supertux/src/Jamfile supertux-nogl/src/Jamfile ---- supertux/src/Jamfile 2006-03-03 20:34:49.000000000 +0100 -+++ supertux-nogl/src/Jamfile 2006-04-07 04:11:50.000000000 +0200 -@@ -24,7 +24,7 @@ - Application supertux : $(sources) $(wrapper_objects) ; - C++Flags supertux : -DAPPDATADIR='\"$(appdatadir)\"' ; - LinkWith supertux : squirrel ; --ExternalLibs supertux : SDL SDLIMAGE GL OPENAL VORBIS VORBISFILE OGG ICONV PHYSFS BINRELOC ; -+ExternalLibs supertux : SDL SDLIMAGE SDLGFX OPENAL VORBIS VORBISFILE OGG ICONV PHYSFS BINRELOC ; - Help supertux : "Build the supertux executable" ; - IncludeDir supertux : squirrel/include ; - -diff -Naur supertux/src/main.cpp supertux-nogl/src/main.cpp ---- supertux/src/main.cpp 2006-04-07 03:32:14.000000000 +0200 -+++ supertux-nogl/src/main.cpp 2006-04-07 04:11:50.000000000 +0200 -@@ -35,7 +35,6 @@ - #include - #include - #include --#include - - #include "gameconfig.hpp" - #include "resources.hpp" -@@ -266,44 +265,6 @@ - ; - } - --static void check_gl_error() --{ -- GLenum glerror = glGetError(); -- std::string errormsg; -- -- if(glerror != GL_NO_ERROR) { -- switch(glerror) { -- case GL_INVALID_ENUM: -- errormsg = "Invalid enumeration value"; -- break; -- case GL_INVALID_VALUE: -- errormsg = "Numeric argzment out of range"; -- break; -- case GL_INVALID_OPERATION: -- errormsg = "Invalid operation"; -- break; -- case GL_STACK_OVERFLOW: -- errormsg = "stack overflow"; -- break; -- case GL_STACK_UNDERFLOW: -- errormsg = "stack underflow"; -- break; -- case GL_OUT_OF_MEMORY: -- errormsg = "out of memory"; -- break; -- case GL_TABLE_TOO_LARGE: -- errormsg = "table too large"; -- break; -- default: -- errormsg = "unknown error number"; -- break; -- } -- std::stringstream msg; -- msg << "OpenGL Error: " << errormsg; -- throw std::runtime_error(msg.str()); -- } --} -- - void init_video() - { - if(texture_manager != NULL) -@@ -314,7 +275,7 @@ - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - -- int flags = SDL_OPENGL; -+ int flags = SDL_SWSURFACE; - if(config->use_fullscreen) - flags |= SDL_FULLSCREEN; - int width = config->screenwidth; -@@ -344,24 +305,6 @@ - } - #endif + #include -- // setup opengl state and transform -- glDisable(GL_DEPTH_TEST); -- glDisable(GL_CULL_FACE); -- glEnable(GL_TEXTURE_2D); -- glEnable(GL_BLEND); -- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -- -- glViewport(0, 0, screen->w, screen->h); -- glMatrixMode(GL_PROJECTION); -- glLoadIdentity(); -- // logical resolution here not real monitor resolution -- glOrtho(0, 800, 600, 0, -1.0, 1.0); -- glMatrixMode(GL_MODELVIEW); -- glLoadIdentity(); -- glTranslatef(0, 0, 0); -- -- check_gl_error(); -- - if(texture_manager != NULL) - texture_manager->reload_textures(); - else -diff -Naur supertux/src/video/drawing_context.cpp supertux-nogl/src/video/drawing_context.cpp ---- supertux/src/video/drawing_context.cpp 2006-03-31 04:18:01.000000000 +0200 -+++ supertux-nogl/src/video/drawing_context.cpp 2006-04-07 04:11:49.000000000 +0200 -@@ -22,8 +22,6 @@ + class Config +@@ -39,6 +41,9 @@ + float aspect_ratio; + + bool use_fullscreen; ++#ifdef HAVE_OPENGL ++ bool use_opengl; ++#endif + bool try_vsync; + bool show_fps; + bool sound_enabled; +Index: src/video/drawing_context.cpp +=================================================================== +--- src/video/drawing_context.cpp (revision 5071) ++++ src/video/drawing_context.cpp (working copy) +@@ -23,17 +23,16 @@ #include #include #include -#include --#include + #include + #include + #include ++#include "glutil.hpp" #include "drawing_context.hpp" #include "surface.hpp" -@@ -49,30 +47,20 @@ + #include "font.hpp" + #include "main.hpp" + #include "gameconfig.hpp" +-#include "glutil.hpp" + #include "texture.hpp" + #include "texture_manager.hpp" + #include "obstack/obstackpp.hpp" +@@ -113,6 +112,7 @@ { screen = SDL_GetVideoSurface(); -- lightmap_width = screen->w / LIGHTMAP_DIV; -- lightmap_height = screen->h / LIGHTMAP_DIV; -- unsigned int width = next_po2(lightmap_width); -- unsigned int height = next_po2(lightmap_height); -- -- lightmap = new Texture(width, height, GL_RGB); -- -- lightmap_uv_right = static_cast(lightmap_width) / static_cast(width); -- lightmap_uv_bottom = static_cast(lightmap_height) / static_cast(height); -- texture_manager->register_texture(lightmap); -- -+ target = NORMAL; - requests = &drawing_requests; - } - - DrawingContext::~DrawingContext() - { -- texture_manager->remove_texture(lightmap); -- delete lightmap; - } - - void - DrawingContext::draw_surface(const Surface* surface, const Vector& position, - int layer) - { -+ if(target != NORMAL) return; -+ - assert(surface != 0); - - DrawingRequest request; -@@ -97,6 +85,8 @@ - DrawingContext::draw_surface_part(const Surface* surface, const Vector& source, - const Vector& size, const Vector& dest, int layer) - { -+ if(target != NORMAL) return; -+ - assert(surface != 0); - - DrawingRequest request; -@@ -136,6 +126,8 @@ - DrawingContext::draw_text(const Font* font, const std::string& text, - const Vector& position, FontAlignment alignment, int layer) - { -+ if(target != NORMAL) return; -+ - DrawingRequest request; ++#ifdef HAVE_OPENGL + lightmap_width = screen->w / LIGHTMAP_DIV; + lightmap_height = screen->h / LIGHTMAP_DIV; + unsigned int width = next_po2(lightmap_width); +@@ -123,6 +123,7 @@ + lightmap_uv_right = static_cast(lightmap_width) / static_cast(width); + lightmap_uv_bottom = static_cast(lightmap_height) / static_cast(height); + texture_manager->register_texture(lightmap); ++#endif - request.type = TEXT; -@@ -157,6 +149,8 @@ - DrawingContext::draw_center_text(const Font* font, const std::string& text, - const Vector& position, int layer) - { -+ if(target != NORMAL) return; -+ - draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y), - CENTER_ALLIGN, layer); - } -@@ -164,6 +158,8 @@ - void - DrawingContext::draw_gradient(const Color& top, const Color& bottom, int layer) - { -+ if(target != NORMAL) return; -+ - DrawingRequest request; + requests = &drawing_requests; - request.type = GRADIENT; -@@ -185,6 +181,8 @@ - DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size, - const Color& color, int layer) +@@ -133,8 +134,10 @@ { -+ if(target != NORMAL) return; -+ - DrawingRequest request; + obstack_free(&obst, NULL); - request.type = FILLRECT; -@@ -218,23 +216,55 @@ - delete surfacepartrequest; ++#ifdef HAVE_OPENGL + texture_manager->remove_texture(lightmap); + delete lightmap; ++#endif } -+namespace -+{ -+ void fillrect(SDL_Surface* screen, float x, float y, float w, float h, int r, int g, int b, int a) + void +@@ -338,15 +341,31 @@ + const GetLightRequest* getlightrequest + = (GetLightRequest*) request.request_data; + +- float pixels[3]; +- for( int i = 0; i<3; i++) +- pixels[i] = 0.0f; //set to black ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) + { -+ if(w < 0) { -+ x += w; -+ w = -w; -+ } -+ if(h < 0) { -+ y += h; -+ h = -h; -+ } -+ -+ SDL_Rect src, rect; -+ SDL_Surface *temp = NULL; -+ -+ rect.x = (int)x; -+ rect.y = (int)y; -+ rect.w = (int)w; -+ rect.h = (int)h; -+ -+ if(a != 255) { -+ temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); -+ -+ src.x = 0; -+ src.y = 0; -+ src.w = rect.w; -+ src.h = rect.h; -+ -+ SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b)); -+ SDL_SetAlpha(temp, SDL_SRCALPHA, a); -+ SDL_BlitSurface(temp,0,screen,&rect); -+ SDL_FreeSurface(temp); ++ float pixels[3]; ++ for( int i = 0; i<3; i++) ++ pixels[i] = 0.0f; //set to black + +- float posX = request.pos.x * lightmap_width / SCREEN_WIDTH; +- float posY = screen->h - request.pos.y * lightmap_height / SCREEN_HEIGHT; +- glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels); ++ float posX = request.pos.x * lightmap_width / SCREEN_WIDTH; ++ float posY = screen->h - request.pos.y * lightmap_height / SCREEN_HEIGHT; ++ glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels); + *(getlightrequest->color_ptr) = Color( pixels[0], pixels[1], pixels[2]); +- //printf("get_light %f/%f =>%f/%f r%f g%f b%f\n", request.pos.x, request.pos.y, posX, posY, pixels[0], pixels[1], pixels[2]); ++ //printf("get_light %f/%f =>%f/%f r%f g%f b%f\n", request.pos.x, request.pos.y, posX, posY, pixels[0], pixels[1], pixels[2]); ++ } ++ else ++#endif ++ { ++ // FIXME: implement properly for SDL ++ static int i = 0; ++ i += 1; i &= 0xFFFF; ++ if (i & 0x8000) { ++ *(getlightrequest->color_ptr) = Color(0.0f, 0.0f, 0.0f); + } else { -+ SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b)); ++ *(getlightrequest->color_ptr) = Color(1.0f, 1.0f, 1.0f); + } + } -+} -+ + } + void - DrawingContext::draw_gradient(DrawingRequest& request) - { - GradientRequest* gradientrequest = (GradientRequest*) request.request_data; +@@ -370,17 +389,50 @@ const Color& top = gradientrequest->top; const Color& bottom = gradientrequest->bottom; -- + - glDisable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - glColor4f(top.red, top.green, top.blue, top.alpha); @@ -386,21 +158,77 @@ diff -Naur supertux/src/video/drawing_context.cpp supertux-nogl/src/video/drawin - glVertex2f(0, SCREEN_HEIGHT); - glEnd(); - glEnable(GL_TEXTURE_2D); +- glColor4f(1, 1, 1, 1); ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) ++ { ++ glDisable(GL_TEXTURE_2D); ++ glBegin(GL_QUADS); ++ glColor4f(top.red, top.green, top.blue, top.alpha); ++ glVertex2f(0, 0); ++ glVertex2f(SCREEN_WIDTH, 0); ++ glColor4f(bottom.red, bottom.green, bottom.blue, bottom.alpha); ++ glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT); ++ glVertex2f(0, SCREEN_HEIGHT); ++ glEnd(); ++ glEnable(GL_TEXTURE_2D); ++ glColor4f(1, 1, 1, 1); ++ } ++ else ++#endif ++ { ++ for(int y = 0;y < screen->h;++y) ++ { ++ Uint8 r = (Uint8)((((float)(top.red-bottom.red)/(0-screen->h)) * y + top.red) * 255); ++ Uint8 g = (Uint8)((((float)(top.green-bottom.green)/(0-screen->h)) * y + top.green) * 255); ++ Uint8 b = (Uint8)((((float)(top.blue-bottom.blue)/(0-screen->h)) * y + top.blue) * 255); ++ Uint8 a = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-screen->h)) * y + top.alpha) * 255); ++ Uint32 color = SDL_MapRGB(screen->format, r, g, b); + -+ int width = 800; -+ int height = 600; -+ for(float y = 0; y < height; y += 2) ::fillrect(screen, 0, (int)y, width, 2, (int)(((float)(top.red-bottom.red)/(0-height)) * y + top.red), (int)(((float)(top.green-bottom.green)/(0-height)) * y + top.green), (int)(((float)(top.blue-bottom.blue)/(0-height)) * y + top.blue), 255); - - delete gradientrequest; ++ SDL_Rect rect; ++ rect.x = 0; ++ rect.y = y; ++ rect.w = screen->w; ++ rect.h = 1; ++ ++ if(a == SDL_ALPHA_OPAQUE) { ++ SDL_FillRect(screen, &rect, color); ++ } else if(a != SDL_ALPHA_TRANSPARENT) { ++ SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); ++ ++ SDL_FillRect(temp, 0, color); ++ SDL_SetAlpha(temp, SDL_SRCALPHA, a); ++ SDL_BlitSurface(temp, 0, screen, &rect); ++ SDL_FreeSurface(temp); ++ } ++ } ++ } } -@@ -260,17 +290,12 @@ - float w = fillrectrequest->size.x; - float h = fillrectrequest->size.y; + + void +@@ -398,29 +450,76 @@ + const FillRectRequest* fillrectrequest + = (FillRectRequest*) request.request_data; + +- float x = request.pos.x; +- float y = request.pos.y; +- float w = fillrectrequest->size.x; +- float h = fillrectrequest->size.y; ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) ++ { ++ float x = request.pos.x; ++ float y = request.pos.y; ++ float w = fillrectrequest->size.x; ++ float h = fillrectrequest->size.y; - glDisable(GL_TEXTURE_2D); - glColor4f(fillrectrequest->color.red, fillrectrequest->color.green, - fillrectrequest->color.blue, fillrectrequest->color.alpha); -- ++ glDisable(GL_TEXTURE_2D); ++ glColor4f(fillrectrequest->color.red, fillrectrequest->color.green, ++ fillrectrequest->color.blue, fillrectrequest->color.alpha); + - glBegin(GL_QUADS); - glVertex2f(x, y); - glVertex2f(x+w, y); @@ -408,343 +236,614 @@ diff -Naur supertux/src/video/drawing_context.cpp supertux-nogl/src/video/drawin - glVertex2f(x, y+h); - glEnd(); - glEnable(GL_TEXTURE_2D); -+ int r = static_cast(fillrectrequest->color.red); -+ int g = static_cast(fillrectrequest->color.green); -+ int b = static_cast(fillrectrequest->color.blue); -+ int a = static_cast(fillrectrequest->color.alpha); +- +- glColor4f(1, 1, 1, 1); ++ glBegin(GL_QUADS); ++ glVertex2f(x, y); ++ glVertex2f(x+w, y); ++ glVertex2f(x+w, y+h); ++ glVertex2f(x, y+h); ++ glEnd(); ++ glEnable(GL_TEXTURE_2D); ++ glColor4f(1, 1, 1, 1); ++ } ++ else ++#endif ++ { ++ float xfactor = (float) config->screenwidth / SCREEN_WIDTH; ++ float yfactor = (float) config->screenheight / SCREEN_HEIGHT; ++ int numerator; ++ int denominator; ++ if(xfactor < yfactor) ++ { ++ numerator = config->screenwidth; ++ denominator = SCREEN_WIDTH; ++ } ++ else ++ { ++ numerator = config->screenheight; ++ denominator = SCREEN_HEIGHT; ++ } ++ ++ SDL_Rect rect; ++ rect.x = (Sint16)request.pos.x * numerator / denominator; ++ rect.y = (Sint16)request.pos.y * numerator / denominator; ++ rect.w = (Uint16)fillrectrequest->size.x * numerator / denominator; ++ rect.h = (Uint16)fillrectrequest->size.y * numerator / denominator; ++ Uint8 r = static_cast(fillrectrequest->color.red * 255); ++ Uint8 g = static_cast(fillrectrequest->color.green * 255); ++ Uint8 b = static_cast(fillrectrequest->color.blue * 255); ++ Uint8 a = static_cast(fillrectrequest->color.alpha * 255); ++ Uint32 color = SDL_MapRGB(screen->format, r, g, b); ++ if(a == SDL_ALPHA_OPAQUE) { ++ SDL_FillRect(screen, &rect, color); ++ } else if(a != SDL_ALPHA_TRANSPARENT) { ++ SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); + -+ ::fillrect(screen, x, y, w, h, r, g, b, a); ++ SDL_FillRect(temp, 0, color); ++ SDL_SetAlpha(temp, SDL_SRCALPHA, a); ++ SDL_BlitSurface(temp, 0, screen, &rect); ++ SDL_FreeSurface(temp); ++ } ++ } + } + + void ++#ifdef HAVE_OPENGL + DrawingContext::draw_lightmap(const DrawingRequest& request) const ++#else ++DrawingContext::draw_lightmap(const DrawingRequest&) const ++#endif + { ++#ifdef HAVE_OPENGL + const Texture* texture = reinterpret_cast (request.request_data); - delete fillrectrequest; + // multiple the lightmap with the framebuffer +@@ -444,6 +543,7 @@ + glEnd(); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ++#endif } -@@ -285,66 +310,10 @@ - transformstack.clear(); - target_stack.clear(); -- bool use_lightmap = lightmap_requests.size() != 0; -- -- // PART1: create lightmap -- if(use_lightmap) { + void +@@ -462,29 +562,38 @@ + + // PART1: create lightmap + if(use_lightmap) { - glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height); - glMatrixMode(GL_PROJECTION); -- glLoadIdentity(); +- glLoadIdentity(); - glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); -- -- //glClearColor(1.0f, 1.0f, 1.0f, 1.0f); -- glClearColor(0, 0, 0, 1); ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) ++ { ++ glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height); ++ glMatrixMode(GL_PROJECTION); ++ glLoadIdentity(); ++ glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0); ++ glMatrixMode(GL_MODELVIEW); ++ glLoadIdentity(); + +- glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 ); - glClear(GL_COLOR_BUFFER_BIT); - handle_drawing_requests(lightmap_requests); - lightmap_requests.clear(); -- ++ glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 ); ++ glClear(GL_COLOR_BUFFER_BIT); ++ handle_drawing_requests(lightmap_requests); ++ lightmap_requests.clear(); + - glDisable(GL_BLEND); - glBindTexture(GL_TEXTURE_2D, lightmap->get_handle()); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height); -- ++ glDisable(GL_BLEND); ++ glBindTexture(GL_TEXTURE_2D, lightmap->get_handle()); ++ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height); + - glViewport(0, 0, screen->w, screen->h); - glMatrixMode(GL_PROJECTION); -- glLoadIdentity(); +- glLoadIdentity(); - glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0); -- glMatrixMode(GL_MODELVIEW); +- glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glEnable(GL_BLEND); -- } -- -- //glClear(GL_COLOR_BUFFER_BIT); - handle_drawing_requests(drawing_requests); - drawing_requests.clear(); ++ glViewport(0, 0, screen->w, screen->h); ++ glMatrixMode(GL_PROJECTION); ++ glLoadIdentity(); ++ glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0); ++ glMatrixMode(GL_MODELVIEW); ++ glLoadIdentity(); ++ glEnable(GL_BLEND); ++ } ++ else ++#endif ++ { ++ // FIXME: SDL alternative ++ } -- if(use_lightmap) { -- glBlendFunc(GL_SRC_ALPHA, GL_ONE); -- -- glBindTexture(GL_TEXTURE_2D, lightmap->get_handle()); -- glBegin(GL_QUADS); -- -- glTexCoord2f(0, lightmap_uv_bottom); -- glVertex2f(0, 0); -- -- glTexCoord2f(lightmap_uv_right, lightmap_uv_bottom); -- glVertex2f(SCREEN_WIDTH, 0); -- -- glTexCoord2f(lightmap_uv_right, 0); -- glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT); -- -- glTexCoord2f(0, 0); -- glVertex2f(0, SCREEN_HEIGHT); -- -- glEnd(); -- -- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -- } -- + // add a lightmap drawing request into the queue + DrawingRequest* request = new(obst) DrawingRequest(); +@@ -499,7 +608,12 @@ + drawing_requests.clear(); + obstack_free(&obst, NULL); + obstack_init(&obst); - assert_gl("drawing"); -- ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) ++ { ++ assert_gl("drawing"); ++ } ++#endif + + // if a screenshot was requested, take one + if (screenshot_requested) { +@@ -507,7 +621,16 @@ + screenshot_requested = false; + } + - SDL_GL_SwapBuffers(); -+ SDL_Flip(screen); ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) ++ { ++ SDL_GL_SwapBuffers(); ++ } ++ else ++#endif ++ { ++ SDL_Flip(screen); ++ } } - void -@@ -433,9 +402,5 @@ - DrawingContext::set_target(Target target) + class RequestPtrCompare +@@ -644,36 +767,47 @@ { - this->target = target; -- if(target == LIGHTMAP) -- requests = &lightmap_requests; -- else -- requests = &drawing_requests; - } + // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it? + +- // create surface to hold screenshot +- #if SDL_BYTEORDER == SDL_BIG_ENDIAN +- SDL_Surface* shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0); +- #else +- SDL_Surface* shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0); +- #endif +- if (!shot_surf) { +- log_warning << "Could not create RGB Surface to contain screenshot" << std::endl; +- return; +- } ++ SDL_Surface *shot_surf; ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) ++ { ++ // create surface to hold screenshot ++ #if SDL_BYTEORDER == SDL_BIG_ENDIAN ++ shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0); ++ #else ++ shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0); ++ #endif ++ if (!shot_surf) { ++ log_warning << "Could not create RGB Surface to contain screenshot" << std::endl; ++ return; ++ } -diff -Naur supertux/src/video/drawing_context.hpp supertux-nogl/src/video/drawing_context.hpp ---- supertux/src/video/drawing_context.hpp 2006-03-03 20:34:27.000000000 +0100 -+++ supertux-nogl/src/video/drawing_context.hpp 2006-04-07 04:11:49.000000000 +0200 -@@ -23,7 +23,6 @@ - #include - #include +- // read pixels into array +- char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT]; +- if (!pixels) { +- log_warning << "Could not allocate memory to store screenshot" << std::endl; +- SDL_FreeSurface(shot_surf); +- return; +- } +- glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels); ++ // read pixels into array ++ char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT]; ++ if (!pixels) { ++ log_warning << "Could not allocate memory to store screenshot" << std::endl; ++ SDL_FreeSurface(shot_surf); ++ return; ++ } ++ glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels); + +- // copy array line-by-line +- for (int i = 0; i < SCREEN_HEIGHT; i++) { +- char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1)); +- char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch; +- memcpy(dst, src, 3 * SCREEN_WIDTH); ++ // copy array line-by-line ++ for (int i = 0; i < SCREEN_HEIGHT; i++) { ++ char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1)); ++ char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch; ++ memcpy(dst, src, 3 * SCREEN_WIDTH); ++ } ++ ++ // free array ++ delete[](pixels); + } ++ else ++#endif ++ { ++ shot_surf = SDL_GetVideoSurface(); ++ shot_surf->refcount++; ++ } --#include - #include - #include - #include -@@ -33,8 +32,9 @@ - #include "font.hpp" - #include "color.hpp" +- // free array +- delete[](pixels); +- + // save screenshot + static const std::string writeDir = PHYSFS_getWriteDir(); + static const std::string dirSep = PHYSFS_getDirSeparator(); +Index: src/video/texture_manager.hpp +=================================================================== +--- src/video/texture_manager.hpp (revision 5071) ++++ src/video/texture_manager.hpp (working copy) +@@ -20,7 +20,7 @@ + #ifndef __IMAGE_TEXTURE_MANAGER_HPP__ + #define __IMAGE_TEXTURE_MANAGER_HPP__ +-#include +#include "glutil.hpp" -+ - class Surface; --class Texture; - - // some constants for predefined layer values - enum { -@@ -202,16 +202,12 @@ - void draw_filled_rect(DrawingRequest& request); - - DrawingRequests drawing_requests; -- DrawingRequests lightmap_requests; - - DrawingRequests* requests; - - SDL_Surface* screen; - Target target; - std::vector target_stack; -- Texture* lightmap; -- int lightmap_width, lightmap_height; -- float lightmap_uv_right, lightmap_uv_bottom; - }; + #include + #include + #include +Index: src/video/texture.cpp +=================================================================== +--- src/video/texture.cpp (revision 5071) ++++ src/video/texture.cpp (working copy) +@@ -20,90 +20,134 @@ + #include - #endif -diff -Naur supertux/src/video/glutil.hpp supertux-nogl/src/video/glutil.hpp ---- supertux/src/video/glutil.hpp 2006-03-21 16:13:11.000000000 +0100 -+++ supertux-nogl/src/video/glutil.hpp 2006-04-07 04:11:49.000000000 +0200 -@@ -21,45 +21,14 @@ + #include "texture.hpp" ++#include "gameconfig.hpp" ++#include "glutil.hpp" - #include - #include -#include + #include +-#include "glutil.hpp" ++#include --static inline void assert_gl(const char* message) --{ --#ifdef DEBUG -- GLenum error = glGetError(); -- if(error != GL_NO_ERROR) { -- std::ostringstream msg; -- msg << "OpenGLError while '" << message << "': "; -- switch(error) { -- case GL_INVALID_ENUM: -- msg << "INVALID_ENUM: An unacceptable value is specified for an " -- "enumerated argument."; -- break; -- case GL_INVALID_VALUE: -- msg << "INVALID_VALUE: A numeric argument is out of range."; -- break; -- case GL_INVALID_OPERATION: -- msg << "INVALID_OPERATION: The specified operation is not allowed " -- "in the current state."; -- break; -- case GL_STACK_OVERFLOW: -- msg << "STACK_OVERFLOW: This command would cause a stack overflow."; -- break; -- case GL_STACK_UNDERFLOW: -- msg << "STACK_UNDERFLOW: This command would cause a stack underflow."; -- break; -- case GL_OUT_OF_MEMORY: -- msg << "OUT_OF_MEMORY: There is not enough memory left to execute the " -- "command."; -- break; -- default: -- msg << "Unknown error (code " << error << ")"; -- } -- -- throw std::runtime_error(msg.str()); -- } --#endif --} -+#define GLenum int -+#define GLint int -+#define GL_SRC_ALPHA 0 -+#define GL_ONE_MINUS_SRC_ALPHA 1 -+#define GL_RGBA 2 -+ -+ + static inline bool is_power_of_2(int v) + { + return (v & (v-1)) == 0; + } - #endif ++#ifdef HAVE_OPENGL + Texture::Texture(unsigned int w, unsigned int h, GLenum glformat) ++#else ++Texture::Texture(unsigned int w, unsigned int h, GLenum) ++#endif + { + assert(is_power_of_2(w)); + assert(is_power_of_2(h)); ++#ifdef HAVE_OPENGL ++ use_opengl = config->use_opengl; -diff -Naur supertux/src/video/screen.cpp supertux-nogl/src/video/screen.cpp ---- supertux/src/video/screen.cpp 2006-04-07 03:32:13.000000000 +0200 -+++ supertux-nogl/src/video/screen.cpp 2006-04-07 04:11:49.000000000 +0200 -@@ -38,61 +38,70 @@ +- this->width = w; +- this->height = h; ++ if(use_opengl) ++ { ++ surface.opengl.width = w; ++ surface.opengl.height = h; - static const float LOOP_DELAY = 20.0; +- assert_gl("before creating texture"); +- glGenTextures(1, &handle); ++ assert_gl("before creating texture"); ++ glGenTextures(1, &surface.opengl.handle); --void fillrect(float x, float y, float w, float h, const Color& col) --{ -- if(w < 0) { -- x += w; -- w = -w; -- } -- if(h < 0) { -- y += h; -- h = -h; -- } -- -- glColor4f(col.red, col.green, col.blue, col.alpha); +- try { +- glBindTexture(GL_TEXTURE_2D, handle); ++ try { ++ glBindTexture(GL_TEXTURE_2D, surface.opengl.handle); -- glDisable(GL_TEXTURE_2D); -- glBegin(GL_POLYGON); -- glVertex2f(x, y); -- glVertex2f(x+w, y); -- glVertex2f(x+w, y+h); -- glVertex2f(x, y+h); -- glEnd(); -- glEnable(GL_TEXTURE_2D); -- -- glColor4f(0, 0, 0, 1); -+void fillrect(float x, float y, float w, float h, int r, int g, int b, int a) -+ { -+ SDL_Surface* screen = SDL_GetVideoSurface(); -+ -+ if(w < 0) { -+ x += w; -+ w = -w; +- glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, +- GL_UNSIGNED_BYTE, 0); ++ glTexImage2D(GL_TEXTURE_2D, 0, glformat, surface.opengl.width, ++ surface.opengl.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + +- set_texture_params(); +- } catch(...) { +- glDeleteTextures(1, &handle); +- throw; ++ set_texture_params(); ++ } catch(...) { ++ glDeleteTextures(1, &surface.opengl.handle); ++ throw; + } -+ if(h < 0) { -+ y += h; -+ h = -h; + } ++ else ++#endif ++ { ++ surface.sdl = 0; ++ } + } + ++#ifdef HAVE_OPENGL + Texture::Texture(SDL_Surface* image, GLenum glformat) ++#else ++Texture::Texture(SDL_Surface* image, GLenum) ++#endif + { + const SDL_PixelFormat* format = image->format; + if(!is_power_of_2(image->w) || !is_power_of_2(image->h)) +- throw std::runtime_error("image has no power of 2 size"); ++ throw std::runtime_error("image does not have power of 2 size"); + if(format->BitsPerPixel != 24 && format->BitsPerPixel != 32) +- throw std::runtime_error("image has no 24 or 32 bit color depth"); ++ throw std::runtime_error("image does not have 24 or 32 bit color depth"); ++#ifdef HAVE_OPENGL ++ use_opengl = config->use_opengl; + +- this->width = image->w; +- this->height = image->h; ++ if(use_opengl) ++ { ++ surface.opengl.width = image->w; ++ surface.opengl.height = image->h; + +- assert_gl("before creating texture"); +- glGenTextures(1, &handle); ++ assert_gl("before creating texture"); ++ glGenTextures(1, &surface.opengl.handle); + +- try { +- GLenum sdl_format; +- if(format->BytesPerPixel == 3) +- sdl_format = GL_RGB; +- else if(format->BytesPerPixel == 4) +- sdl_format = GL_RGBA; +- else +- assert(false); ++ try { ++ GLenum sdl_format; ++ if(format->BytesPerPixel == 3) ++ sdl_format = GL_RGB; ++ else if(format->BytesPerPixel == 4) ++ sdl_format = GL_RGBA; ++ else ++ assert(false); + +- glBindTexture(GL_TEXTURE_2D, handle); +- glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +- glPixelStorei(GL_UNPACK_ROW_LENGTH, image->pitch/format->BytesPerPixel); +- glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, sdl_format, +- GL_UNSIGNED_BYTE, image->pixels); ++ glBindTexture(GL_TEXTURE_2D, surface.opengl.handle); ++ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); ++ glPixelStorei(GL_UNPACK_ROW_LENGTH, image->pitch/format->BytesPerPixel); ++ glTexImage2D(GL_TEXTURE_2D, 0, glformat, surface.opengl.width, ++ surface.opengl.height, 0, sdl_format, ++ GL_UNSIGNED_BYTE, image->pixels); + +- assert_gl("creating texture"); ++ assert_gl("creating texture"); + +- set_texture_params(); +- } catch(...) { +- glDeleteTextures(1, &handle); +- throw; ++ set_texture_params(); ++ } catch(...) { ++ glDeleteTextures(1, &surface.opengl.handle); ++ throw; + } + } ++ else ++#endif ++ { ++ surface.sdl = SDL_DisplayFormatAlpha(image); ++ } + } + + Texture::~Texture() + { +- glDeleteTextures(1, &handle); ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ glDeleteTextures(1, &surface.opengl.handle); ++ } ++ else ++#endif ++ { ++ SDL_FreeSurface(surface.sdl); ++ } + } + + void + Texture::set_texture_params() + { +- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); +- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + +- assert_gl("set texture params"); ++ assert_gl("set texture params"); ++ } ++#endif + } +Index: src/video/drawing_context.hpp +=================================================================== +--- src/video/drawing_context.hpp (revision 5071) ++++ src/video/drawing_context.hpp (working copy) +@@ -25,9 +25,9 @@ + + #include + +-#include + #include + ++#include "glutil.hpp" + #include "obstack/obstack.h" + #include "math/vector.hpp" + #include "math/rect.hpp" +Index: src/video/glutil.hpp +=================================================================== +--- src/video/glutil.hpp (revision 5071) ++++ src/video/glutil.hpp (working copy) +@@ -19,9 +19,14 @@ + #ifndef __GLUTIL_HPP__ + #define __GLUTIL_HPP__ + ++#include ++ ++#ifdef HAVE_OPENGL ++ + #include + #include + #include ++#include + + static inline void check_gl_error(const char* message) + { +@@ -77,4 +82,15 @@ + #endif + } + ++#else + -+ SDL_Rect src, rect; -+ SDL_Surface *temp = NULL; ++#define GLenum int ++#define GLint int ++#define GL_SRC_ALPHA 0 ++#define GL_ONE_MINUS_SRC_ALPHA 1 ++#define GL_RGBA 2 ++#define GL_ONE 3 + -+ rect.x = (int)x; -+ rect.y = (int)y; -+ rect.w = (int)w; -+ rect.h = (int)h; + #endif + -+ if(a != 255) { -+ temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); ++#endif +Index: src/video/texture.hpp +=================================================================== +--- src/video/texture.hpp (revision 5071) ++++ src/video/texture.hpp (working copy) +@@ -20,9 +20,15 @@ + #ifndef __TEXTURE_HPP__ + #define __TEXTURE_HPP__ + ++#include + -+ src.x = 0; -+ src.y = 0; -+ src.w = rect.w; -+ src.h = rect.h; ++#include + -+ SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b)); -+ SDL_SetAlpha(temp, SDL_SRCALPHA, a); -+ SDL_BlitSurface(temp,0,screen,&rect); -+ SDL_FreeSurface(temp); -+ } -+ else -+ SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b)); - } + #include +-#include - void fadeout(float fade_time) ++#include "gameconfig.hpp" ++#include "glutil.hpp" ++ + /** + * This class is a wrapper around a texture handle. It stores the texture width + * and height and provides convenience functions for uploading SDL_Surfaces +@@ -31,29 +37,82 @@ + class Texture { -- float alpha_inc = LOOP_DELAY / fade_time; -- Color c(0, 0, 0, alpha_inc); -- float alpha = 1.0; -+ float alpha_inc = 256 / (fade_time / LOOP_DELAY); -+ float alpha = 256; - -- while(alpha >= 0) { -+ while(alpha > 0) { - alpha -= alpha_inc; -- fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, c); -- // left side -+ fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0,0,0, (int)alpha_inc); // left side - -- SDL_GL_SwapBuffers(); -+ SDL_Flip(SDL_GetVideoSurface()); - sound_manager->update(); - - SDL_Delay(int(LOOP_DELAY)); -- alpha -= alpha_inc; - } -- -- fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, Color()); -+ fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0, 255); - } + protected: +- friend class TextureManager; +- GLuint handle; +- unsigned int width; +- unsigned int height; ++#ifdef HAVE_OPENGL ++ bool use_opengl; ++ union ++ { ++ struct ++ { ++ GLuint handle; ++ unsigned int width; ++ unsigned int height; ++ } opengl; ++#else ++ struct ++ { ++#endif ++ SDL_Surface *sdl; ++ } surface; - void shrink_fade(const Vector& point, float fade_time) - { -- float left_inc = point.x / (fade_time / LOOP_DELAY); -- float right_inc = (SCREEN_WIDTH - point.x) / (fade_time / LOOP_DELAY); -- float up_inc = point.y / (fade_time / LOOP_DELAY); -- float down_inc = (SCREEN_HEIGHT - point.y) / (fade_time / LOOP_DELAY); -+ float left_inc = point.x / ((float)fade_time / LOOP_DELAY); -+ float right_inc = (SCREEN_WIDTH - point.x) / ((float)fade_time / LOOP_DELAY); -+ float up_inc = point.y / ((float)fade_time / LOOP_DELAY); -+ float down_inc = (SCREEN_HEIGHT - point.y) / ((float)fade_time / LOOP_DELAY); - - float left_cor = 0, right_cor = 0, up_cor = 0, down_cor = 0; -- Color c; - - while(left_cor < point.x && right_cor < SCREEN_WIDTH - point.x && - up_cor < point.y && down_cor < SCREEN_HEIGHT - point.y) { -@@ -101,15 +110,14 @@ - up_cor += up_inc; - down_cor += down_inc; - -- fillrect(0, 0, left_cor, SCREEN_HEIGHT, c); // left side -- fillrect(SCREEN_WIDTH - right_cor, 0, right_cor, SCREEN_HEIGHT, c); // right side -- fillrect(0, 0, SCREEN_WIDTH, up_cor, c); // up side -- fillrect(0, SCREEN_HEIGHT - down_cor, SCREEN_WIDTH, down_cor+1, c); // down side -+ fillrect(0, 0, left_cor, SCREEN_HEIGHT, 0,0,0, 255); // left side -+ fillrect(SCREEN_WIDTH - right_cor, 0, right_cor, SCREEN_HEIGHT, 0,0,0, 255); // right side -+ fillrect(0, 0, SCREEN_WIDTH, up_cor, 0,0,0, 255); // up side -+ fillrect(0, SCREEN_HEIGHT - down_cor, SCREEN_WIDTH, down_cor+1, 0,0,0, 255); // down side - -- SDL_GL_SwapBuffers(); -+ SDL_Flip(SDL_GetVideoSurface()); - - sound_manager->update(); - SDL_Delay(int(LOOP_DELAY)); + public: + Texture(unsigned int width, unsigned int height, GLenum glformat); +- Texture(SDL_Surface* surface, GLenum glformat); ++ Texture(SDL_Surface* sdlsurface, GLenum glformat); + virtual ~Texture(); + +- GLuint get_handle() const ++#ifdef HAVE_OPENGL ++ const GLuint &get_handle() const { ++ assert(use_opengl); ++ return surface.opengl.handle; ++ } ++ ++ void set_handle(GLuint handle) { ++ assert(use_opengl); ++ surface.opengl.handle = handle; ++ } ++#endif ++ ++ SDL_Surface *get_surface() const + { +- return handle; ++#ifdef HAVE_OPENGL ++ assert(!use_opengl); ++#endif ++ return surface.sdl; } - } -- -diff -Naur supertux/src/video/screen.hpp supertux-nogl/src/video/screen.hpp ---- supertux/src/video/screen.hpp 2006-04-07 03:32:13.000000000 +0200 -+++ supertux-nogl/src/video/screen.hpp 2006-04-07 04:11:49.000000000 +0200 -@@ -20,7 +20,6 @@ - #define SUPERTUX_SCREEN_H - #include --#include - #include ++ void set_surface(SDL_Surface *sdlsurface) ++ { ++#ifdef HAVE_OPENGL ++ assert(!use_opengl); ++#endif ++ surface.sdl = sdlsurface; ++ } ++ + unsigned int get_width() const + { +- return width; ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ return surface.opengl.width; ++ } ++ else ++#endif ++ { ++ return surface.sdl->w; ++ } + } - #include -diff -Naur supertux/src/video/surface.cpp supertux-nogl/src/video/surface.cpp ---- supertux/src/video/surface.cpp 2006-03-25 01:16:31.000000000 +0100 -+++ supertux-nogl/src/video/surface.cpp 2006-04-07 04:11:49.000000000 +0200 -@@ -28,6 +29,7 @@ + unsigned int get_height() const + { +- return height; ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ return surface.opengl.height; ++ } ++ else ++#endif ++ { ++ return surface.sdl->h; ++ } + } + private: +Index: src/video/surface.cpp +=================================================================== +--- src/video/surface.cpp (revision 5071) ++++ src/video/surface.cpp (working copy) +@@ -29,6 +29,7 @@ #include #include -+#include ++#include "main.hpp" #include "gameconfig.hpp" #include "physfs/physfs_sdl.hpp" -@@ -40,13 +42,13 @@ + #include "video/surface.hpp" +@@ -41,13 +42,32 @@ { texture = texture_manager->get(file); texture->ref(); @@ -755,16 +854,35 @@ diff -Naur supertux/src/video/surface.cpp supertux-nogl/src/video/surface.cpp - width = texture->get_image_width(); - height = texture->get_image_height(); -+ offsetx = 0; -+ offsety = 0; -+ width = static_cast(texture->get_image_width()); -+ height = static_cast(texture->get_image_height()); ++#ifdef HAVE_OPENGL ++ use_opengl = config->use_opengl; ++ ++ if(use_opengl) ++ { ++ surface.opengl.uv_left = 0; ++ surface.opengl.uv_top = 0; ++ surface.opengl.uv_right = texture->get_uv_right(); ++ surface.opengl.uv_bottom = texture->get_uv_bottom(); ++ ++ surface.opengl.width = texture->get_image_width(); ++ surface.opengl.height = texture->get_image_height(); ++ } ++ else ++#endif ++ { ++ memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *)); ++ ++ surface.sdl.offsetx = 0; ++ surface.sdl.offsety = 0; ++ surface.sdl.width = static_cast(texture->get_image_width()); ++ surface.sdl.height = static_cast(texture->get_image_height()); + -+ flipx = false; ++ surface.sdl.flipx = false; ++ } } Surface::Surface(const std::string& file, int x, int y, int w, int h) -@@ -54,15 +56,12 @@ +@@ -55,15 +75,33 @@ texture = texture_manager->get(file); texture->ref(); @@ -774,17 +892,39 @@ diff -Naur supertux/src/video/surface.cpp supertux-nogl/src/video/surface.cpp - uv_top = static_cast(y) / tex_h; - uv_right = static_cast(x+w) / tex_w; - uv_bottom = static_cast(y+h) / tex_h; -- -+ offsetx = x; -+ offsety = y; - width = w; - height = h; ++#ifdef HAVE_OPENGL ++ use_opengl = config->use_opengl; + +- width = w; +- height = h; ++ if(use_opengl) ++ { ++ float tex_w = static_cast (texture->get_width()); ++ float tex_h = static_cast (texture->get_height()); ++ surface.opengl.uv_left = static_cast(x) / tex_w; ++ surface.opengl.uv_top = static_cast(y) / tex_h; ++ surface.opengl.uv_right = static_cast(x+w) / tex_w; ++ surface.opengl.uv_bottom = static_cast(y+h) / tex_h; ++ ++ surface.opengl.width = w; ++ surface.opengl.height = h; ++ } ++ else ++#endif ++ { ++ memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *)); ++ ++ surface.sdl.offsetx = x; ++ surface.sdl.offsety = y; ++ surface.sdl.width = w; ++ surface.sdl.height = h; + -+ flipx = false; ++ surface.sdl.flipx = false; ++ } } Surface::Surface(const Surface& other) -@@ -70,12 +69,12 @@ +@@ -71,12 +109,30 @@ texture = other.texture; texture->ref(); @@ -792,16 +932,36 @@ diff -Naur supertux/src/video/surface.cpp supertux-nogl/src/video/surface.cpp - uv_top = other.uv_top; - uv_right = other.uv_right; - uv_bottom = other.uv_bottom; -+ offsetx = other.offsetx; -+ offsety = other.offsety; - width = other.width; - height = other.height; +- width = other.width; +- height = other.height; ++#ifdef HAVE_OPENGL ++ use_opengl = config->use_opengl; ++ ++ if(use_opengl) ++ { ++ surface.opengl.uv_left = other.surface.opengl.uv_left; ++ surface.opengl.uv_top = other.surface.opengl.uv_top; ++ surface.opengl.uv_right = other.surface.opengl.uv_right; ++ surface.opengl.uv_bottom = other.surface.opengl.uv_bottom; ++ surface.opengl.width = other.surface.opengl.width; ++ surface.opengl.height = other.surface.opengl.height; ++ } ++ else ++#endif ++ { ++ memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *)); ++ ++ surface.sdl.offsetx = other.surface.sdl.offsetx; ++ surface.sdl.offsety = other.surface.sdl.offsety; ++ surface.sdl.width = other.surface.sdl.width; ++ surface.sdl.height = other.surface.sdl.height; + -+ flipx = other.flipx; ++ surface.sdl.flipx = other.surface.sdl.flipx; ++ } } const Surface& -@@ -85,81 +84,95 @@ +@@ -86,148 +142,584 @@ texture->unref(); texture = other.texture; @@ -809,12 +969,32 @@ diff -Naur supertux/src/video/surface.cpp supertux-nogl/src/video/surface.cpp - uv_top = other.uv_top; - uv_right = other.uv_right; - uv_bottom = other.uv_bottom; -+ offsetx = other.offsetx; -+ offsety = other.offsety; - width = other.width; - height = other.height; +- width = other.width; +- height = other.height; ++#ifdef HAVE_OPENGL ++ use_opengl = config->use_opengl; -+ flipx = other.flipx; ++ if(use_opengl) ++ { ++ surface.opengl.uv_left = other.surface.opengl.uv_left; ++ surface.opengl.uv_top = other.surface.opengl.uv_top; ++ surface.opengl.uv_right = other.surface.opengl.uv_right; ++ surface.opengl.uv_bottom = other.surface.opengl.uv_bottom; ++ surface.opengl.width = other.surface.opengl.width; ++ surface.opengl.height = other.surface.opengl.height; ++ } ++ else ++#endif ++ { ++ memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *)); ++ ++ surface.sdl.offsetx = other.surface.sdl.offsetx; ++ surface.sdl.offsety = other.surface.sdl.offsety; ++ surface.sdl.width = other.surface.sdl.width; ++ surface.sdl.height = other.surface.sdl.height; ++ ++ surface.sdl.flipx = other.surface.sdl.flipx; ++ } + return *this; } @@ -823,9 +1003,11 @@ diff -Naur supertux/src/video/surface.cpp supertux-nogl/src/video/surface.cpp { texture->unref(); + -+ for (std::list::iterator i = transformedSurfaces.begin(); i != transformedSurfaces.end(); i++) { -+ SDL_FreeSurface((*i)->surface); -+ delete (*i); ++#ifdef HAVE_OPENGL ++ if(!use_opengl) ++#endif ++ { ++ std::for_each(transforms, transforms + NUM_EFFECTS, SDL_FreeSurface); + } } @@ -833,333 +1015,637 @@ diff -Naur supertux/src/video/surface.cpp supertux-nogl/src/video/surface.cpp Surface::hflip() { - std::swap(uv_left, uv_right); --} -- ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ std::swap(surface.opengl.uv_left, surface.opengl.uv_right); ++ } ++ else ++#endif ++ { ++ surface.sdl.flipx = !surface.sdl.flipx; ++ } + } + -static inline void intern_draw(float left, float top, float right, float bottom, float uv_left, float uv_top, - float uv_right, float uv_bottom, - DrawingEffect effect) --{ ++#ifdef HAVE_OPENGL ++namespace + { - if(effect & HORIZONTAL_FLIP) - std::swap(uv_left, uv_right); - if(effect & VERTICAL_FLIP) { - std::swap(uv_top, uv_bottom); - } -- ++ inline void intern_draw(float left, float top, float right, float bottom, float uv_left, float uv_top, ++ float uv_right, float uv_bottom, ++ DrawingEffect effect) ++ { ++ if(effect & HORIZONTAL_FLIP) ++ std::swap(uv_left, uv_right); ++ if(effect & VERTICAL_FLIP) { ++ std::swap(uv_top, uv_bottom); ++ } + - glBegin(GL_QUADS); - glTexCoord2f(uv_left, uv_top); - glVertex2f(left, top); -- ++ glBegin(GL_QUADS); ++ glTexCoord2f(uv_left, uv_top); ++ glVertex2f(left, top); + - glTexCoord2f(uv_right, uv_top); - glVertex2f(right, top); -- ++ glTexCoord2f(uv_right, uv_top); ++ glVertex2f(right, top); + - glTexCoord2f(uv_right, uv_bottom); - glVertex2f(right, bottom); -- ++ glTexCoord2f(uv_right, uv_bottom); ++ glVertex2f(right, bottom); + - glTexCoord2f(uv_left, uv_bottom); - glVertex2f(left, bottom); - glEnd(); -+ flipx = !flipx; - } - - void - Surface::draw(float x, float y, float alpha, DrawingEffect effect) const - { -- glColor4f(1.0f, 1.0f, 1.0f, alpha); -- glBindTexture(GL_TEXTURE_2D, texture->get_handle()); -- -- intern_draw(x, y, -- x + width, y + height, -- uv_left, uv_top, uv_right, uv_bottom, effect); -+ draw_part(0, 0, x, y, width, height, alpha, effect); - } - - void - Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y, -- float width, float height, float alpha, -+ float width, float height, float, - DrawingEffect effect) const - { -- float uv_width = uv_right - uv_left; -- float uv_height = uv_bottom - uv_top; -- -- float uv_left = this->uv_left + (uv_width * src_x) / this->width; -- float uv_top = this->uv_top + (uv_height * src_y) / this->height; -- float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width; -- float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height; -- -- glColor4f(1.0f, 1.0f, 1.0f, alpha); -- glBindTexture(GL_TEXTURE_2D, texture->get_handle()); -- -- intern_draw(dst_x, dst_y, -- dst_x + width, dst_y + height, -- uv_left, uv_top, uv_right, uv_bottom, effect); -+ //FIXME: support parameter "alpha" -+ SDL_Surface* surface = texture->getSurface(); -+ -+ // get and check SDL_Surface -+ if (surface == 0) { -+ std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl; -+ return; -+ } -+ -+ SDL_Surface* transformedSurface = surface; -+ -+ if (flipx) effect = HORIZONTAL_FLIP; -+ -+ if (effect != NO_EFFECT) { -+ transformedSurface = 0; -+ -+ // check if we have this effect buffered -+ for (std::list::const_iterator i = transformedSurfaces.begin(); i != transformedSurfaces.end(); i++) { -+ if ((*i)->effect == effect) transformedSurface = (*i)->surface; -+ } -+ -+ // if not: transform and buffer -+ if (!transformedSurface) { -+ if (effect == HORIZONTAL_FLIP) transformedSurface = zoomSurface(surface, -1, 1, 0); -+ if (effect == VERTICAL_FLIP) transformedSurface = zoomSurface(surface, 1, -1, 0); -+ if (transformedSurface == 0) { -+ std::cerr << "Warning: No known transformation applies to surface, skipped draw" << std::endl; -+ return; -+ } -+ TransformedSurface* su = new TransformedSurface(); -+ su->surface = transformedSurface; -+ su->effect = effect; -+ -+ transformedSurfaces.push_front(su); -+ } -+ } -+ -+ int ox = offsetx; if (effect == HORIZONTAL_FLIP) ox = static_cast(surface->w) - (ox+static_cast(width)); -+ int oy = offsety; if (effect == VERTICAL_FLIP) oy = static_cast(surface->h) - (oy+static_cast(height)); -+ // draw surface to screen -+ SDL_Surface* screen = SDL_GetVideoSurface(); -+ -+ SDL_Rect srcRect; -+ srcRect.x = static_cast(ox+src_x); -+ srcRect.y = static_cast(oy+src_y); -+ srcRect.w = static_cast(width); -+ srcRect.h = static_cast(height); -+ -+ SDL_Rect dstRect; -+ dstRect.x = static_cast(dst_x); -+ dstRect.y = static_cast(dst_y); -+ -+ SDL_BlitSurface(transformedSurface, &srcRect, screen, &dstRect); - } - -diff -Naur supertux/src/video/surface.hpp supertux-nogl/src/video/surface.hpp ---- supertux/src/video/surface.hpp 2006-03-03 20:34:27.000000000 +0100 -+++ supertux-nogl/src/video/surface.hpp 2006-04-07 04:11:49.000000000 +0200 -@@ -20,7 +20,9 @@ - #ifndef __SURFACE_HPP__ - #define __SURFACE_HPP__ - -+#include - #include -+#include - - class ImageTexture; - -@@ -35,6 +37,15 @@ - }; - - /** -+ * Helper class to buffer a pre-transformed SDL_Surface -+ */ -+class TransformedSurface { -+ public: -+ SDL_Surface* surface; -+ DrawingEffect effect; -+}; -+ -+/** - * A rectangular image. - * The class basically holds a reference to a texture with additional UV - * coordinates that specify a rectangular area on this texture -@@ -46,18 +57,23 @@ - friend class Font; - ImageTexture* texture; - -- float uv_left; -- float uv_top; -- float uv_right; -- float uv_bottom; -+ bool flipx; - -+ /** draw the surface on the screen, applying a ::DrawingEffect on-the-fly. Transformed Surfaces will be cached in ::transformedSurfaces */ - void draw(float x, float y, float alpha, DrawingEffect effect) const; -+ -+ /** draw the surface on the screen, applying a ::DrawingEffect on-the-fly. Transformed Surfaces will be cached in ::transformedSurfaces */ - void draw_part(float src_x, float src_y, float dst_x, float dst_y, - float width, float height, - float alpha, DrawingEffect effect) const; - -- float width; -- float height; -+ int offsetx; /**< Region in ::surface to be used for blitting */ -+ int offsety; /**< Region in ::surface to be used for blitting */ -+ int width; /**< Region in ::surface to be used for blitting */ -+ int height; /**< Region in ::surface to be used for blitting */ -+ -+ mutable std::list transformedSurfaces; /**< Cache for pre-transformed surfaces */ -+ - public: - Surface(const std::string& file); - Surface(const std::string& file, int x, int y, int w, int h); -diff -Naur supertux/src/video/texture.cpp supertux-nogl/src/video/texture.cpp ---- supertux/src/video/texture.cpp 2006-03-03 20:34:27.000000000 +0100 -+++ supertux-nogl/src/video/texture.cpp 2006-04-07 04:11:49.000000000 +0200 -@@ -20,7 +20,6 @@ - - #include "texture.hpp" - --#include - #include - #include "glutil.hpp" - -@@ -29,81 +28,37 @@ - return (v & (v-1)) == 0; - } - --Texture::Texture(unsigned int w, unsigned int h, GLenum glformat) -+Texture::Texture(unsigned int w, unsigned int h, GLenum) - { - assert(is_power_of_2(w)); - assert(is_power_of_2(h)); - - this->width = w; - this->height = h; -- -- assert_gl("before creating texture"); -- glGenTextures(1, &handle); -- -- try { -- glBindTexture(GL_TEXTURE_2D, handle); -- -- glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, -- GL_UNSIGNED_BYTE, 0); -- -- set_texture_params(); -- } catch(...) { -- glDeleteTextures(1, &handle); -- throw; -- } -+ -+ surface = 0; - } - --Texture::Texture(SDL_Surface* image, GLenum glformat) -+Texture::Texture(SDL_Surface* image, GLenum) - { - const SDL_PixelFormat* format = image->format; - if(!is_power_of_2(image->w) || !is_power_of_2(image->h)) - throw std::runtime_error("image has no power of 2 size"); - if(format->BitsPerPixel != 24 && format->BitsPerPixel != 32) - throw std::runtime_error("image has no 24 or 32 bit color depth"); -- -+ - this->width = image->w; - this->height = image->h; - -- assert_gl("before creating texture"); -- glGenTextures(1, &handle); -- -- try { -- GLenum sdl_format; -- if(format->BytesPerPixel == 3) -- sdl_format = GL_RGB; -- else if(format->BytesPerPixel == 4) -- sdl_format = GL_RGBA; -- else -- assert(false); -- -- glBindTexture(GL_TEXTURE_2D, handle); -- glPixelStorei(GL_UNPACK_ALIGNMENT, 1); -- glPixelStorei(GL_UNPACK_ROW_LENGTH, image->pitch/format->BytesPerPixel); -- glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, sdl_format, -- GL_UNSIGNED_BYTE, image->pixels); -- -- assert_gl("creating texture"); +-} - -- set_texture_params(); -- } catch(...) { -- glDeleteTextures(1, &handle); -- throw; -- } -+ surface = SDL_DisplayFormatAlpha(image); - } +-static inline void intern_draw2(float left, float top, float right, float bottom, +- float uv_left, float uv_top, +- float uv_right, float uv_bottom, +- float angle, float alpha, +- const Color& color, +- const Blend& blend, +- DrawingEffect effect) +-{ +- if(effect & HORIZONTAL_FLIP) +- std::swap(uv_left, uv_right); +- if(effect & VERTICAL_FLIP) { +- std::swap(uv_top, uv_bottom); ++ glTexCoord2f(uv_left, uv_bottom); ++ glVertex2f(left, bottom); ++ glEnd(); + } - Texture::~Texture() - { -- glDeleteTextures(1, &handle); +- float center_x = (left + right) / 2; +- float center_y = (top + bottom) / 2; ++ inline void intern_draw2(float left, float top, float right, float bottom, ++ float uv_left, float uv_top, ++ float uv_right, float uv_bottom, ++ float angle, float alpha, ++ const Color& color, ++ const Blend& blend, ++ DrawingEffect effect) ++ { ++ if(effect & HORIZONTAL_FLIP) ++ std::swap(uv_left, uv_right); ++ if(effect & VERTICAL_FLIP) { ++ std::swap(uv_top, uv_bottom); ++ } + +- float sa = sinf(angle/180.0f*M_PI); +- float ca = cosf(angle/180.0f*M_PI); ++ float center_x = (left + right) / 2; ++ float center_y = (top + bottom) / 2; + +- left -= center_x; +- right -= center_x; ++ float sa = sinf(angle/180.0f*M_PI); ++ float ca = cosf(angle/180.0f*M_PI); + +- top -= center_y; +- bottom -= center_y; ++ left -= center_x; ++ right -= center_x; + +- glBlendFunc(blend.sfactor, blend.dfactor); +- glColor4f(color.red, color.green, color.blue, color.alpha * alpha); +- glBegin(GL_QUADS); +- glTexCoord2f(uv_left, uv_top); +- glVertex2f(left*ca - top*sa + center_x, +- left*sa + top*ca + center_y); ++ top -= center_y; ++ bottom -= center_y; + +- glTexCoord2f(uv_right, uv_top); +- glVertex2f(right*ca - top*sa + center_x, +- right*sa + top*ca + center_y); ++ glBlendFunc(blend.sfactor, blend.dfactor); ++ glColor4f(color.red, color.green, color.blue, color.alpha * alpha); ++ glBegin(GL_QUADS); ++ glTexCoord2f(uv_left, uv_top); ++ glVertex2f(left*ca - top*sa + center_x, ++ left*sa + top*ca + center_y); + +- glTexCoord2f(uv_right, uv_bottom); +- glVertex2f(right*ca - bottom*sa + center_x, +- right*sa + bottom*ca + center_y); ++ glTexCoord2f(uv_right, uv_top); ++ glVertex2f(right*ca - top*sa + center_x, ++ right*sa + top*ca + center_y); + +- glTexCoord2f(uv_left, uv_bottom); +- glVertex2f(left*ca - bottom*sa + center_x, +- left*sa + bottom*ca + center_y); +- glEnd(); ++ glTexCoord2f(uv_right, uv_bottom); ++ glVertex2f(right*ca - bottom*sa + center_x, ++ right*sa + bottom*ca + center_y); + +- // FIXME: find a better way to restore the blend mode +- glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ++ glTexCoord2f(uv_left, uv_bottom); ++ glVertex2f(left*ca - bottom*sa + center_x, ++ left*sa + bottom*ca + center_y); ++ glEnd(); ++ ++ // FIXME: find a better way to restore the blend mode ++ glColor4f(1.0f, 1.0f, 1.0f, 1.0f); ++ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ++ } } ++#endif void - Texture::set_texture_params() +-Surface::draw(float x, float y, float alpha, float angle, const Color& color, const Blend& blend, DrawingEffect effect) const ++Surface::draw(float x, float y, float alpha, ++#ifdef HAVE_OPENGL ++ float angle, const Color& color, const Blend& blend, ++#else ++ float, const Color&, const Blend&, ++#endif ++ DrawingEffect effect) const { -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); +- glBindTexture(GL_TEXTURE_2D, texture->get_handle()); - -- assert_gl("set texture params"); +- intern_draw2(x, y, +- x + width, y + height, +- uv_left, uv_top, uv_right, uv_bottom, +- angle, +- alpha, +- color, +- blend, +- effect); ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ glBindTexture(GL_TEXTURE_2D, texture->get_handle()); ++ intern_draw2(x, y, ++ x + surface.opengl.width, y + surface.opengl.height, ++ surface.opengl.uv_left, surface.opengl.uv_top, ++ surface.opengl.uv_right, surface.opengl.uv_bottom, ++ angle, ++ alpha, ++ color, ++ blend, ++ effect); ++ } ++ else ++#endif ++ { ++ draw_part(0, 0, x, y, surface.sdl.width, surface.sdl.height, alpha, effect); ++ } } -diff -Naur supertux/src/video/texture.hpp supertux-nogl/src/video/texture.hpp ---- supertux/src/video/texture.hpp 2006-03-03 20:34:27.000000000 +0100 -+++ supertux-nogl/src/video/texture.hpp 2006-04-07 04:11:49.000000000 +0200 -@@ -20,7 +20,7 @@ - #define __TEXTURE_HPP__ + void + Surface::draw(float x, float y, float alpha, DrawingEffect effect) const + { +- glBindTexture(GL_TEXTURE_2D, texture->get_handle()); ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ glBindTexture(GL_TEXTURE_2D, texture->get_handle()); ++ glColor4f(1, 1, 1, alpha); ++ intern_draw(x, y, ++ x + surface.opengl.width, y + surface.opengl.height, ++ surface.opengl.uv_left, surface.opengl.uv_top, ++ surface.opengl.uv_right, surface.opengl.uv_bottom, effect); ++ glColor4f(1, 1, 1, 1); ++ } ++ else ++#endif ++ { ++ draw_part(0, 0, x, y, surface.sdl.width, surface.sdl.height, alpha, effect); ++ } ++} - #include --#include -+#include "glutil.hpp" +- glColor4f(1, 1, 1, alpha); +- intern_draw(x, y, +- x + width, y + height, +- uv_left, uv_top, uv_right, uv_bottom, effect); +- glColor4f(1, 1, 1, 1); ++namespace ++{ ++#define BILINEAR ++ ++#ifdef NAIVE ++ SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator) ++ { ++ if(numerator == denominator) ++ { ++ src->refcount++; ++ return src; ++ } ++ else ++ { ++ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); ++ int bpp = dst->format->BytesPerPixel; ++ for(int y = 0;y < dst->h;y++) { ++ for(int x = 0;x < dst->w;x++) { ++ Uint8 *srcpixel = (Uint8 *) src->pixels + (y * denominator / numerator) * src->pitch + (x * denominator / numerator) * bpp; ++ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp; ++ switch(bpp) { ++ case 4: ++ dstpixel[3] = srcpixel[3]; ++ case 3: ++ dstpixel[2] = srcpixel[2]; ++ case 2: ++ dstpixel[1] = srcpixel[1]; ++ case 1: ++ dstpixel[0] = srcpixel[0]; ++ } ++ } ++ } ++ return dst; ++ } ++ } ++#endif ++ ++#ifdef BILINEAR ++ void getpixel(SDL_Surface *src, int srcx, int srcy, Uint8 color[4]) ++ { ++ int bpp = src->format->BytesPerPixel; ++ Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp; ++ Uint32 mapped = 0; ++ switch(bpp) { ++ case 1: ++ mapped = *srcpixel; ++ break; ++ case 2: ++ mapped = *(Uint16 *)srcpixel; ++ break; ++ case 3: ++#if SDL_BYTEORDER == SDL_BIG_ENDIAN ++ mapped |= srcpixel[0] << 16; ++ mapped |= srcpixel[1] << 8; ++ mapped |= srcpixel[2] << 0; ++#else ++ mapped |= srcpixel[0] << 0; ++ mapped |= srcpixel[1] << 8; ++ mapped |= srcpixel[2] << 16; ++#endif ++ break; ++ case 4: ++ mapped = *(Uint32 *)srcpixel; ++ break; ++ } ++ SDL_GetRGBA(mapped, src->format, &color[0], &color[1], &color[2], &color[3]); ++ } ++ ++ void merge(Uint8 color[4], Uint8 color0[4], Uint8 color1[4], int rem, int total) ++ { ++ color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total; ++ color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total; ++ color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total; ++ color[3] = (color0[3] * (total - rem) + color1[3] * rem) / total; ++ } ++ ++ SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator) ++ { ++ if(numerator == denominator) ++ { ++ src->refcount++; ++ return src; ++ } ++ else ++ { ++ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); ++ int bpp = dst->format->BytesPerPixel; ++ for(int y = 0;y < dst->h;y++) { ++ for(int x = 0;x < dst->w;x++) { ++ int srcx = x * denominator / numerator; ++ int srcy = y * denominator / numerator; ++ Uint8 color00[4], color01[4], color10[4], color11[4]; ++ getpixel(src, srcx, srcy, color00); ++ getpixel(src, srcx + 1, srcy, color01); ++ getpixel(src, srcx, srcy + 1, color10); ++ getpixel(src, srcx + 1, srcy + 1, color11); ++ Uint8 color0[4], color1[4], color[4]; ++ int remx = x * denominator % numerator; ++ merge(color0, color00, color01, remx, numerator); ++ merge(color1, color10, color11, remx, numerator); ++ int remy = y * denominator % numerator; ++ merge(color, color0, color1, remy, numerator); ++ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp; ++ Uint32 mapped = SDL_MapRGBA(dst->format, color[0], color[1], color[2], color[3]); ++ switch(bpp) { ++ case 1: ++ *dstpixel = mapped; ++ break; ++ case 2: ++ *(Uint16 *)dstpixel = mapped; ++ break; ++ case 3: ++#if SDL_BYTEORDER == SDL_BIG_ENDIAN ++ dstpixel[0] = (mapped >> 16) & 0xff; ++ dstpixel[1] = (mapped >> 8) & 0xff; ++ dstpixel[2] = (mapped >> 0) & 0xff; ++#else ++ dstpixel[0] = (mapped >> 0) & 0xff; ++ dstpixel[1] = (mapped >> 8) & 0xff; ++ dstpixel[2] = (mapped >> 16) & 0xff; ++#endif ++ break; ++ case 4: ++ *(Uint32 *)dstpixel = mapped; ++ break; ++ } ++ } ++ } ++ return dst; ++ } ++ } ++#endif ++ ++ // FIXME: Horizontal and vertical line problem ++#ifdef BRESENHAM ++ void accumulate(SDL_Surface *src, int srcx, int srcy, int color[4], int weight) ++ { ++ if(srcx < 0 || srcy < 0 || weight == 0) { ++ return; ++ } ++ int bpp = src->format->BytesPerPixel; ++ Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp; ++ Uint32 mapped = 0; ++ switch(bpp) { ++ case 1: ++ mapped = *srcpixel; ++ break; ++ case 2: ++ mapped = *(Uint16 *)srcpixel; ++ break; ++ case 3: ++#if SDL_BYTEORDER == SDL_BIG_ENDIAN ++ mapped |= srcpixel[0] << 16; ++ mapped |= srcpixel[1] << 8; ++ mapped |= srcpixel[2] << 0; ++#else ++ mapped |= srcpixel[0] << 0; ++ mapped |= srcpixel[1] << 8; ++ mapped |= srcpixel[2] << 16; ++#endif ++ break; ++ case 4: ++ mapped = *(Uint32 *)srcpixel; ++ break; ++ } ++ Uint8 red, green, blue, alpha; ++ SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha); ++ color[0] += red * weight; ++ color[1] += green * weight; ++ color[2] += blue * weight; ++ color[3] += alpha * weight; ++ } ++ ++ void accumulate_line(SDL_Surface *src, int srcy, int line[][4], int linesize, int weight, int numerator, int denominator) ++ { ++ int intpart = denominator / numerator; ++ int fractpart = denominator % numerator; ++ for(int x = 0, xe = 0, srcx = 0;x < linesize;x++) { ++ accumulate(src, srcx, srcy, line[x], (numerator - xe) * weight); ++ srcx++; ++ for(int i = 0;i < intpart - 1;i++) { ++ accumulate(src, srcx, srcy, line[x], numerator * weight); ++ srcx++; ++ } ++ xe += fractpart; ++ if(xe >= numerator) { ++ xe -= numerator; ++ srcx++; ++ } ++ accumulate(src, srcx, srcy, line[x], xe * weight); ++ } ++ } ++ ++ SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator) ++ { ++ if(numerator == denominator) ++ { ++ src->refcount++; ++ return src; ++ } ++ else ++ { ++ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); ++ int bpp = dst->format->BytesPerPixel; ++ int intpart = denominator / numerator; ++ int fractpart = denominator % numerator; ++ for(int y = 0, ye = 0, srcy = 0;y < dst->h;y++) { ++ int line[dst->w][4]; ++ memset(line, 0, sizeof(int) * dst->w * 4); ++ accumulate_line(src, srcy, line, dst->w, numerator - ye, numerator, denominator); ++ srcy++; ++ for(int i = 0;i < intpart - 1;i++) { ++ accumulate_line(src, srcy, line, dst->w, numerator, numerator, denominator); ++ srcy++; ++ } ++ ye += fractpart; ++ if(ye >= numerator) { ++ ye -= numerator; ++ srcy++; ++ } ++ accumulate_line(src, srcy, line, dst->w, ye, numerator, denominator); ++ for(int x = 0;x < dst->w;x++) { ++ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp; ++ Uint32 mapped = SDL_MapRGBA(dst->format, line[x][0] / (denominator * denominator), line[x][1] / (denominator * denominator), line[x][2] / (denominator * denominator), line[x][3] / (denominator * denominator)); ++ switch(bpp) { ++ case 1: ++ *dstpixel = mapped; ++ break; ++ case 2: ++ *(Uint16 *)dstpixel = mapped; ++ break; ++ case 3: ++#if SDL_BYTEORDER == SDL_BIG_ENDIAN ++ dstpixel[0] = (mapped >> 16) & 0xff; ++ dstpixel[1] = (mapped >> 8) & 0xff; ++ dstpixel[2] = (mapped >> 0) & 0xff; ++#else ++ dstpixel[0] = (mapped >> 0) & 0xff; ++ dstpixel[1] = (mapped >> 8) & 0xff; ++ dstpixel[2] = (mapped >> 16) & 0xff; ++#endif ++ break; ++ case 4: ++ *(Uint32 *)dstpixel = mapped; ++ break; ++ } ++ } ++ } ++ return dst; ++ } ++ } ++#endif ++ ++ SDL_Surface *horz_flip(SDL_Surface *src) ++ { ++ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); ++ int bpp = dst->format->BytesPerPixel; ++ for(int y = 0;y < dst->h;y++) { ++ for(int x = 0;x < dst->w;x++) { ++ Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp; ++ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + (dst->w - x - 1) * bpp; ++ switch(bpp) { ++ case 4: ++ dstpixel[3] = srcpixel[3]; ++ case 3: ++ dstpixel[2] = srcpixel[2]; ++ case 2: ++ dstpixel[1] = srcpixel[1]; ++ case 1: ++ dstpixel[0] = srcpixel[0]; ++ } ++ } ++ } ++ return dst; ++ } ++ ++ SDL_Surface *vert_flip(SDL_Surface *src) ++ { ++ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); ++ int bpp = dst->format->BytesPerPixel; ++ for(int y = 0;y < dst->h;y++) { ++ for(int x = 0;x < dst->w;x++) { ++ Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp; ++ Uint8 *dstpixel = (Uint8 *) dst->pixels + (dst->h - y - 1) * dst->pitch + x * bpp; ++ switch(bpp) { ++ case 4: ++ dstpixel[3] = srcpixel[3]; ++ case 3: ++ dstpixel[2] = srcpixel[2]; ++ case 2: ++ dstpixel[1] = srcpixel[1]; ++ case 1: ++ dstpixel[0] = srcpixel[0]; ++ } ++ } ++ } ++ return dst; ++ } + } - /** - * This class is a wrapper around a texture handle. It stores the texture width -@@ -30,8 +30,9 @@ - class Texture + void + Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y, ++#ifdef HAVE_OPENGL + float width, float height, float alpha, ++#else ++ float width, float height, float, ++#endif + DrawingEffect effect) const { - protected: -+ SDL_Surface* surface; /**< non-GL branch stores optimized surface */ -+ - friend class TextureManager; -- GLuint handle; - unsigned int width; - unsigned int height; +- float uv_width = uv_right - uv_left; +- float uv_height = uv_bottom - uv_top; ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ float uv_width = surface.opengl.uv_right - surface.opengl.uv_left; ++ float uv_height = surface.opengl.uv_bottom - surface.opengl.uv_top; -@@ -40,11 +41,6 @@ - Texture(SDL_Surface* surface, GLenum glformat); - virtual ~Texture(); - -- GLuint get_handle() const -- { -- return handle; -- } -- - unsigned int get_width() const - { - return width; -@@ -55,6 +51,14 @@ - return height; - } +- float uv_left = this->uv_left + (uv_width * src_x) / this->width; +- float uv_top = this->uv_top + (uv_height * src_y) / this->height; +- float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width; +- float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height; ++ float uv_left = surface.opengl.uv_left + (uv_width * src_x) / surface.opengl.width; ++ float uv_top = surface.opengl.uv_top + (uv_height * src_y) / surface.opengl.height; ++ float uv_right = surface.opengl.uv_left + (uv_width * (src_x + width)) / surface.opengl.width; ++ float uv_bottom = surface.opengl.uv_top + (uv_height * (src_y + height)) / surface.opengl.height; -+ SDL_Surface* getSurface() { -+ return surface; +- glBindTexture(GL_TEXTURE_2D, texture->get_handle()); ++ glBindTexture(GL_TEXTURE_2D, texture->get_handle()); ++ glColor4f(1, 1, 1, alpha); ++ intern_draw(dst_x, dst_y, ++ dst_x + width, dst_y + height, ++ uv_left, uv_top, uv_right, uv_bottom, effect); ++ glColor4f(1, 1, 1, 1); + } ++ else ++#endif ++ { ++ //FIXME: support parameter "alpha" ++ ++ // get and check SDL_Surface ++ if (texture->get_surface() == 0) { ++ std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl; ++ return; ++ } + +- glColor4f(1, 1, 1, alpha); +- intern_draw(dst_x, dst_y, +- dst_x + width, dst_y + height, +- uv_left, uv_top, uv_right, uv_bottom, effect); +- glColor4f(1, 1, 1, 1); ++ if (surface.sdl.flipx) effect = HORIZONTAL_FLIP; + -+ void setSurface(SDL_Surface* surface) { -+ this->surface = surface; -+ } ++ float xfactor = (float) config->screenwidth / SCREEN_WIDTH; ++ float yfactor = (float) config->screenheight / SCREEN_HEIGHT; ++ int numerator; ++ int denominator; ++ if(xfactor < yfactor) ++ { ++ numerator = config->screenwidth; ++ denominator = SCREEN_WIDTH; ++ } ++ else ++ { ++ numerator = config->screenheight; ++ denominator = SCREEN_HEIGHT; ++ } + - private: - void set_texture_params(); - }; -diff -Naur supertux/src/video/texture_manager.cpp supertux-nogl/src/video/texture_manager.cpp ---- supertux/src/video/texture_manager.cpp 2006-04-07 03:32:13.000000000 +0200 -+++ supertux-nogl/src/video/texture_manager.cpp 2006-04-07 04:11:49.000000000 +0200 -@@ -5,8 +5,6 @@ ++ if(transforms[effect] == 0) { ++ if(transforms[NO_EFFECT] == 0) { ++ transforms[NO_EFFECT] = scale(texture->get_surface(), numerator, denominator); ++ } ++ switch(effect) { ++ case NO_EFFECT: ++ break; ++ case HORIZONTAL_FLIP: ++ transforms[HORIZONTAL_FLIP] = horz_flip(transforms[NO_EFFECT]); ++ break; ++ case VERTICAL_FLIP: ++ transforms[VERTICAL_FLIP] = vert_flip(transforms[NO_EFFECT]); ++ break; ++ default: ++ std::cerr << "Warning: No known transformation applies to surface, skipped draw" << std::endl; ++ return; ++ } ++ } ++ ++ int ox = surface.sdl.offsetx; ++ if (effect == HORIZONTAL_FLIP) ox = static_cast(texture->get_surface()->w) - (ox+static_cast(width)); ++ int oy = surface.sdl.offsety; ++ if (effect == VERTICAL_FLIP) oy = static_cast(texture->get_surface()->h) - (oy+static_cast(height)); ++ // draw surface to screen ++ SDL_Surface* screen = SDL_GetVideoSurface(); ++ ++ SDL_Rect srcRect; ++ srcRect.x = static_cast((ox + src_x) * numerator / denominator); ++ srcRect.y = static_cast((oy + src_y) * numerator / denominator); ++ srcRect.w = static_cast(width * numerator / denominator); ++ srcRect.h = static_cast(height * numerator / denominator); ++ ++ SDL_Rect dstRect; ++ dstRect.x = static_cast(dst_x * numerator / denominator); ++ dstRect.y = static_cast(dst_y * numerator / denominator); ++ ++ SDL_BlitSurface(transforms[effect], &srcRect, screen, &dstRect); ++ } + } +Index: src/video/texture_manager.cpp +=================================================================== +--- src/video/texture_manager.cpp (revision 5071) ++++ src/video/texture_manager.cpp (working copy) +@@ -24,14 +24,13 @@ #include #include #include @@ -1168,7 +1654,14 @@ diff -Naur supertux/src/video/texture_manager.cpp supertux-nogl/src/video/textur #include #include #include -@@ -126,12 +124,6 @@ + #include "physfs/physfs_sdl.hpp" + #include "image_texture.hpp" + #include "glutil.hpp" ++#include "gameconfig.hpp" + #include "file_system.hpp" + #include "log.hpp" + +@@ -149,12 +148,16 @@ void TextureManager::save_textures() { @@ -1178,10 +1671,20 @@ diff -Naur supertux/src/video/texture_manager.cpp supertux-nogl/src/video/textur - glPixelStorei(GL_PACK_SKIP_ROWS, 0); - glPixelStorei(GL_PACK_SKIP_IMAGES, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 1); ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) { ++ glPixelStorei(GL_PACK_ROW_LENGTH, 0); ++ glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0); ++ glPixelStorei(GL_PACK_SKIP_PIXELS, 0); ++ glPixelStorei(GL_PACK_SKIP_ROWS, 0); ++ glPixelStorei(GL_PACK_SKIP_IMAGES, 0); ++ glPixelStorei(GL_PACK_ALIGNMENT, 1); ++ } ++#endif for(Textures::iterator i = textures.begin(); i != textures.end(); ++i) { save_texture(*i); } -@@ -146,75 +138,16 @@ +@@ -169,74 +172,90 @@ { SavedTexture saved_texture; saved_texture.texture = texture; @@ -1200,19 +1703,51 @@ diff -Naur supertux/src/video/texture_manager.cpp supertux-nogl/src/video/textur - &saved_texture.wrap_s); - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - &saved_texture.wrap_t); ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) { ++ glBindTexture(GL_TEXTURE_2D, texture->get_handle()); ++ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, ++ &saved_texture.width); ++ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, ++ &saved_texture.height); ++ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, ++ &saved_texture.border); ++ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ++ &saved_texture.min_filter); ++ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ++ &saved_texture.mag_filter); ++ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ++ &saved_texture.wrap_s); ++ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ++ &saved_texture.wrap_t); ++ } ++#endif size_t pixelssize = saved_texture.width * saved_texture.height * 4; saved_texture.pixels = new char[pixelssize]; -- + - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, - saved_texture.pixels); ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) { ++ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, ++ saved_texture.pixels); ++ } ++#endif saved_textures.push_back(saved_texture); -- + - glDeleteTextures(1, &(texture->handle)); - texture->handle = 0; -- ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) { ++ glDeleteTextures(1, &(texture->get_handle())); ++ texture->set_handle(0); + - assert_gl("retrieving texture for save"); ++ assert_gl("retrieving texture for save"); ++ } ++#endif } void @@ -1224,15 +1759,29 @@ diff -Naur supertux/src/video/texture_manager.cpp supertux-nogl/src/video/textur - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); -- ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) { ++ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); ++ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); ++ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); ++ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); ++ glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); ++ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + - for(std::vector::iterator i = saved_textures.begin(); - i != saved_textures.end(); ++i) { - SavedTexture& saved_texture = *i; -- ++ for(std::vector::iterator i = saved_textures.begin(); ++ i != saved_textures.end(); ++i) { ++ SavedTexture& saved_texture = *i; + - GLuint handle; - glGenTextures(1, &handle); - assert_gl("creating texture handle"); -- ++ GLuint handle; ++ glGenTextures(1, &handle); ++ assert_gl("creating texture handle"); + - glBindTexture(GL_TEXTURE_2D, handle); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - saved_texture.width, saved_texture.height, @@ -1240,7 +1789,14 @@ diff -Naur supertux/src/video/texture_manager.cpp supertux-nogl/src/video/textur - GL_UNSIGNED_BYTE, saved_texture.pixels); - delete[] saved_texture.pixels; - assert_gl("uploading texture pixel data"); -- ++ glBindTexture(GL_TEXTURE_2D, handle); ++ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ++ saved_texture.width, saved_texture.height, ++ saved_texture.border, GL_RGBA, ++ GL_UNSIGNED_BYTE, saved_texture.pixels); ++ delete[] saved_texture.pixels; ++ assert_gl("uploading texture pixel data"); + - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - saved_texture.min_filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, @@ -1249,23 +1805,267 @@ diff -Naur supertux/src/video/texture_manager.cpp supertux-nogl/src/video/textur - saved_texture.wrap_s); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - saved_texture.wrap_t); -- ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ++ saved_texture.min_filter); ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ++ saved_texture.mag_filter); ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ++ saved_texture.wrap_s); ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ++ saved_texture.wrap_t); + - assert_gl("setting texture_params"); - saved_texture.texture->handle = handle; -- } -- ++ assert_gl("setting texture_params"); ++ saved_texture.texture->set_handle(handle); ++ } + } ++#endif + saved_textures.clear(); } +Index: src/video/surface.hpp +=================================================================== +--- src/video/surface.hpp (revision 5071) ++++ src/video/surface.hpp (working copy) +@@ -20,7 +20,11 @@ + #ifndef __SURFACE_HPP__ + #define __SURFACE_HPP__ -diff -Naur supertux/src/video/texture_manager.hpp supertux-nogl/src/video/texture_manager.hpp ---- supertux/src/video/texture_manager.hpp 2006-03-03 20:34:27.000000000 +0100 -+++ supertux-nogl/src/video/texture_manager.hpp 2006-04-07 04:11:49.000000000 +0200 -@@ -1,7 +1,7 @@ - #ifndef __IMAGE_TEXTURE_MANAGER_HPP__ - #define __IMAGE_TEXTURE_MANAGER_HPP__ ++#include ++ + #include ++#include ++#include "gameconfig.hpp" + #include "math/vector.hpp" + + class Color; +@@ -30,11 +34,12 @@ + /// bitset for drawing effects + enum DrawingEffect { + /** Don't apply anything */ +- NO_EFFECT = 0x0000, ++ NO_EFFECT, + /** Draw the Surface upside down */ +- VERTICAL_FLIP = 0x0001, ++ VERTICAL_FLIP, + /** Draw the Surface from left to down */ +- HORIZONTAL_FLIP = 0x0002, ++ HORIZONTAL_FLIP, ++ NUM_EFFECTS + }; + + /** +@@ -47,21 +52,43 @@ + private: + friend class DrawingContext; + friend class Font; +- ImageTexture* texture; + +- float uv_left; +- float uv_top; +- float uv_right; +- float uv_bottom; +- + void draw(float x, float y, float alpha, float angle, const Color& color, const Blend& blend, DrawingEffect effect) const; + void draw(float x, float y, float alpha, DrawingEffect effect) const; + void draw_part(float src_x, float src_y, float dst_x, float dst_y, + float width, float height, + float alpha, DrawingEffect effect) const; + +- float width; +- float height; ++ ImageTexture* texture; ++#ifdef HAVE_OPENGL ++ bool use_opengl; ++ union ++ { ++ struct ++ { ++ float uv_left; ++ float uv_top; ++ float uv_right; ++ float uv_bottom; ++ ++ float width; ++ float height; ++ } opengl; ++#else ++ struct ++ { ++#endif ++ struct ++ { ++ bool flipx; ++ int offsetx; /**< Region in ::surface to be used for blitting */ ++ int offsety; /**< Region in ::surface to be used for blitting */ ++ int width; /**< Region in ::surface to be used for blitting */ ++ int height; /**< Region in ::surface to be used for blitting */ ++ } sdl; ++ } surface; ++ mutable SDL_Surface *transforms[NUM_EFFECTS]; /**< Cache for pre-transformed surfaces */ ++ + public: + Surface(const std::string& file); + Surface(const std::string& file, int x, int y, int w, int h); +@@ -75,12 +102,30 @@ + + float get_width() const + { +- return width; ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ return surface.opengl.width; ++ } ++ else ++#endif ++ { ++ return surface.sdl.width; ++ } + } + + float get_height() const + { +- return height; ++#ifdef HAVE_OPENGL ++ if(use_opengl) ++ { ++ return surface.opengl.height; ++ } ++ else ++#endif ++ { ++ return surface.sdl.height; ++ } + } + /** +Index: src/gameconfig.cpp +=================================================================== +--- src/gameconfig.cpp (revision 5071) ++++ src/gameconfig.cpp (working copy) +@@ -36,6 +36,9 @@ + Config::Config() + { + use_fullscreen = true; ++#ifdef HAVE_OPENGL ++ use_opengl = true; ++#endif + try_vsync = true; + show_fps = false; + sound_enabled = true; +@@ -70,7 +73,10 @@ + const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video"); + if(config_video_lisp) { + config_video_lisp->get("fullscreen", use_fullscreen); +- config_video_lisp->get("vsync", try_vsync); ++#ifdef HAVE_OPENGL ++ config_video_lisp->get("opengl", use_opengl); ++#endif ++ config_video_lisp->get("vsync", try_vsync); + config_video_lisp->get("width", screenwidth); + config_video_lisp->get("height", screenheight); + config_video_lisp->get("aspect_ratio", aspect_ratio); +@@ -100,6 +106,9 @@ + + writer.start_list("video"); + writer.write_bool("fullscreen", use_fullscreen); ++#ifdef HAVE_OPENGL ++ writer.write_bool("opengl", use_opengl); ++#endif + writer.write_bool("vsync", try_vsync); + writer.write_int("width", screenwidth); + writer.write_int("height", screenheight); +Index: src/main.cpp +=================================================================== +--- src/main.cpp (revision 5071) ++++ src/main.cpp (working copy) +@@ -33,7 +33,6 @@ + #include + #include + #include -#include -+#include "video/glutil.hpp" - #include - #include - #include + + #include "gameconfig.hpp" + #include "resources.hpp" +@@ -383,7 +382,11 @@ + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + +- int flags = SDL_OPENGL; ++#ifdef HAVE_OPENGL ++ int flags = config->use_opengl ? SDL_OPENGL : SDL_SWSURFACE; ++#else ++ int flags = SDL_SWSURFACE; ++#endif + if(config->use_fullscreen) + flags |= SDL_FULLSCREEN; + int width = config->screenwidth; +@@ -437,23 +440,28 @@ + + log_info << (config->use_fullscreen?"fullscreen ":"window ") << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << " Ratio: " << aspect_ratio << "\n"; + +- // setup opengl state and transform +- glDisable(GL_DEPTH_TEST); +- glDisable(GL_CULL_FACE); +- glEnable(GL_TEXTURE_2D); +- glEnable(GL_BLEND); +- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ++#ifdef HAVE_OPENGL ++ if(config->use_opengl) ++ { ++ // setup opengl state and transform ++ glDisable(GL_DEPTH_TEST); ++ glDisable(GL_CULL_FACE); ++ glEnable(GL_TEXTURE_2D); ++ glEnable(GL_BLEND); ++ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +- glViewport(0, 0, screen->w, screen->h); +- glMatrixMode(GL_PROJECTION); +- glLoadIdentity(); +- // logical resolution here not real monitor resolution +- glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0); +- glMatrixMode(GL_MODELVIEW); +- glLoadIdentity(); +- glTranslatef(0, 0, 0); ++ glViewport(0, 0, screen->w, screen->h); ++ glMatrixMode(GL_PROJECTION); ++ glLoadIdentity(); ++ // logical resolution here not real monitor resolution ++ glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0); ++ glMatrixMode(GL_MODELVIEW); ++ glLoadIdentity(); ++ glTranslatef(0, 0, 0); + +- check_gl_error("Setting up view matrices"); ++ check_gl_error("Setting up view matrices"); ++ } ++#endif + + if(texture_manager != NULL) + texture_manager->reload_textures(); +Index: configure.ac +=================================================================== +--- configure.ac (revision 5071) ++++ configure.ac (working copy) +@@ -154,9 +154,15 @@ + [AC_MSG_ERROR([Please install OpenAL])], + [], []) + +-AX_CHECK_GL +-if test "$no_gl" = "yes"; then +- AC_MSG_ERROR([Please install opengl libraries and headers]) ++AC_ARG_ENABLE(opengl, ++ AC_HELP_STRING([--enable-opengl], [enable opengl support]), ++ [enable_opengl=$enableval], [enable_opengl=yes]) ++ ++if test "$enable_opengl" = "yes"; then ++ AX_CHECK_GL ++ if test "$no_gl" != "yes"; then ++ AC_DEFINE_UNQUOTED(HAVE_OPENGL, 1, Define if OpenGL is present on the system) ++ fi + fi + + dnl Checks for library functions.