Apply filter mask.
authorRicardo Cruz <rick2@aeiou.pt>
Fri, 27 Aug 2004 20:34:56 +0000 (20:34 +0000)
committerRicardo Cruz <rick2@aeiou.pt>
Fri, 27 Aug 2004 20:34:56 +0000 (20:34 +0000)
TODO: make it working over the other rather than a colorization.

SVN-Revision: 1850

lib/video/screen.cpp
lib/video/screen.h
lib/video/surface.cpp
lib/video/surface.h

index 41245ee..1714943 100644 (file)
 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!
  */
index 93c0bfa..c3c1d82 100644 (file)
@@ -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 <int> 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);
index 1adff4f..73dc131 100644 (file)
@@ -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()
 {}
 
index ad327e9..23d0c2e 100644 (file)
@@ -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);