SDL::Lightmap Class Reference

#include <sdl_lightmap.hpp>

Inherits Lightmap.

List of all members.

Public Member Functions

 Lightmap ()
 ~Lightmap ()
void start_draw (const Color &ambient_color)
void end_draw ()
void do_draw ()
void draw_surface (const DrawingRequest &request)
void draw_surface_part (const DrawingRequest &request)
void draw_text (const DrawingRequest &request)
void draw_gradient (const DrawingRequest &request)
void draw_filled_rect (const DrawingRequest &request)
void get_light (const DrawingRequest &request) const

Private Member Functions

void light_blit (SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)

Private Attributes

SDL_Surface * screen
Uint8 * red_channel
Uint8 * blue_channel
Uint8 * green_channel
int width
int height
int numerator
int denominator
int LIGHTMAP_DIV


Detailed Description

Definition at line 31 of file sdl_lightmap.hpp.


Constructor & Destructor Documentation

Lightmap::Lightmap (  ) 

Definition at line 47 of file sdl_lightmap.cpp.

References screen.

00048   {
00049     screen = SDL_GetVideoSurface();
00050 
00051     //float xfactor = 1.0f; // FIXME: (float) config->screenwidth / SCREEN_WIDTH;
00052     //float yfactor = 1.0f; // FIXME: (float) config->screenheight / SCREEN_HEIGHT;
00053 
00054     numerator = 1;
00055     denominator = 1;
00056 
00057     /* FIXME:
00058     if(xfactor < yfactor)
00059     {
00060       numerator = config->screenwidth;
00061       denominator = SCREEN_WIDTH;
00062     }
00063     else
00064     {
00065       numerator = config->screenheight;
00066       denominator = SCREEN_HEIGHT;
00067     }
00068     */
00069 
00070     LIGHTMAP_DIV = 8 * numerator / denominator;
00071 
00072     width = screen->w / LIGHTMAP_DIV;
00073     height = screen->h / LIGHTMAP_DIV;
00074 
00075     red_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
00076     green_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
00077     blue_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
00078   }

Lightmap::~Lightmap (  )  [virtual]

Reimplemented from Lightmap.

Definition at line 80 of file sdl_lightmap.cpp.

00081   {
00082     free(red_channel);
00083     free(green_channel);
00084     free(blue_channel);
00085   }


Member Function Documentation

void Lightmap::start_draw ( const Color ambient_color  )  [virtual]

Implements Lightmap.

Definition at line 88 of file sdl_lightmap.cpp.

References Color::blue, Color::green, and Color::red.

00089   {
00090     memset(red_channel, (Uint8) (ambient_color.red * 255), width * height * sizeof(Uint8));
00091     memset(green_channel, (Uint8) (ambient_color.green * 255), width * height * sizeof(Uint8));
00092     memset(blue_channel, (Uint8) (ambient_color.blue * 255), width * height * sizeof(Uint8));
00093   }

void Lightmap::end_draw (  )  [virtual]

Implements Lightmap.

Definition at line 96 of file sdl_lightmap.cpp.

00097   {
00098   }

void Lightmap::do_draw (  )  [virtual]

Implements Lightmap.

Definition at line 115 of file sdl_lightmap.cpp.

References merge(), and screen.

00116   {
00117     // FIXME: This is really slow
00118     if(LIGHTMAP_DIV == 1)
00119     {
00120       int bpp = screen->format->BytesPerPixel;
00121       if(SDL_MUSTLOCK(screen))
00122       {
00123         SDL_LockSurface(screen);
00124       }
00125       Uint8 *pixel = (Uint8 *) screen->pixels;
00126       int loc = 0;
00127       for(int y = 0;y < height;y++) {
00128         for(int x = 0;x < width;x++, pixel += bpp, loc++) {
00129           if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
00130           {
00131             continue;
00132           }
00133           Uint32 mapped = 0;
00134           switch(bpp) {
00135             case 1:
00136               mapped = *pixel;
00137               break;
00138             case 2:
00139               mapped = *(Uint16 *)pixel;
00140               break;
00141             case 3:
00142 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00143               mapped |= pixel[0] << 16;
00144               mapped |= pixel[1] << 8;
00145               mapped |= pixel[2] << 0;
00146 #else
00147               mapped |= pixel[0] << 0;
00148               mapped |= pixel[1] << 8;
00149               mapped |= pixel[2] << 16;
00150 #endif
00151               break;
00152             case 4:
00153               mapped = *(Uint32 *)pixel;
00154               break;
00155           }
00156           Uint8 red, green, blue, alpha;
00157           SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
00158           red = (red * red_channel[loc]) >> 8;
00159           green = (green * green_channel[loc]) >> 8;
00160           blue = (blue * blue_channel[loc]) >> 8;
00161           mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
00162           switch(bpp) {
00163             case 1:
00164               *pixel = mapped;
00165               break;
00166             case 2:
00167               *(Uint16 *)pixel = mapped;
00168               break;
00169             case 3:
00170 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00171               pixel[0] = (mapped >> 16) & 0xff;
00172               pixel[1] = (mapped >> 8) & 0xff;
00173               pixel[2] = (mapped >> 0) & 0xff;
00174 #else
00175               pixel[0] = (mapped >> 0) & 0xff;
00176               pixel[1] = (mapped >> 8) & 0xff;
00177               pixel[2] = (mapped >> 16) & 0xff;
00178 #endif
00179               break;
00180             case 4:
00181               *(Uint32 *)pixel = mapped;
00182               break;
00183           }
00184         }
00185         pixel += screen->pitch - width * bpp;
00186       }
00187       if(SDL_MUSTLOCK(screen))
00188       {
00189         SDL_UnlockSurface(screen);
00190       }
00191     }
00192     else
00193     {
00194       int bpp = screen->format->BytesPerPixel;
00195       if(SDL_MUSTLOCK(screen))
00196       {
00197         SDL_LockSurface(screen);
00198       }
00199       Uint8 *div_pixel = (Uint8 *) screen->pixels;
00200       int loc = 0;
00201       for(int y = 0;y < height;y++) {
00202         for(int x = 0;x < width;x++, div_pixel += bpp * LIGHTMAP_DIV, loc++) {
00203           if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
00204           {
00205             continue;
00206           }
00207           Uint8 *pixel = div_pixel;
00208           for(int div_y = 0;div_y < LIGHTMAP_DIV;div_y++) {
00209             for(int div_x = 0;div_x < LIGHTMAP_DIV;pixel += bpp, div_x++) {
00210               Uint32 mapped = 0;
00211               switch(bpp) {
00212                 case 1:
00213                   mapped = *pixel;
00214                   break;
00215                 case 2:
00216                   mapped = *(Uint16 *)pixel;
00217                   break;
00218                 case 3:
00219 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00220                   mapped |= pixel[0] << 16;
00221                   mapped |= pixel[1] << 8;
00222                   mapped |= pixel[2] << 0;
00223 #else
00224                   mapped |= pixel[0] << 0;
00225                   mapped |= pixel[1] << 8;
00226                   mapped |= pixel[2] << 16;
00227 #endif
00228                   break;
00229                 case 4:
00230                   mapped = *(Uint32 *)pixel;
00231                   break;
00232               }
00233               Uint8 red, green, blue, alpha;
00234               SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
00235 
00236 #ifdef BILINEAR
00237               int xinc = (x + 1 != width ? 1 : 0);
00238               int yinc = (y + 1 != height ? width : 0);
00239               Uint8 color00[3], color01[3], color10[3], color11[3];
00240               {
00241                 color00[0] = red_channel[loc];
00242                 color00[1] = green_channel[loc];
00243                 color00[2] = blue_channel[loc];
00244               }
00245               {
00246                 color01[0] = red_channel[loc + xinc];
00247                 color01[1] = green_channel[loc + xinc];
00248                 color01[2] = blue_channel[loc + xinc];
00249               }
00250               {
00251                 color10[0] = red_channel[loc + yinc];
00252                 color10[1] = green_channel[loc + yinc];
00253                 color10[2] = blue_channel[loc + yinc];
00254               }
00255               {
00256                 color11[0] = red_channel[loc + yinc + xinc];
00257                 color11[1] = green_channel[loc + yinc + xinc];
00258                 color11[2] = blue_channel[loc + yinc + xinc];
00259               }
00260               Uint8 color0[3], color1[3], color[3];
00261               merge(color0, color00, color01, div_x, LIGHTMAP_DIV);
00262               merge(color1, color10, color11, div_x, LIGHTMAP_DIV);
00263               merge(color, color0, color1, div_y, LIGHTMAP_DIV);
00264               red = (red * color[0]) >> 8;
00265               green = (green * color[1]) >> 8;
00266               blue = (blue * color[2]) >> 8;
00267 #else
00268               red = (red * red_channel[loc]) >> 8;
00269               green = (green * green_channel[loc]) >> 8;
00270               blue = (blue * blue_channel[loc]) >> 8;
00271 #endif
00272 
00273               mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
00274               switch(bpp) {
00275                 case 1:
00276                   *pixel = mapped;
00277                   break;
00278                 case 2:
00279                   *(Uint16 *)pixel = mapped;
00280                   break;
00281                 case 3:
00282 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00283                   pixel[0] = (mapped >> 16) & 0xff;
00284                   pixel[1] = (mapped >> 8) & 0xff;
00285                   pixel[2] = (mapped >> 0) & 0xff;
00286 #else
00287                   pixel[0] = (mapped >> 0) & 0xff;
00288                   pixel[1] = (mapped >> 8) & 0xff;
00289                   pixel[2] = (mapped >> 16) & 0xff;
00290 #endif
00291                   break;
00292                 case 4:
00293                   *(Uint32 *)pixel = mapped;
00294                   break;
00295               }
00296             }
00297             pixel += screen->pitch - LIGHTMAP_DIV * bpp;
00298           }
00299         }
00300         div_pixel += (screen->pitch - width * bpp) * LIGHTMAP_DIV;
00301       }
00302       if(SDL_MUSTLOCK(screen))
00303       {
00304         SDL_UnlockSurface(screen);
00305       }
00306     }
00307   }

void Lightmap::draw_surface ( const DrawingRequest request  )  [virtual]

Implements Lightmap.

Definition at line 458 of file sdl_lightmap.cpp.

References DrawingRequest::alpha, Color::alpha, Color::blue, DrawingRequest::color, DrawingRequest::drawing_effect, Surface::get_flipx(), SDL::SurfaceData::get_src_rect(), Surface::get_surface_data(), Surface::get_texture(), Color::green, HORIZONTAL_FLIP, DrawingRequest::pos, Color::red, DrawingRequest::request_data, Vector::x, and Vector::y.

00459   {
00460     if((request.color.red == 0.0 && request.color.green == 0.0 && request.color.blue == 0.0) || request.color.alpha == 0.0 || request.alpha == 0.0)
00461     {
00462       return;
00463     }
00464     //FIXME: support parameters request.alpha, request.angle, request.blend
00465  
00466     const Surface* surface = (const Surface*) request.request_data;
00467     SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
00468     SDL::SurfaceData *surface_data = reinterpret_cast<SDL::SurfaceData *>(surface->get_surface_data());
00469 
00470     DrawingEffect effect = request.drawing_effect;
00471     if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
00472 
00473     SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
00474 
00475     // get and check SDL_Surface
00476     if (transform == 0) {
00477       std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
00478       return;
00479     }
00480 
00481     SDL_Rect *src_rect = surface_data->get_src_rect(effect);
00482     int dstx = (int) request.pos.x * numerator / denominator;
00483     int dsty = (int) request.pos.y * numerator / denominator;
00484     light_blit(transform, src_rect, dstx, dsty);
00485   }

void Lightmap::draw_surface_part ( const DrawingRequest request  )  [virtual]

Implements Lightmap.

Definition at line 488 of file sdl_lightmap.cpp.

References DrawingRequest::drawing_effect, HORIZONTAL_FLIP, DrawingRequest::pos, DrawingRequest::request_data, SurfacePartRequest::size, SurfacePartRequest::source, SurfacePartRequest::surface, VERTICAL_FLIP, Vector::x, and Vector::y.

00489   {
00490     const SurfacePartRequest* surfacepartrequest
00491       = (SurfacePartRequest*) request.request_data;
00492 
00493     const Surface* surface = surfacepartrequest->surface;
00494     SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
00495 
00496     DrawingEffect effect = request.drawing_effect;
00497     if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
00498 
00499     SDL_Surface *transform = sdltexture->get_transform(Color(1.0, 1.0, 1.0), effect);
00500 
00501     // get and check SDL_Surface
00502     if (transform == 0) {
00503       std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
00504       return;
00505     }
00506 
00507     int ox, oy;
00508     if (effect == HORIZONTAL_FLIP)
00509     {
00510       ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x;
00511     }
00512     else
00513     {
00514       ox = surface->get_x();
00515     }
00516     if (effect == VERTICAL_FLIP)
00517     {
00518       oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y;
00519     }
00520     else
00521     {
00522       oy = surface->get_y();
00523     }
00524 
00525     SDL_Rect src_rect;
00526     src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
00527     src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
00528     src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
00529     src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
00530     int dstx = (int) request.pos.x * numerator / denominator;
00531     int dsty = (int) request.pos.y * numerator / denominator;
00532     light_blit(transform, &src_rect, dstx, dsty);
00533   }

void SDL::Lightmap::draw_text ( const DrawingRequest request  ) 

void Lightmap::draw_gradient ( const DrawingRequest request  )  [virtual]

Implements Lightmap.

Definition at line 536 of file sdl_lightmap.cpp.

References GradientRequest::bottom, DrawingRequest::request_data, and GradientRequest::top.

00537   {
00538     const GradientRequest* gradientrequest 
00539       = (GradientRequest*) request.request_data;
00540     const Color& top = gradientrequest->top;
00541     const Color& bottom = gradientrequest->bottom;
00542 
00543     int loc = 0;
00544     for(int y = 0;y < height;++y)
00545     {
00546       Uint8 red = (Uint8)((((float)(top.red-bottom.red)/(0-height)) * y + top.red) * 255);
00547       Uint8 green = (Uint8)((((float)(top.green-bottom.green)/(0-height)) * y + top.green) * 255);
00548       Uint8 blue = (Uint8)((((float)(top.blue-bottom.blue)/(0-height)) * y + top.blue) * 255);
00549       Uint8 alpha = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-height)) * y + top.alpha) * 255);
00550       for(int x = 0;x < width;x++, loc++) {
00551         if(red != 0)
00552         {
00553           int redsum = red_channel[loc] + (red * alpha >> 8);
00554           red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
00555         }
00556         if(green != 0)
00557         {
00558           int greensum = green_channel[loc] + (green * alpha >> 8);
00559           green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
00560         }
00561         if(blue != 0)
00562         {
00563           int bluesum = blue_channel[loc] + (blue * alpha >> 8);
00564           blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
00565         }
00566       }
00567     }
00568   }

void Lightmap::draw_filled_rect ( const DrawingRequest request  )  [virtual]

Implements Lightmap.

Definition at line 571 of file sdl_lightmap.cpp.

References Color::alpha, Color::blue, FillRectRequest::color, Color::green, DrawingRequest::pos, Color::red, DrawingRequest::request_data, SCREEN_HEIGHT, SCREEN_WIDTH, FillRectRequest::size, Vector::x, and Vector::y.

00572   {
00573     const FillRectRequest* fillrectrequest
00574       = (FillRectRequest*) request.request_data;
00575 
00576     int rect_x = (int) (request.pos.x * width / SCREEN_WIDTH);
00577     int rect_y = (int) (request.pos.y * height / SCREEN_HEIGHT);
00578     int rect_w = (int) (fillrectrequest->size.x * width / SCREEN_WIDTH);
00579     int rect_h = (int) (fillrectrequest->size.y * height / SCREEN_HEIGHT);
00580     Uint8 red = (Uint8) (fillrectrequest->color.red * fillrectrequest->color.alpha * 255);
00581     Uint8 green = (Uint8) (fillrectrequest->color.green * fillrectrequest->color.alpha * 255);
00582     Uint8 blue = (Uint8) (fillrectrequest->color.blue * fillrectrequest->color.alpha * 255);
00583     if(red == 0 && green == 0 && blue == 0)
00584     {
00585       return;
00586     }
00587     for(int y = rect_y;y < rect_y + rect_h;y++) {
00588       for(int x = rect_x;x < rect_x + rect_w;x++) {
00589         int loc = y * width + x;
00590         if(red != 0)
00591         {
00592           int redsum = red_channel[loc] + red;
00593           red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
00594         }
00595         if(green != 0)
00596         {
00597           int greensum = green_channel[loc] + green;
00598           green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
00599         }
00600         if(blue != 0)
00601         {
00602           int bluesum = blue_channel[loc] + blue;
00603           blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
00604         }
00605       }
00606     }
00607   }

void Lightmap::get_light ( const DrawingRequest request  )  const [virtual]

Implements Lightmap.

Definition at line 610 of file sdl_lightmap.cpp.

References GetLightRequest::color_ptr, DrawingRequest::pos, DrawingRequest::request_data, SCREEN_HEIGHT, SCREEN_WIDTH, Vector::x, and Vector::y.

00611   {
00612     const GetLightRequest* getlightrequest 
00613       = (GetLightRequest*) request.request_data;
00614 
00615     int x = (int) (request.pos.x * width / SCREEN_WIDTH);
00616     int y = (int) (request.pos.y * height / SCREEN_HEIGHT);
00617     int loc = y * width + x;
00618     *(getlightrequest->color_ptr) = Color(((float)red_channel[loc])/255, ((float)green_channel[loc])/255, ((float)blue_channel[loc])/255);
00619   }

void Lightmap::light_blit ( SDL_Surface *  src,
SDL_Rect *  src_rect,
int  dstx,
int  dsty 
) [private]

Definition at line 309 of file sdl_lightmap.cpp.

00310   {
00311     dstx /= LIGHTMAP_DIV;
00312     dsty /= LIGHTMAP_DIV;
00313     int srcx = src_rect->x / LIGHTMAP_DIV;
00314     int srcy = src_rect->y / LIGHTMAP_DIV;
00315     int blit_width = src_rect->w / LIGHTMAP_DIV;
00316     int blit_height = src_rect->h / LIGHTMAP_DIV;
00317     int bpp = src->format->BytesPerPixel;
00318     if(SDL_MUSTLOCK(src))
00319     {
00320       SDL_LockSurface(src);
00321     }
00322     Uint8 *pixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
00323     int loc = dsty * width + dstx;
00324     for(int y = 0;y < blit_height;y++) {
00325       for(int x = 0;x < blit_width;x++, pixel += bpp * LIGHTMAP_DIV, loc++) {
00326         if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
00327         {
00328           continue;
00329         }
00330         if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
00331         {
00332           continue;
00333         }
00334 
00335         Uint32 mapped = 0;
00336         switch(bpp) {
00337           case 1:
00338             mapped = *pixel;
00339             break;
00340           case 2:
00341             mapped = *(Uint16 *)pixel;
00342             break;
00343           case 3:
00344 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00345             mapped |= pixel[0] << 16;
00346             mapped |= pixel[1] << 8;
00347             mapped |= pixel[2] << 0;
00348 #else
00349             mapped |= pixel[0] << 0;
00350             mapped |= pixel[1] << 8;
00351             mapped |= pixel[2] << 16;
00352 #endif
00353             break;
00354           case 4:
00355             mapped = *(Uint32 *)pixel;
00356             break;
00357         }
00358         Uint8 red, green, blue, alpha;
00359         SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
00360 
00361         if(red != 0)
00362         {
00363           int redsum = red_channel[loc] + (red * alpha >> 8);
00364           red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
00365         }
00366         if(green != 0)
00367         {
00368           int greensum = green_channel[loc] + (green * alpha >> 8);
00369           green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
00370         }
00371         if(blue != 0)
00372         {
00373           int bluesum = blue_channel[loc] + (blue * alpha >> 8);
00374           blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
00375         }
00376       }
00377       pixel += (src->pitch - blit_width * bpp) * LIGHTMAP_DIV;
00378       loc += width - blit_width;
00379     }
00380     if(SDL_MUSTLOCK(src))
00381     {
00382       SDL_UnlockSurface(src);
00383     }
00384   }


Member Data Documentation

SDL_Surface* SDL::Lightmap::screen [private]

Definition at line 48 of file sdl_lightmap.hpp.

Uint8* SDL::Lightmap::red_channel [private]

Definition at line 49 of file sdl_lightmap.hpp.

Uint8* SDL::Lightmap::blue_channel [private]

Definition at line 50 of file sdl_lightmap.hpp.

Uint8* SDL::Lightmap::green_channel [private]

Definition at line 51 of file sdl_lightmap.hpp.

int SDL::Lightmap::width [private]

Definition at line 52 of file sdl_lightmap.hpp.

int SDL::Lightmap::height [private]

Definition at line 52 of file sdl_lightmap.hpp.

int SDL::Lightmap::numerator [private]

Definition at line 53 of file sdl_lightmap.hpp.

int SDL::Lightmap::denominator [private]

Definition at line 53 of file sdl_lightmap.hpp.

int SDL::Lightmap::LIGHTMAP_DIV [private]

Definition at line 54 of file sdl_lightmap.hpp.


The documentation for this class was generated from the following files:
Generated on Mon Nov 16 03:38:18 2009 for SuperTux by  doxygen 1.5.1