#include <sdl_lightmap.hpp>
Inherits Lightmap.
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 |
Definition at line 31 of file sdl_lightmap.hpp.
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 }
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] |
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 }
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.