From: Tim Goya Date: Sat, 18 Aug 2007 01:21:26 +0000 (+0000) Subject: Precalculated renderer specific surface data, better management of multiple renderers... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=e7a12ed844f040d270e50ce25f74de5f017c1157;p=supertux.git Precalculated renderer specific surface data, better management of multiple renderers (all the big switches in one file and uses an enum), symbolic names for commonly used colors. SVN-Revision: 5143 --- diff --git a/src/gameconfig.cpp b/src/gameconfig.cpp index 80f27c020..61ca19e99 100644 --- a/src/gameconfig.cpp +++ b/src/gameconfig.cpp @@ -36,11 +36,7 @@ Config* config = 0; Config::Config() { use_fullscreen = true; -#ifdef HAVE_OPENGL - video = "opengl"; -#else - video = "sdl"; -#endif + video = OPENGL; try_vsync = true; show_fps = false; sound_enabled = true; @@ -78,7 +74,9 @@ Config::load() 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("video", video); + std::string video_string; + config_video_lisp->get("video", video_string); + video = get_video_system(video_string); config_video_lisp->get("vsync", try_vsync); config_video_lisp->get("width", screenwidth); config_video_lisp->get("height", screenheight); @@ -110,7 +108,7 @@ Config::save() writer.start_list("video"); writer.write_bool("fullscreen", use_fullscreen); - writer.write_string("video", video); + writer.write_string("video", get_video_string(video)); writer.write_bool("vsync", try_vsync); writer.write_int("width", screenwidth); writer.write_int("height", screenheight); diff --git a/src/gameconfig.hpp b/src/gameconfig.hpp index 0efeacd50..ac45730c7 100644 --- a/src/gameconfig.hpp +++ b/src/gameconfig.hpp @@ -23,6 +23,8 @@ #include +#include "video/video_systems.hpp" + class Config { public: @@ -41,7 +43,7 @@ public: float aspect_ratio; bool use_fullscreen; - std::string video; + VideoSystem video; bool try_vsync; bool show_fps; bool sound_enabled; diff --git a/src/video/color.cpp b/src/video/color.cpp new file mode 100644 index 000000000..46bccc421 --- /dev/null +++ b/src/video/color.cpp @@ -0,0 +1,30 @@ +// $Id: color.cpp 5063 2007-05-27 11:32:00Z matzeb $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + +#include "color.hpp" + +const Color Color::BLACK(0.0, 0.0, 0.0); +const Color Color::RED(1.0, 0.0, 0.0); +const Color Color::GREEN(0.0, 1.0, 0.0); +const Color Color::BLUE(0.0, 0.0, 1.0); +const Color Color::CYAN(0.0, 1.0, 1.0); +const Color Color::MAGENTA(1.0, 0.0, 1.0); +const Color Color::YELLOW(1.0, 1.0, 0.0); +const Color Color::WHITE(1.0, 1.0, 1.0); diff --git a/src/video/color.hpp b/src/video/color.hpp index e3ff67804..f0bd76d6b 100644 --- a/src/video/color.hpp +++ b/src/video/color.hpp @@ -77,6 +77,15 @@ public: } float red, green, blue, alpha; + + static const Color BLACK; + static const Color RED; + static const Color GREEN; + static const Color BLUE; + static const Color CYAN; + static const Color MAGENTA; + static const Color YELLOW; + static const Color WHITE; }; #endif diff --git a/src/video/drawing_context.cpp b/src/video/drawing_context.cpp index 428454da5..0a6485068 100644 --- a/src/video/drawing_context.cpp +++ b/src/video/drawing_context.cpp @@ -29,10 +29,9 @@ #include "drawing_context.hpp" #include "drawing_request.hpp" -#include "gl_renderer.hpp" -#include "gl_lightmap.hpp" -#include "sdl_renderer.hpp" -#include "sdl_lightmap.hpp" +#include "video_systems.hpp" +#include "renderer.hpp" +#include "lightmap.hpp" #include "surface.hpp" #include "main.hpp" #include "gameconfig.hpp" @@ -68,23 +67,11 @@ DrawingContext::~DrawingContext() void DrawingContext::init_renderer() { - if(renderer) - delete renderer; - if(lightmap) - delete lightmap; + delete renderer; + delete lightmap; -#ifdef HAVE_OPENGL - if(config->video == "opengl") - { - renderer = new GL::Renderer(); - lightmap = new GL::Lightmap(); - } - else -#endif - { - renderer = new SDL::Renderer(); - lightmap = new SDL::Lightmap(); - } + renderer = new_renderer(); + lightmap = new_lightmap(); } void diff --git a/src/video/gl_lightmap.cpp b/src/video/gl_lightmap.cpp index 6649a0e57..bc4c12b34 100644 --- a/src/video/gl_lightmap.cpp +++ b/src/video/gl_lightmap.cpp @@ -32,6 +32,7 @@ #include "glutil.hpp" #include "gl_lightmap.hpp" +#include "gl_surface_data.hpp" #include "drawing_context.hpp" #include "drawing_request.hpp" #include "renderer.hpp" @@ -195,14 +196,16 @@ namespace GL { const Surface* surface = (const Surface*) request.request_data; GL::Texture *gltexture = dynamic_cast(surface->get_texture()); + GL::SurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); + glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); intern_draw(request.pos.x, request.pos.y, request.pos.x + surface->get_width(), request.pos.y + surface->get_height(), - surface->get_uv_left(), - surface->get_uv_top(), - surface->get_uv_right(), - surface->get_uv_bottom(), + surface_data->get_uv_left(), + surface_data->get_uv_top(), + surface_data->get_uv_right(), + surface_data->get_uv_bottom(), request.angle, request.alpha, request.color, @@ -217,14 +220,15 @@ namespace GL = (SurfacePartRequest*) request.request_data; const Surface *surface = surfacepartrequest->surface; GL::Texture *gltexture = dynamic_cast(surface->get_texture()); + GL::SurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); - float uv_width = surface->get_uv_right() - surface->get_uv_left(); - float uv_height = surface->get_uv_bottom() - surface->get_uv_top(); + float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left(); + float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top(); - float uv_left = surface->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width(); - float uv_top = surface->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height(); - float uv_right = surface->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width(); - float uv_bottom = surface->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height(); + float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width(); + float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height(); + float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width(); + float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height(); glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); intern_draw(request.pos.x, request.pos.y, diff --git a/src/video/gl_renderer.cpp b/src/video/gl_renderer.cpp index 8158874c5..9fa6b0310 100644 --- a/src/video/gl_renderer.cpp +++ b/src/video/gl_renderer.cpp @@ -33,6 +33,7 @@ #include "glutil.hpp" #include "gl_renderer.hpp" #include "gl_texture.hpp" +#include "gl_surface_data.hpp" #include "drawing_context.hpp" #include "drawing_request.hpp" #include "surface.hpp" @@ -164,14 +165,16 @@ namespace GL { const Surface* surface = (const Surface*) request.request_data; GL::Texture *gltexture = dynamic_cast(surface->get_texture()); + GL::SurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); + glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); intern_draw(request.pos.x, request.pos.y, request.pos.x + surface->get_width(), request.pos.y + surface->get_height(), - surface->get_uv_left(), - surface->get_uv_top(), - surface->get_uv_right(), - surface->get_uv_bottom(), + surface_data->get_uv_left(), + surface_data->get_uv_top(), + surface_data->get_uv_right(), + surface_data->get_uv_bottom(), request.angle, request.alpha, request.color, @@ -186,14 +189,15 @@ namespace GL = (SurfacePartRequest*) request.request_data; const Surface *surface = surfacepartrequest->surface; GL::Texture *gltexture = dynamic_cast(surface->get_texture()); + GL::SurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); - float uv_width = surface->get_uv_right() - surface->get_uv_left(); - float uv_height = surface->get_uv_bottom() - surface->get_uv_top(); + float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left(); + float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top(); - float uv_left = surface->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width(); - float uv_top = surface->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height(); - float uv_right = surface->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width(); - float uv_bottom = surface->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height(); + float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width(); + float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height(); + float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width(); + float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height(); glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); intern_draw(request.pos.x, request.pos.y, diff --git a/src/video/gl_surface_data.hpp b/src/video/gl_surface_data.hpp new file mode 100644 index 000000000..a441f1095 --- /dev/null +++ b/src/video/gl_surface_data.hpp @@ -0,0 +1,73 @@ +// $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + +#ifdef HAVE_OPENGL + +#ifndef __GL_SURFACE_DATA_HPP__ +#define __GL_SURFACE_DATA_HPP__ + +#include "surface.hpp" + +namespace GL +{ + class SurfaceData + { + private: + const Surface &surface; + float uv_left; + float uv_top; + float uv_right; + float uv_bottom; + + public: + SurfaceData(const Surface &surface) : + surface(surface) + { + uv_left = (float) surface.get_x() / surface.get_texture()->get_texture_width(); + uv_top = (float) surface.get_y() / surface.get_texture()->get_texture_height(); + uv_right = (float) (surface.get_x() + surface.get_width()) / surface.get_texture()->get_texture_width(); + uv_bottom = (float) (surface.get_y() + surface.get_height()) / surface.get_texture()->get_texture_height(); + } + + float get_uv_left() const + { + return surface.get_flipx() ? uv_right : uv_left; + } + + float get_uv_top() const + { + return uv_top; + } + + float get_uv_right() const + { + return surface.get_flipx() ? uv_left : uv_right; + } + + float get_uv_bottom() const + { + return uv_bottom; + } + }; +} + +#endif + +#endif diff --git a/src/video/image_texture.cpp b/src/video/image_texture.cpp deleted file mode 100644 index c9a0de1d3..000000000 --- a/src/video/image_texture.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// $Id$ -// -// SuperTux -// Copyright (C) 2006 Matthias Braun -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#if 0 -#include - -#include "image_texture.hpp" -#include "texture_manager.hpp" - -ImageTexture::ImageTexture(SDL_Surface* surface) - : Texture(surface, GL_RGBA), refcount(0) -{ -} - -ImageTexture::~ImageTexture() -{ -} - -void -ImageTexture::release() -{ - texture_manager->release(this); -} -#endif diff --git a/src/video/image_texture.hpp b/src/video/image_texture.hpp deleted file mode 100644 index 9d32f761e..000000000 --- a/src/video/image_texture.hpp +++ /dev/null @@ -1,80 +0,0 @@ -// $Id$ -// -// SuperTux -// Copyright (C) 2006 Matthias Braun -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#if 0 -#ifndef __SURFACE_TEXTURE_HPP__ -#define __SURFACE_TEXTURE_HPP__ - -#include -#include -#include "texture.hpp" - -class ImageTexture : public Texture -{ -private: - std::string filename; - float image_width; - float image_height; - int refcount; - -public: - float get_image_width() const - { - return image_width; - } - - float get_image_height() const - { - return image_height; - } - - float get_uv_right() const - { - return image_width / static_cast (get_width()); - } - - float get_uv_bottom() const - { - return image_height / static_cast (get_height()); - } - - void ref() - { - refcount++; - } - - void unref() - { - assert(refcount > 0); - refcount--; - if(refcount == 0) - release(); - } - -private: - friend class TextureManager; - - ImageTexture(SDL_Surface* surface); - virtual ~ImageTexture(); - - void release(); -}; - -#endif -#endif diff --git a/src/video/sdl_lightmap.cpp b/src/video/sdl_lightmap.cpp index 52294b9ba..1020d0320 100644 --- a/src/video/sdl_lightmap.cpp +++ b/src/video/sdl_lightmap.cpp @@ -30,6 +30,7 @@ #include "glutil.hpp" #include "sdl_lightmap.hpp" #include "sdl_texture.hpp" +#include "sdl_surface_data.hpp" #include "drawing_context.hpp" #include "drawing_request.hpp" #include "renderer.hpp" @@ -50,6 +51,19 @@ namespace SDL width = screen->w; height = screen->h; + float xfactor = (float) config->screenwidth / SCREEN_WIDTH; + float yfactor = (float) config->screenheight / SCREEN_HEIGHT; + if(xfactor < yfactor) + { + numerator = config->screenwidth; + denominator = SCREEN_WIDTH; + } + else + { + numerator = config->screenheight; + denominator = SCREEN_HEIGHT; + } + red_channel = (Uint8 *)malloc(width * height * sizeof(Uint8)); green_channel = (Uint8 *)malloc(width * height * sizeof(Uint8)); blue_channel = (Uint8 *)malloc(width * height * sizeof(Uint8)); @@ -144,14 +158,13 @@ namespace SDL } } - void Lightmap::light_blit(SDL_Surface *src, int dstx, int dsty, - int srcx, int srcy, int blit_width, int blit_height) + void Lightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty) { int bpp = src->format->BytesPerPixel; - Uint8 *pixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp; + Uint8 *pixel = (Uint8 *) src->pixels + src_rect->y * src->pitch + src_rect->x * bpp; int loc = dsty * width + dstx; - for(int y = 0;y < blit_height;y++) { - for(int x = 0;x < blit_width;x++, pixel += bpp, loc++) { + for(int y = 0;y < src_rect->h;y++) { + for(int x = 0;x < src_rect->w;x++, pixel += bpp, loc++) { if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height) { continue; @@ -203,8 +216,8 @@ namespace SDL blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum; } } - pixel += src->pitch - blit_width * bpp; - loc += width - blit_width; + pixel += src->pitch - src_rect->w * bpp; + loc += width - src_rect->w; } } @@ -219,6 +232,8 @@ namespace SDL const Surface* surface = (const Surface*) request.request_data; SDL::Texture *sdltexture = dynamic_cast(surface->get_texture()); + SDL::SurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); + DrawingEffect effect = request.drawing_effect; if (surface->get_flipx()) effect = HORIZONTAL_FLIP; @@ -230,45 +245,10 @@ namespace SDL return; } - int ox, oy; - if (effect == HORIZONTAL_FLIP) - { - ox = sdltexture->get_texture_width() - surface->get_x() - surface->get_width(); - } - else - { - ox = surface->get_x(); - } - if (effect == VERTICAL_FLIP) - { - oy = sdltexture->get_texture_height() - surface->get_y() - surface->get_height(); - } - else - { - oy = surface->get_y(); - } - - int numerator, denominator; - float xfactor = (float) config->screenwidth / SCREEN_WIDTH; - float yfactor = (float) config->screenheight / SCREEN_HEIGHT; - if(xfactor < yfactor) - { - numerator = config->screenwidth; - denominator = SCREEN_WIDTH; - } - else - { - numerator = config->screenheight; - denominator = SCREEN_HEIGHT; - } - + SDL_Rect *src_rect = surface_data->get_src_rect(effect); int dstx = (int) request.pos.x * numerator / denominator; int dsty = (int) request.pos.y * numerator / denominator; - int srcx = ox * numerator / denominator; - int srcy = oy * numerator / denominator; - int blit_width = surface->get_width() * numerator / denominator; - int blit_height = surface->get_height() * numerator / denominator; - light_blit(transform, dstx, dsty, srcx, srcy, blit_width, blit_height); + light_blit(transform, src_rect, dstx, dsty); } void @@ -279,6 +259,7 @@ namespace SDL const Surface* surface = surfacepartrequest->surface; SDL::Texture *sdltexture = dynamic_cast(surface->get_texture()); + DrawingEffect effect = request.drawing_effect; if (surface->get_flipx()) effect = HORIZONTAL_FLIP; @@ -308,27 +289,14 @@ namespace SDL oy = surface->get_y(); } - int numerator, denominator; - float xfactor = (float) config->screenwidth / SCREEN_WIDTH; - float yfactor = (float) config->screenheight / SCREEN_HEIGHT; - if(xfactor < yfactor) - { - numerator = config->screenwidth; - denominator = SCREEN_WIDTH; - } - else - { - numerator = config->screenheight; - denominator = SCREEN_HEIGHT; - } - + SDL_Rect src_rect; + src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator; + src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator; + src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator; + src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator; int dstx = (int) request.pos.x * numerator / denominator; int dsty = (int) request.pos.y * numerator / denominator; - int srcx = (ox + (int) surfacepartrequest->source.x) * numerator / denominator; - int srcy = (oy + (int) surfacepartrequest->source.y) * numerator / denominator; - int blit_width = (int) surfacepartrequest->size.x * numerator / denominator; - int blit_height = (int) surfacepartrequest->size.y * numerator / denominator; - light_blit(transform, dstx, dsty, srcx, srcy, blit_width, blit_height); + light_blit(transform, &src_rect, dstx, dsty); } void diff --git a/src/video/sdl_lightmap.hpp b/src/video/sdl_lightmap.hpp index 985615ab6..ab7e1bc8d 100644 --- a/src/video/sdl_lightmap.hpp +++ b/src/video/sdl_lightmap.hpp @@ -50,9 +50,9 @@ namespace SDL Uint8 *blue_channel; Uint8 *green_channel; int width, height; + int numerator, denominator; - void light_blit(SDL_Surface *src, int dstx, int dsty, - int srcx, int srcy, int blit_width, int blit_height); + void light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty); }; } diff --git a/src/video/sdl_renderer.cpp b/src/video/sdl_renderer.cpp index 25fa832e5..90ee2a134 100644 --- a/src/video/sdl_renderer.cpp +++ b/src/video/sdl_renderer.cpp @@ -31,12 +31,14 @@ #include "glutil.hpp" #include "sdl_renderer.hpp" #include "sdl_texture.hpp" +#include "sdl_surface_data.hpp" #include "drawing_context.hpp" #include "drawing_request.hpp" #include "surface.hpp" #include "font.hpp" #include "main.hpp" #include "gameconfig.hpp" +#include "log.hpp" #include "texture.hpp" #include "texture_manager.hpp" #include "obstack/obstackpp.hpp" @@ -45,21 +47,43 @@ namespace SDL { Renderer::Renderer() { - int flags = SDL_SWSURFACE; + const SDL_VideoInfo *info = SDL_GetVideoInfo(); + log_info << "Hardware surfaces are " << (info->hw_available ? "" : "not ") << "available." << std::endl; + log_info << "Hardware to hardware blits are " << (info->blit_hw ? "" : "not ") << "accelerated." << std::endl; + log_info << "Hardware to hardware blits with colorkey are " << (info->blit_hw_CC ? "" : "not ") << "accelerated." << std::endl; + log_info << "Hardware to hardware blits with alpha are " << (info->blit_hw_A ? "" : "not ") << "accelerated." << std::endl; + log_info << "Software to hardware blits are " << (info->blit_sw ? "" : "not ") << "accelerated." << std::endl; + log_info << "Software to hardware blits with colorkey are " << (info->blit_sw_CC ? "" : "not ") << "accelerated." << std::endl; + log_info << "Software to hardware blits with alpha are " << (info->blit_sw_A ? "" : "not ") << "accelerated." << std::endl; + log_info << "Color fills are " << (info->blit_fill ? "" : "not ") << "accelerated." << std::endl; + + int flags = SDL_SWSURFACE | SDL_ANYFORMAT; if(config->use_fullscreen) flags |= SDL_FULLSCREEN; int width = config->screenwidth; int height = config->screenheight; - int bpp = 0; - screen = SDL_SetVideoMode(width, height, bpp, flags); + screen = SDL_SetVideoMode(width, height, 0, flags); if(screen == 0) { std::stringstream msg; msg << "Couldn't set video mode (" << width << "x" << height - << "-" << bpp << "bpp): " << SDL_GetError(); + << "): " << SDL_GetError(); throw std::runtime_error(msg.str()); } + float xfactor = (float) config->screenwidth / SCREEN_WIDTH; + float yfactor = (float) config->screenheight / SCREEN_HEIGHT; + if(xfactor < yfactor) + { + numerator = config->screenwidth; + denominator = SCREEN_WIDTH; + } + else + { + numerator = config->screenheight; + denominator = SCREEN_HEIGHT; + } + if(texture_manager == 0) texture_manager = new TextureManager(); } @@ -73,7 +97,9 @@ namespace SDL { //FIXME: support parameters request.alpha, request.angle, request.blend const Surface* surface = (const Surface*) request.request_data; - SDL::Texture *sdltexture = dynamic_cast(surface->get_texture()); + SDL::Texture *sdltexture = dynamic_cast(surface->get_texture()); + SDL::SurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); + DrawingEffect effect = request.drawing_effect; if (surface->get_flipx()) effect = HORIZONTAL_FLIP; @@ -85,49 +111,12 @@ namespace SDL return; } - int ox, oy; - if (effect == HORIZONTAL_FLIP) - { - ox = sdltexture->get_texture_width() - surface->get_x() - surface->get_width(); - } - else - { - ox = surface->get_x(); - } - if (effect == VERTICAL_FLIP) - { - oy = sdltexture->get_texture_height() - surface->get_y() - surface->get_height(); - } - else - { - oy = surface->get_y(); - } - - int numerator, denominator; - float xfactor = (float) config->screenwidth / SCREEN_WIDTH; - float yfactor = (float) config->screenheight / SCREEN_HEIGHT; - if(xfactor < yfactor) - { - numerator = config->screenwidth; - denominator = SCREEN_WIDTH; - } - else - { - numerator = config->screenheight; - denominator = SCREEN_HEIGHT; - } - - SDL_Rect srcRect; - srcRect.x = ox * numerator / denominator; - srcRect.y = oy * numerator / denominator; - srcRect.w = surface->get_width() * numerator / denominator; - srcRect.h = surface->get_height() * numerator / denominator; - - SDL_Rect dstRect; - dstRect.x = (int) request.pos.x * numerator / denominator; - dstRect.y = (int) request.pos.y * numerator / denominator; + SDL_Rect *src_rect = surface_data->get_src_rect(effect); + SDL_Rect dst_rect; + dst_rect.x = (int) request.pos.x * numerator / denominator; + dst_rect.y = (int) request.pos.y * numerator / denominator; - SDL_BlitSurface(transform, &srcRect, screen, &dstRect); + SDL_BlitSurface(transform, src_rect, screen, &dst_rect); } void @@ -137,7 +126,8 @@ namespace SDL = (SurfacePartRequest*) request.request_data; const Surface* surface = surfacepartrequest->surface; - SDL::Texture *sdltexture = dynamic_cast(surface->get_texture()); + SDL::Texture *sdltexture = dynamic_cast(surface->get_texture()); + DrawingEffect effect = request.drawing_effect; if (surface->get_flipx()) effect = HORIZONTAL_FLIP; @@ -167,31 +157,17 @@ namespace SDL oy = surface->get_y(); } - int numerator, denominator; - float xfactor = (float) config->screenwidth / SCREEN_WIDTH; - float yfactor = (float) config->screenheight / SCREEN_HEIGHT; - if(xfactor < yfactor) - { - numerator = config->screenwidth; - denominator = SCREEN_WIDTH; - } - else - { - numerator = config->screenheight; - denominator = SCREEN_HEIGHT; - } - - SDL_Rect srcRect; - srcRect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator; - srcRect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator; - srcRect.w = (int) surfacepartrequest->size.x * numerator / denominator; - srcRect.h = (int) surfacepartrequest->size.y * numerator / denominator; + SDL_Rect src_rect; + src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator; + src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator; + src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator; + src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator; - SDL_Rect dstRect; - dstRect.x = (int) request.pos.x * numerator / denominator; - dstRect.y = (int) request.pos.y * numerator / denominator; + SDL_Rect dst_rect; + dst_rect.x = (int) request.pos.x * numerator / denominator; + dst_rect.y = (int) request.pos.y * numerator / denominator; - SDL_BlitSurface(transform, &srcRect, screen, &dstRect); + SDL_BlitSurface(transform, &src_rect, screen, &dst_rect); } void diff --git a/src/video/sdl_renderer.hpp b/src/video/sdl_renderer.hpp index 8c943f1e1..24dcb84ff 100644 --- a/src/video/sdl_renderer.hpp +++ b/src/video/sdl_renderer.hpp @@ -40,6 +40,7 @@ namespace SDL void flip(); private: SDL_Surface *screen; + int numerator, denominator; }; } diff --git a/src/video/sdl_surface_data.hpp b/src/video/sdl_surface_data.hpp new file mode 100644 index 000000000..1e46e683a --- /dev/null +++ b/src/video/sdl_surface_data.hpp @@ -0,0 +1,80 @@ +// $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#ifndef __SDL_SURFACE_DATA_HPP__ +#define __SDL_SURFACE_DATA_HPP__ + +#include + +#include "surface.hpp" +#include "texture.hpp" +#include "main.hpp" +#include "gameconfig.hpp" + +namespace SDL +{ + class SurfaceData + { + private: + const Surface &surface; + SDL_Rect src_rects[NUM_EFFECTS]; + + public: + SurfaceData(const Surface &surface) : + surface(surface) + { + int numerator, denominator; + float xfactor = (float) config->screenwidth / SCREEN_WIDTH; + float yfactor = (float) config->screenheight / SCREEN_HEIGHT; + if(xfactor < yfactor) + { + numerator = config->screenwidth; + denominator = SCREEN_WIDTH; + } + else + { + numerator = config->screenheight; + denominator = SCREEN_HEIGHT; + } + + src_rects[NO_EFFECT].x = surface.get_x() * numerator / denominator; + src_rects[NO_EFFECT].y = surface.get_y() * numerator / denominator; + src_rects[NO_EFFECT].w = surface.get_width() * numerator / denominator; + src_rects[NO_EFFECT].h = surface.get_height() * numerator / denominator; + + int flipped_x = surface.get_texture()->get_texture_width() - surface.get_x() - surface.get_width(); + src_rects[HORIZONTAL_FLIP].x = flipped_x * numerator / denominator; + src_rects[HORIZONTAL_FLIP].y = surface.get_y() * numerator / denominator; + src_rects[HORIZONTAL_FLIP].w = surface.get_width() * numerator / denominator; + src_rects[HORIZONTAL_FLIP].h = surface.get_height() * numerator / denominator; + + int flipped_y = surface.get_texture()->get_texture_height() - surface.get_y() - surface.get_height(); + src_rects[VERTICAL_FLIP].x = flipped_y * numerator / denominator; + src_rects[VERTICAL_FLIP].y = surface.get_y() * numerator / denominator; + src_rects[VERTICAL_FLIP].w = surface.get_width() * numerator / denominator; + src_rects[VERTICAL_FLIP].h = surface.get_height() * numerator / denominator; + } + + SDL_Rect *get_src_rect(DrawingEffect effect) + { + return src_rects + effect; + } + }; +} + +#endif diff --git a/src/video/sdl_texture.cpp b/src/video/sdl_texture.cpp index 917a4df48..2eb5de6cb 100644 --- a/src/video/sdl_texture.cpp +++ b/src/video/sdl_texture.cpp @@ -327,8 +327,6 @@ namespace return dst; } - const Color white(1.0, 1.0, 1.0); - SDL_Surface *colorize(SDL_Surface *src, const Color &color) { // FIXME: This is really slow @@ -416,7 +414,7 @@ namespace SDL numerator = config->screenheight; denominator = SCREEN_HEIGHT; } - cache[NO_EFFECT][white] = scale(texture, numerator, denominator); + cache[NO_EFFECT][Color::WHITE] = scale(texture, numerator, denominator); } Texture::~Texture() @@ -427,8 +425,8 @@ namespace SDL SDL_Surface *Texture::get_transform(const Color &color, DrawingEffect effect) { if(cache[NO_EFFECT][color] == 0) { - assert(cache[NO_EFFECT][white]); - cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][white], color); + assert(cache[NO_EFFECT][Color::WHITE]); + cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][Color::WHITE], color); } if(cache[effect][color] == 0) { assert(cache[NO_EFFECT][color]); diff --git a/src/video/surface.hpp b/src/video/surface.hpp index e1b7cd425..d90494bfd 100644 --- a/src/video/surface.hpp +++ b/src/video/surface.hpp @@ -26,6 +26,7 @@ #include #include "math/vector.hpp" #include "texture.hpp" +#include "video_systems.hpp" /** * A rectangular image. @@ -36,6 +37,7 @@ class Surface { private: Texture* texture; + void *surface_data; int x; int y; int w; @@ -51,6 +53,7 @@ public: texture->ref(); w = texture->get_image_width(); h = texture->get_image_height(); + surface_data = new_surface_data(*this); } Surface(const std::string& file, int x, int y, int w, int h) : @@ -59,6 +62,7 @@ public: flipx(false) { texture->ref(); + surface_data = new_surface_data(*this); } Surface(const Surface& other) : @@ -68,10 +72,12 @@ public: flipx(false) { texture->ref(); + surface_data = new_surface_data(*this); } ~Surface() { + free_surface_data(surface_data); texture->unref(); } @@ -103,6 +109,11 @@ public: return texture; } + void *get_surface_data() const + { + return surface_data; + } + int get_x() const { return x; @@ -131,30 +142,6 @@ public: */ Vector get_size() const { return Vector(get_width(), get_height()); } - - float get_uv_left() const - { - return (float) (x + (flipx ? w : 0)) / texture->get_texture_width(); - } - - float get_uv_top() const - { - return (float) y / texture->get_texture_height(); - } - - float get_uv_right() const - { - return (float) (x + (flipx ? 0 : w)) / texture->get_texture_width(); - } - - float get_uv_bottom() const - { - return (float) (y + h) / texture->get_texture_height(); - } - - //void draw_part(float src_x, float src_y, float dst_x, float dst_y, - // float width, float height, float alpha, - // DrawingEffect effect) const; }; #endif diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index 7b556a642..0e0008696 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -28,8 +28,8 @@ #include #include #include "physfs/physfs_sdl.hpp" +#include "video_systems.hpp" #include "gl_texture.hpp" -#include "sdl_texture.hpp" #include "glutil.hpp" #include "gameconfig.hpp" #include "file_system.hpp" @@ -103,16 +103,7 @@ TextureManager::create_image_texture(const std::string& filename) Texture* result = 0; try { -#ifdef HAVE_OPENGL - if(config->video == "opengl") - { - result = new GL::Texture(image); - } - else -#endif - { - result = new SDL::Texture(image); - } + result = new_texture(image); result->set_filename(filename); } catch(...) { delete result; diff --git a/src/video/video_systems.cpp b/src/video/video_systems.cpp new file mode 100644 index 000000000..29404e042 --- /dev/null +++ b/src/video/video_systems.cpp @@ -0,0 +1,139 @@ +// $Id: video_systems.cpp 5063 2007-05-27 11:32:00Z matzeb $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + +#include "video_systems.hpp" +#include "gameconfig.hpp" +#include "renderer.hpp" +#include "gl_renderer.hpp" +#include "sdl_renderer.hpp" +#include "lightmap.hpp" +#include "gl_lightmap.hpp" +#include "sdl_lightmap.hpp" +#include "texture.hpp" +#include "gl_texture.hpp" +#include "sdl_texture.hpp" +#include "gl_surface_data.hpp" +#include "sdl_surface_data.hpp" + +Renderer *new_renderer() +{ + switch(config->video) + { +#ifdef HAVE_OPENGL + case OPENGL: + return new GL::Renderer(); +#endif + case PURE_SDL: + return new SDL::Renderer(); + default: + assert(0 && "invalid video system in config"); + return new SDL::Renderer(); + } +} + +Lightmap *new_lightmap() +{ + switch(config->video) + { +#ifdef HAVE_OPENGL + case OPENGL: + return new GL::Lightmap(); +#endif + case PURE_SDL: + return new SDL::Lightmap(); + default: + assert(0 && "invalid video system in config"); + return new SDL::Lightmap(); + } +} + +Texture *new_texture(SDL_Surface *image) +{ + switch(config->video) + { +#ifdef HAVE_OPENGL + case OPENGL: + return new GL::Texture(image); +#endif + case PURE_SDL: + return new SDL::Texture(image); + default: + assert(0 && "invalid video system in config"); + return new SDL::Texture(image); + } +} + +void *new_surface_data(const Surface &surface) +{ + switch(config->video) + { +#ifdef HAVE_OPENGL + case OPENGL: + return new GL::SurfaceData(surface); +#endif + case PURE_SDL: + return new SDL::SurfaceData(surface); + default: + assert(0 && "invalid video system in config"); + return new SDL::SurfaceData(surface); + } +} + +void free_surface_data(void *surface_data) +{ + delete reinterpret_cast(surface_data); +} + +VideoSystem get_video_system(const std::string &video) +{ + if(0) {} +#ifdef HAVE_OPENGL + else if(video == "opengl") + { + return OPENGL; + } +#endif + else if(video == "sdl") + { + return PURE_SDL; + } + else + { +#ifdef HAVE_OPENGL + return OPENGL; +#else + return PURE_SDL; +#endif + } +} + +std::string get_video_string(VideoSystem video) +{ + switch(video) + { + case OPENGL: + return "opengl"; + case PURE_SDL: + return "sdl"; + default: + assert(0 && "invalid video system in config"); + return "sdl"; + } +} diff --git a/src/video/video_systems.hpp b/src/video/video_systems.hpp new file mode 100644 index 000000000..4f3a991c2 --- /dev/null +++ b/src/video/video_systems.hpp @@ -0,0 +1,47 @@ +// $Id: video_systems.hpp 5138 2007-08-15 01:02:22Z tuxdev $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +#ifndef __RENDER_SYTSTEMS_HPP__ +#define __RENDER_SYTSTEMS_HPP__ + +#include + +#include +#include + +class Renderer; +class Lightmap; +class Texture; +class Surface; + +enum VideoSystem { + OPENGL, + PURE_SDL, + NUM_SYSTEMS +}; + +Renderer *new_renderer(); +Lightmap *new_lightmap(); +Texture *new_texture(SDL_Surface *image); +void *new_surface_data(const Surface &surface); +void free_surface_data(void *surface_data); +VideoSystem get_video_system(const std::string &video); +std::string get_video_string(VideoSystem video); + +#endif