This is an implementation that creates a gradient Surface, in order to speed up the...
authorRicardo Cruz <rick2@aeiou.pt>
Thu, 10 Jun 2004 14:09:49 +0000 (14:09 +0000)
committerRicardo Cruz <rick2@aeiou.pt>
Thu, 10 Jun 2004 14:09:49 +0000 (14:09 +0000)
But it is working even slower in SDL, and doesn't work at all in OpenGL.
Just committed, in the hope that someone finds the problem.

SVN-Revision: 1462

src/background.cpp
src/screen/drawing_context.h
src/screen/screen.h
src/screen/texture.cpp
src/screen/texture.h

index ed51950..65d7be7 100644 (file)
@@ -95,13 +95,17 @@ Background::set_gradient(Color top, Color bottom)
   type = GRADIENT;
   gradient_top = top;
   gradient_bottom = bottom;
+
+  delete image;
+  image = new Surface(top, bottom, screen->w, screen->h);
 }
 
 void
 Background::draw(DrawingContext& context)
 {
   if(type == GRADIENT) {
-    context.draw_gradient(gradient_top, gradient_bottom, LAYER_BACKGROUND0);
+    context.draw_surface(image, Vector(0, 0), LAYER_BACKGROUND0);
+//    context.draw_gradient(gradient_top, gradient_bottom, LAYER_BACKGROUND0);
   } else if(type == IMAGE) {
     int sx = int(-context.get_translation().x * speed)
       % image->w - image->w;
index 0051301..d171c44 100644 (file)
@@ -43,24 +43,6 @@ enum {
   LAYER_GUI         = 500
 };
 
-class Color
-{
-public:
-  Color() 
-    : red(0), green(0), blue(0), alpha(0)
-  {}
-  
-  Color(Uint8 red_, Uint8 green_, Uint8 blue_, Uint8 alpha_ = 0)
-    : red(red_), green(green_), blue(blue_), alpha(alpha_)
-  {}
-
-  Color(const Color& o)
-    : red(o.red), green(o.green), blue(o.blue), alpha(o.alpha)
-  { }
-
-  Uint8 red, green, blue, alpha;
-};
-
 /**
  * This class provides functions for drawing things on screen. It also
  * maintains a stack of transforms that are applied to graphics.
index 4c7f3df..85744e8 100644 (file)
 #ifndef NOOPENGL
 #include <SDL_opengl.h>
 #endif
+
+class Color
+{
+public:
+  Color() 
+    : red(0), green(0), blue(0), alpha(0)
+  {}
+  
+  Color(Uint8 red_, Uint8 green_, Uint8 blue_, Uint8 alpha_ = 0)
+    : red(red_), green(green_), blue(blue_), alpha(alpha_)
+  {}
+
+  Color(const Color& o)
+    : red(o.red), green(o.green), blue(o.blue), alpha(o.alpha)
+  { }
+
+  Uint8 red, green, blue, alpha;
+};
+
 #include "texture.h"
 
 class Vector;
index fbb9a10..d841754 100644 (file)
@@ -58,6 +58,14 @@ SurfaceData::SurfaceData(const std::string& file_, int x_, int y_, int w_, int h
     x(x_), y(y_), w(w_), h(h_)
 {}
 
+SurfaceData::SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_)
+    : type(GRADIENT), surface(0), use_alpha(false), w(w_), h(h_)
+{
+top_gradient = top_gradient_;
+bottom_gradient = bottom_gradient_;
+}
+
+
 SurfaceData::~SurfaceData()
 {
   SDL_FreeSurface(surface);
@@ -87,6 +95,8 @@ SurfaceData::create_SurfaceSDL()
     return new SurfaceSDL(file, x, y, w, h, use_alpha);
   case SURFACE:
     return new SurfaceSDL(surface, use_alpha);
+  case GRADIENT:
+    return new SurfaceSDL(top_gradient, bottom_gradient, w, h);
   }
   assert(0);
 }
@@ -103,6 +113,8 @@ SurfaceData::create_SurfaceOpenGL()
     return new SurfaceOpenGL(file, x, y, w, h, use_alpha);
   case SURFACE:
     return new SurfaceOpenGL(surface, use_alpha);
+  case GRADIENT:
+    return new SurfaceOpenGL(top_gradient, bottom_gradient, w, h);
   }
 #endif
   assert(0);
@@ -158,6 +170,18 @@ Surface::Surface(const std::string& file, int x, int y, int w, int h, int use_al
   surfaces.push_back(this);
 }
 
+Surface::Surface(Color top_background, Color bottom_background, int w, int h)
+    : data(top_background, bottom_background, w, h), w(0), h(0)
+{
+  impl = data.create();
+  if (impl)
+  {
+    w = impl->w;
+    h = impl->h;
+  }
+  surfaces.push_back(this);
+}
+
 void
 Surface::reload()
 {
@@ -337,6 +361,53 @@ sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha)
   return sdl_surface;
 }
 
+SDL_Surface*
+sdl_surface_from_gradient(Color top, Color bottom, int w, int h)
+{
+  SDL_Surface* sdl_surface;
+
+  Uint32 rmask, gmask, bmask, amask;
+
+  /* SDL interprets each pixel as a 32-bit number, so our masks must depend
+       on the endianness (byte order) of the machine */
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+    rmask = 0xff000000;
+    gmask = 0x00ff0000;
+    bmask = 0x0000ff00;
+    amask = 0x000000ff;
+#else
+    rmask = 0x000000ff;
+    gmask = 0x0000ff00;
+    bmask = 0x00ff0000;
+    amask = 0xff000000;
+#endif
+
+    sdl_surface = SDL_CreateRGBSurface(screen->flags, w, h,
+                      screen->format->BitsPerPixel, rmask, gmask, bmask, amask);
+
+    if(sdl_surface == NULL)
+        st_abort("Cannot create surface for the gradient", "SURFACE");
+
+    float redstep = (float(bottom.red)-float(top.red)) / float(h);
+    float greenstep = (float(bottom.green)-float(top.green)) / float(h);
+    float bluestep = (float(bottom.blue) - float(top.blue)) / float(h);
+
+    SDL_Rect rect;
+    rect.x = 0;
+    rect.w = w;
+    rect.h = 1;
+    for(float y = 0; y < h; y++)
+      {
+      rect.y = (int)y;
+      SDL_FillRect(sdl_surface, &rect, SDL_MapRGB(sdl_surface->format,
+          int(float(top.red) + redstep * y),
+          int(float(top.green) + greenstep * y),
+          int(float(top.blue) + bluestep * y)));
+      }
+
+  return sdl_surface;
+}
+
 //---------------------------------------------------------------------------
 
 SurfaceImpl::SurfaceImpl()
@@ -394,6 +465,15 @@ SurfaceOpenGL::SurfaceOpenGL(const std::string& file, int x, int y, int w, int h
   h = sdl_surface->h;
 }
 
+SurfaceOpenGL::SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h)
+{
+  sdl_surface = sdl_surface_from_gradient(top_gradient, bottom_gradient, w, h);
+  create_gl(sdl_surface, &gl_texture);
+
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
 SurfaceOpenGL::~SurfaceOpenGL()
 {
   glDeleteTextures(1, &gl_texture);
@@ -620,6 +700,13 @@ SurfaceSDL::SurfaceSDL(const std::string& file, int x, int y, int w, int h,  int
   h = sdl_surface->h;
 }
 
+SurfaceSDL::SurfaceSDL(Color top_gradient, Color bottom_gradient, int w, int h)
+{
+  sdl_surface = sdl_surface_from_gradient(top_gradient, bottom_gradient, w, h);
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
 int
 SurfaceSDL::draw(float x, float y, Uint8 alpha, Uint32 effect)
 {
index 469b309..6fe26e3 100644 (file)
@@ -34,6 +34,7 @@
 #include "vector.h"
 
 SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha);
+SDL_Surface* sdl_surface_from_nothing();
 
 class SurfaceImpl;
 class SurfaceSDL;
@@ -42,7 +43,7 @@ class DrawingContext;
 
 /// bitset for drawing effects
 enum {
-      /** Draw the Surface upside down */
+      /** Don't apply anything */
       NONE_EFFECT       = 0x0000,
       /** Draw the Surface upside down */
       VERTICAL_FLIP     = 0x0001,
@@ -54,7 +55,7 @@ enum {
 class SurfaceData 
 {
 public:
-  enum ConstructorType { LOAD, LOAD_PART, SURFACE };
+  enum ConstructorType { LOAD, LOAD_PART, SURFACE, GRADIENT };
   ConstructorType type;
   SDL_Surface* surface;
   std::string file;
@@ -63,10 +64,13 @@ public:
   int y;
   int w;
   int h;
+  Color top_gradient;
+  Color bottom_gradient;
 
   SurfaceData(SDL_Surface* surf, int use_alpha_);
   SurfaceData(const std::string& file_, int use_alpha_);
   SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, int use_alpha_);
+  SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_);
   ~SurfaceData();
 
   SurfaceSDL* create_SurfaceSDL();
@@ -93,6 +97,7 @@ public:
   Surface(SDL_Surface* surf, int use_alpha);  
   Surface(const std::string& file, int use_alpha);  
   Surface(const std::string& file, int x, int y, int w, int h, int use_alpha);
+  Surface(Color top_gradient, Color bottom_gradient, int w, int h);
   ~Surface();
   
   /** Reload the surface, which is necesarry in case of a mode swich */
@@ -133,6 +138,7 @@ public:
   SurfaceSDL(SDL_Surface* surf, int use_alpha);
   SurfaceSDL(const std::string& file, int use_alpha);  
   SurfaceSDL(const std::string& file, int x, int y, int w, int h, int use_alpha);
+  SurfaceSDL(Color top_gradient, Color bottom_gradient, int w, int h);
   virtual ~SurfaceSDL();
 
   int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
@@ -152,6 +158,8 @@ public:
   SurfaceOpenGL(SDL_Surface* surf, int use_alpha);
   SurfaceOpenGL(const std::string& file, int use_alpha);  
   SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, int use_alpha);
+  SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h);
+
   virtual ~SurfaceOpenGL();
 
   int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);