mail[Wesnoth-commits] r33378 - in /trunk/src: sdl_utils.cpp sdl_utils.hpp titlescreen.cpp


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by alinktomine on March 07, 2009 - 03:43:
Author: alink
Date: Sat Mar  7 03:43:01 2009
New Revision: 33378

URL: http://svn.gna.org/viewcvs/wesnoth?rev=33378&view=rev
Log:
An optimized version of scale_surface for opaque surfaces 
(no difference, just skip alpha but ~2x faster)
Currently only used for the titlescreen. But may also be used for story 
images.

Modified:
    trunk/src/sdl_utils.cpp
    trunk/src/sdl_utils.hpp
    trunk/src/titlescreen.cpp

Modified: trunk/src/sdl_utils.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/sdl_utils.cpp?rev=33378&r1=33377&r2=33378&view=diff
==============================================================================
--- trunk/src/sdl_utils.cpp (original)
+++ trunk/src/sdl_utils.cpp Sat Mar  7 03:43:01 2009
@@ -431,6 +431,99 @@
        return optimize ? create_optimized_surface(dst) : dst;
 }
 
+
+// This is a copy-paste of the previous function scale_surface
+// We only removed the alpha channel and big comments
+// and change how we optimize the resulting surface
+surface scale_opaque_surface(surface const &surf, int w, int h, bool 
optimize_format)
+{
+       if(surf == NULL)
+               return NULL;
+
+       if(w == surf->w && h == surf->h) {
+               return surf;
+       }
+       assert(w >= 0);
+       assert(h >= 0);
+
+       surface dst(create_neutral_surface(w,h));
+
+       if (w == 0 || h ==0) {
+               std::cerr << "Create an empty image\n";
+               return create_optimized_surface(dst);
+       }
+
+       surface src(make_neutral_surface(surf));
+       // Now both surfaces are always in the "neutral" pixel format
+
+       if(src == NULL || dst == NULL) {
+               std::cerr << "Could not create surface to scale onto\n";
+               return NULL;
+       }
+
+       const fixed_t xratio = fxpdiv(surf->w,w);
+       const fixed_t yratio = fxpdiv(surf->h,h);
+
+       {
+               surface_lock src_lock(src);
+               surface_lock dst_lock(dst);
+
+               Uint32* const src_pixels = 
reinterpret_cast<Uint32*>(src_lock.pixels());
+               Uint32* const dst_pixels = 
reinterpret_cast<Uint32*>(dst_lock.pixels());
+
+               fixed_t ysrc = ftofxp(0.0);
+               for(int ydst = 0; ydst != h; ++ydst, ysrc += yratio) {
+                       fixed_t xsrc = ftofxp(0.0);
+                       for(int xdst = 0; xdst != w; ++xdst, xsrc += xratio) {
+                               const int xsrcint = fxptoi(xsrc);
+                               const int ysrcint = fxptoi(ysrc);
+
+                               Uint32* const src_word = src_pixels + 
ysrcint*src->w + xsrcint;
+                               Uint32* const dst_word = dst_pixels +    
ydst*dst->w + xdst;
+                               const int dx = (xsrcint + 1 < src->w) ? 1 : 0;
+                               const int dy = (ysrcint + 1 < src->h) ? 
src->w : 0;
+
+                               Uint8 r,g,b;
+                               Uint32 rr,gg,bb;
+                               Uint32 pix[4], bilin[4];
+
+                               const fixed_t e = 0x000000FF & xsrc;
+                               const fixed_t s = 0x000000FF & ysrc;
+                               const fixed_t n = 0xFF - s;
+                               const fixed_t w = 0xFF - e;
+
+                               pix[0] = *src_word;              // northwest
+                               pix[1] = *(src_word + dx);       // northeast
+                               pix[2] = *(src_word + dy);       // southwest
+                               pix[3] = *(src_word + dx + dy);  // southeast
+
+                               bilin[0] = n*w;
+                               bilin[1] = n*e;
+                               bilin[2] = s*w;
+                               bilin[3] = s*e;
+
+                               int loc;
+                               rr = gg = bb = 0;
+                               for (loc=0; loc<4; loc++) {
+                                 r = pix[loc] >> 16;
+                                 g = pix[loc] >> 8;
+                                 b = pix[loc] >> 0;
+                                 rr += r * bilin[loc];
+                                 gg += g * bilin[loc];
+                                 bb += b * bilin[loc];
+                               }
+                               r = rr >> 16;
+                               g = gg >> 16;
+                               b = bb >> 16;
+                               *dst_word = (255 << 24) + (r << 16) + (g << 
8) + b;
+                       }
+               }
+       }
+
+       return optimize_format ? display_format_alpha(dst) : dst;
+}
+
+
 surface scale_surface_blended(surface const &surf, int w, int h, bool 
optimize)
 {
        if(surf== NULL)

Modified: trunk/src/sdl_utils.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/sdl_utils.hpp?rev=33378&r1=33377&r2=33378&view=diff
==============================================================================
--- trunk/src/sdl_utils.hpp (original)
+++ trunk/src/sdl_utils.hpp Sat Mar  7 03:43:01 2009
@@ -176,7 +176,31 @@
 surface stretch_surface_vertical(
        const surface& surf, const unsigned h, const bool optimize = true);
 
+/** Scale a surface
+ *  @param surf              The source surface.
+ *  @param w                 The width of the resulting surface.
+ *  @param h                 The height of the resulting surface.
+ *  @param optimize          Should the return surface be RLE optimized.
+ *  @return                  A surface containing the scaled version of the 
source.
+ *  @retval 0                Returned upon error.
+ *  @retval surf             Returned if w == surf->w and h == surf->h
+ *                           note this ignores the optimize flag.
+ */
 surface scale_surface(surface const &surf, int w, int h, bool optimize=true);
+
+/** Scale an opaque surface
+ *  @param surf              The source surface.
+ *  @param w                 The width of the resulting surface.
+ *  @param h                 The height of the resulting surface.
+ *  @param optimize_format   Optimize by converting to result to display 
format.
+ *  @return                  A surface containing the scaled version of the 
source.
+ *                           No RLE or Alpha bits are set.
+ *  @retval 0                Returned upon error.
+ *  @retval surf             Returned if w == surf->w and h == surf->h
+ *                           note this ignores the optimize_format flag.
+ */
+surface scale_opaque_surface(surface const &surf, int w, int h, bool 
optimize_format=false);
+
 surface scale_surface_blended(surface const &surf, int w, int h, bool 
optimize=true);
 surface adjust_surface_colour(surface const &surf, int r, int g, int b, bool 
optimize=true);
 surface greyscale_image(surface const &surf, bool optimize=true);
@@ -189,12 +213,12 @@
 surface brighten_image(surface const &surf, fixed_t amount, bool 
optimize=true);
 
 /** Get a portion of the screen.
- *  Send NULL 
+ *  Send NULL if the portion is outside of the screen.
  *  @param surf              The source surface.
  *  @param rect              The portion of the source surface to copy.
- *  @param optimize          Optimize by converting to result to display 
format.
- *                           Note that it's only useful if the source is not 
the
- *                           screen and you plan to blit the result on 
screen.
+ *  @param optimize_format   Optimize by converting to result to display 
format.
+ *                           Only useful if the source is not the screen and 
you
+ *                           plan to blit the result on screen several times.
  *  @return                  A surface containing the portion of the source.
  *                           No RLE or Alpha bits are set.
  *  @retval 0                if error or the portion is outside of the 
surface.

Modified: trunk/src/titlescreen.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/titlescreen.cpp?rev=33378&r1=33377&r2=33378&view=diff
==============================================================================
--- trunk/src/titlescreen.cpp (original)
+++ trunk/src/titlescreen.cpp Sat Mar  7 03:43:01 2009
@@ -309,7 +309,7 @@
                if(game_title_list.empty()) {
                        ERR_CONFIG << "No title image defined\n";
                } else {
-                       surface const title_surface(scale_surface(
+                       surface const title_surface(scale_opaque_surface(
                                
image::get_image(game_title_list[rand()%game_title_list.size()]),
                                screen.w(), screen.h()));
 




Related Messages


Powered by MHonArc, Updated Sat Mar 07 08:00:31 2009