From 1028ce017d6809007e39a8f7c034a0d62bfe3052 Mon Sep 17 00:00:00 2001 From: Ricardo Cruz Date: Fri, 27 Aug 2004 20:34:56 +0000 Subject: [PATCH] Apply filter mask. TODO: make it working over the other rather than a colorization. SVN-Revision: 1850 --- lib/video/screen.cpp | 31 +++++++++++++++++++++++++++++++ lib/video/screen.h | 13 ++++++++++++- lib/video/surface.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/video/surface.h | 15 ++++++++++++++- 4 files changed, 108 insertions(+), 2 deletions(-) diff --git a/lib/video/screen.cpp b/lib/video/screen.cpp index 41245eebe..1714943da 100644 --- a/lib/video/screen.cpp +++ b/lib/video/screen.cpp @@ -42,6 +42,37 @@ using namespace SuperTux; /* 'Stolen' from the SDL documentation. + * Return the pixel value at (x, y) + * NOTE: The surface must be locked before calling this! + */ +Uint32 SuperTux::getpixel(SDL_Surface *surface, int x, int y) +{ + int bpp = surface->format->BytesPerPixel; + /* Here p is the address to the pixel we want to retrieve */ + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; + + switch(bpp) { + case 1: + return *p; + + case 2: + return *(Uint16 *)p; + + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + return p[0] << 16 | p[1] << 8 | p[2]; + else + return p[0] | p[1] << 8 | p[2] << 16; + + case 4: + return *(Uint32 *)p; + + default: + return 0; /* shouldn't happen, but avoids warnings */ + } +} + +/* 'Stolen' from the SDL documentation. * Set the pixel at (x, y) to the given value * NOTE: The surface must be locked before calling this! */ diff --git a/lib/video/screen.h b/lib/video/screen.h index 93c0bfae7..c3c1d82ee 100644 --- a/lib/video/screen.h +++ b/lib/video/screen.h @@ -49,6 +49,11 @@ namespace SuperTux { if(color.size() >= 3) { red = color[0]; green = color[1]; blue = color[2]; } if(color.size() == 4) alpha = color[3]; } + Color(std::vector color) + : red(0), green(0), blue(0), alpha(255) + { if(color.size() >= 3) { red = color[0]; green = color[1]; blue = color[2]; } + if(color.size() == 4) alpha = color[3]; } + Color(const Color& o) : red(o.red), green(o.green), blue(o.blue), alpha(o.alpha) { } @@ -61,13 +66,19 @@ namespace SuperTux return false; } + Uint32 map_rgb(SDL_Surface* surface) + { return SDL_MapRGB(surface->format, red, green, blue); } + Uint32 map_rgba(SDL_Surface* surface) + { return SDL_MapRGBA(surface->format, red, green, blue, alpha); } + Uint8 red, green, blue, alpha; }; class Vector; - void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel); + Uint32 getpixel(SDL_Surface* surface, int x, int y); + void putpixel(SDL_Surface* surface, int x, int y, Uint32 pixel); void drawpixel(int x, int y, Uint32 pixel); void fillrect(float x, float y, float w, float h, int r, int g, int b, int a = 255); void draw_line(float x1, float y1, float x2, float y2, int r, int g, int b, int a = 255); diff --git a/lib/video/surface.cpp b/lib/video/surface.cpp index 1adff4f94..73dc131b4 100644 --- a/lib/video/surface.cpp +++ b/lib/video/surface.cpp @@ -26,6 +26,7 @@ #include "SDL_image.h" #include "../video/surface.h" +#include "../video/screen.h" #include "../app/globals.h" #include "../app/setup.h" @@ -196,6 +197,11 @@ Surface::reload() } } +void Surface::apply_mask(Color color) +{ +impl->apply_mask(color); +} + Surface::~Surface() { #ifdef DEBUG @@ -246,6 +252,32 @@ Surface::resize(int w_, int h_) } } +void +apply_filter_to_surface(SDL_Surface* surface, int filter, Color color) +{ +if(filter == MASK_FILTER) + { + Uint8 r,g,b,a; + SDL_Rect rect; + rect.w = rect.h = 1; + SDL_LockSurface(surface); + for(int x = 0; x < surface->w; x++) + for(int y = 0; y < surface->h; y++) + { +// SDL_LockSurface(surface); + SDL_GetRGBA(getpixel(surface,x,y), surface->format, &r,&g,&b,&a); +// SDL_UnlockSurface(surface); + if(a != 0) + { + putpixel(surface, x,y, color.map_rgba(surface)); +// rect.x = x; rect.y = y; +// SDL_FillRect(surface, &rect, color.map_rgba(surface)); + } + } + SDL_UnlockSurface(surface); + } +} + SDL_Surface* sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h, bool use_alpha) { @@ -804,6 +836,16 @@ SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uin return 0; } +void +SurfaceOpenGL::apply_mask(Color color) +{ + ::apply_filter_to_surface(sdl_surface, MASK_FILTER, color); + create_gl(sdl_surface,&gl_texture); + + w = sdl_surface->w; + h = sdl_surface->h; +} + #endif SurfaceSDL::SurfaceSDL(SDL_Surface* surf, bool use_alpha) @@ -1006,6 +1048,15 @@ SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uint32 return ret; } +void +SurfaceSDL::apply_mask(Color color) +{ + ::apply_filter_to_surface(sdl_surface, MASK_FILTER, color); + + w = sdl_surface->w; + h = sdl_surface->h; +} + SurfaceSDL::~SurfaceSDL() {} diff --git a/lib/video/surface.h b/lib/video/surface.h index ad327e9b1..23d0c2e3f 100644 --- a/lib/video/surface.h +++ b/lib/video/surface.h @@ -35,7 +35,8 @@ namespace SuperTux { - + + void apply_filter_to_surface(SDL_Surface *surface, int filter, int value); SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, bool use_alpha); SDL_Surface* sdl_surface_from_nothing(); @@ -56,6 +57,11 @@ namespace SuperTux SEMI_TRANSPARENT = 0x0004 }; + /// types of filters + enum { + MASK_FILTER + }; + /** This class holds all the data necessary to construct a surface */ class SurfaceData { @@ -111,6 +117,8 @@ namespace SuperTux void reload(); void resize(int widht, int height); + + void apply_mask(Color color); }; /** Surface implementation, all implementation have to inherit from @@ -137,6 +145,8 @@ namespace SuperTux int resize(int w_, int h_); SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function + + virtual void apply_mask(Color color) = 0; }; class SurfaceSDL : public SurfaceImpl @@ -151,6 +161,8 @@ namespace SuperTux int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT); int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect = NONE_EFFECT); int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT); + + void apply_mask(Color color); }; #ifndef NOOPENGL @@ -171,6 +183,7 @@ namespace SuperTux int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect = NONE_EFFECT); int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT); + void apply_mask(Color color); private: void create_gl(SDL_Surface * surf, GLuint * tex); -- 2.11.0