#include <sdl_renderer.hpp>
Inherits Renderer.
Public Member Functions | |
SDLRenderer () | |
~SDLRenderer () | |
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 | draw_inverse_ellipse (const DrawingRequest &request) |
void | do_take_screenshot () |
void | flip () |
void | resize (int w, int h) |
void | apply_config () |
Private Member Functions | |
SDLRenderer (const SDLRenderer &) | |
SDLRenderer & | operator= (const SDLRenderer &) |
Private Attributes | |
SDL_Surface * | screen |
int | numerator |
int | denominator |
Definition at line 24 of file sdl_renderer.hpp.
SDLRenderer::SDLRenderer | ( | ) |
Definition at line 113 of file sdl_renderer.cpp.
References denominator, g_config, Renderer::instance_, log_info, numerator, screen, texture_manager, and Config::use_fullscreen.
00113 : 00114 screen(), 00115 numerator(), 00116 denominator() 00117 { 00118 Renderer::instance_ = this; 00119 00120 const SDL_VideoInfo *info = SDL_GetVideoInfo(); 00121 log_info << "Hardware surfaces are " << (info->hw_available ? "" : "not ") << "available." << std::endl; 00122 log_info << "Hardware to hardware blits are " << (info->blit_hw ? "" : "not ") << "accelerated." << std::endl; 00123 log_info << "Hardware to hardware blits with colorkey are " << (info->blit_hw_CC ? "" : "not ") << "accelerated." << std::endl; 00124 log_info << "Hardware to hardware blits with alpha are " << (info->blit_hw_A ? "" : "not ") << "accelerated." << std::endl; 00125 log_info << "Software to hardware blits are " << (info->blit_sw ? "" : "not ") << "accelerated." << std::endl; 00126 log_info << "Software to hardware blits with colorkey are " << (info->blit_sw_CC ? "" : "not ") << "accelerated." << std::endl; 00127 log_info << "Software to hardware blits with alpha are " << (info->blit_sw_A ? "" : "not ") << "accelerated." << std::endl; 00128 log_info << "Color fills are " << (info->blit_fill ? "" : "not ") << "accelerated." << std::endl; 00129 00130 int flags = SDL_SWSURFACE | SDL_ANYFORMAT; 00131 if(g_config->use_fullscreen) 00132 flags |= SDL_FULLSCREEN; 00133 00134 int width = 800; //FIXME: config->screenwidth; 00135 int height = 600; //FIXME: config->screenheight; 00136 00137 screen = SDL_SetVideoMode(width, height, 0, flags); 00138 if(screen == 0) { 00139 std::stringstream msg; 00140 msg << "Couldn't set video mode (" << width << "x" << height 00141 << "): " << SDL_GetError(); 00142 throw std::runtime_error(msg.str()); 00143 } 00144 00145 numerator = 1; 00146 denominator = 1; 00147 /* FIXME: 00148 float xfactor = (float) config->screenwidth / SCREEN_WIDTH; 00149 float yfactor = (float) config->screenheight / SCREEN_HEIGHT; 00150 if(xfactor < yfactor) 00151 { 00152 numerator = config->screenwidth; 00153 denominator = SCREEN_WIDTH; 00154 } 00155 else 00156 { 00157 numerator = config->screenheight; 00158 denominator = SCREEN_HEIGHT; 00159 } 00160 */ 00161 if(texture_manager == 0) 00162 texture_manager = new TextureManager(); 00163 }
SDLRenderer::~SDLRenderer | ( | ) |
SDLRenderer::SDLRenderer | ( | const SDLRenderer & | ) | [private] |
void SDLRenderer::draw_surface | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 170 of file sdl_renderer.cpp.
References DrawingRequest::alpha, DrawingRequest::color, denominator, DrawingRequest::drawing_effect, Surface::get_flipx(), SDLSurfaceData::get_src_rect(), Surface::get_surface_data(), Surface::get_texture(), HORIZONTAL_FLIP, numerator, DrawingRequest::pos, DrawingRequest::request_data, screen, Vector::x, and Vector::y.
00171 { 00172 //FIXME: support parameters request.alpha, request.angle, request.blend 00173 const Surface* surface = (const Surface*) request.request_data; 00174 boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture()); 00175 SDLSurfaceData *surface_data = reinterpret_cast<SDLSurfaceData *>(surface->get_surface_data()); 00176 00177 DrawingEffect effect = request.drawing_effect; 00178 if (surface->get_flipx()) effect = HORIZONTAL_FLIP; 00179 00180 SDL_Surface *transform = sdltexture->get_transform(request.color, effect); 00181 00182 // get and check SDL_Surface 00183 if (transform == 0) { 00184 std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl; 00185 return; 00186 } 00187 00188 SDL_Rect *src_rect = surface_data->get_src_rect(effect); 00189 SDL_Rect dst_rect; 00190 dst_rect.x = (int) request.pos.x * numerator / denominator; 00191 dst_rect.y = (int) request.pos.y * numerator / denominator; 00192 00193 Uint8 alpha = 0; 00194 if(request.alpha != 1.0) 00195 { 00196 if(!transform->format->Amask) 00197 { 00198 if(transform->flags & SDL_SRCALPHA) 00199 { 00200 alpha = transform->format->alpha; 00201 } 00202 else 00203 { 00204 alpha = 255; 00205 } 00206 SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha)); 00207 } 00208 /*else 00209 { 00210 transform = apply_alpha(transform, request.alpha); 00211 }*/ 00212 } 00213 00214 SDL_BlitSurface(transform, src_rect, screen, &dst_rect); 00215 00216 if(request.alpha != 1.0) 00217 { 00218 if(!transform->format->Amask) 00219 { 00220 if(alpha == 255) 00221 { 00222 SDL_SetAlpha(transform, SDL_RLEACCEL, 0); 00223 } 00224 else 00225 { 00226 SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha); 00227 } 00228 } 00229 /*else 00230 { 00231 SDL_FreeSurface(transform); 00232 }*/ 00233 } 00234 }
void SDLRenderer::draw_surface_part | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 237 of file sdl_renderer.cpp.
References DrawingRequest::alpha, DrawingRequest::color, denominator, DrawingRequest::drawing_effect, HORIZONTAL_FLIP, numerator, DrawingRequest::pos, DrawingRequest::request_data, screen, SurfacePartRequest::size, SurfacePartRequest::source, SurfacePartRequest::surface, VERTICAL_FLIP, Vector::x, and Vector::y.
00238 { 00239 const SurfacePartRequest* surfacepartrequest 00240 = (SurfacePartRequest*) request.request_data; 00241 00242 const Surface* surface = surfacepartrequest->surface; 00243 boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture()); 00244 00245 DrawingEffect effect = request.drawing_effect; 00246 if (surface->get_flipx()) effect = HORIZONTAL_FLIP; 00247 00248 SDL_Surface *transform = sdltexture->get_transform(request.color, effect); 00249 00250 // get and check SDL_Surface 00251 if (transform == 0) { 00252 std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl; 00253 return; 00254 } 00255 00256 int ox, oy; 00257 if (effect == HORIZONTAL_FLIP) 00258 { 00259 ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x; 00260 } 00261 else 00262 { 00263 ox = surface->get_x(); 00264 } 00265 if (effect == VERTICAL_FLIP) 00266 { 00267 oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y; 00268 } 00269 else 00270 { 00271 oy = surface->get_y(); 00272 } 00273 00274 SDL_Rect src_rect; 00275 src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator; 00276 src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator; 00277 src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator; 00278 src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator; 00279 00280 SDL_Rect dst_rect; 00281 dst_rect.x = (int) request.pos.x * numerator / denominator; 00282 dst_rect.y = (int) request.pos.y * numerator / denominator; 00283 00284 Uint8 alpha = 0; 00285 if(request.alpha != 1.0) 00286 { 00287 if(!transform->format->Amask) 00288 { 00289 if(transform->flags & SDL_SRCALPHA) 00290 { 00291 alpha = transform->format->alpha; 00292 } 00293 else 00294 { 00295 alpha = 255; 00296 } 00297 SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha)); 00298 } 00299 /*else 00300 { 00301 transform = apply_alpha(transform, request.alpha); 00302 }*/ 00303 } 00304 00305 SDL_BlitSurface(transform, &src_rect, screen, &dst_rect); 00306 00307 if(request.alpha != 1.0) 00308 { 00309 if(!transform->format->Amask) 00310 { 00311 if(alpha == 255) 00312 { 00313 SDL_SetAlpha(transform, SDL_RLEACCEL, 0); 00314 } 00315 else 00316 { 00317 SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha); 00318 } 00319 } 00320 /*else 00321 { 00322 SDL_FreeSurface(transform); 00323 }*/ 00324 } 00325 }
void SDLRenderer::draw_text | ( | const DrawingRequest & | request | ) |
void SDLRenderer::draw_gradient | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 328 of file sdl_renderer.cpp.
References GradientRequest::bottom, DrawingRequest::request_data, screen, and GradientRequest::top.
00329 { 00330 const GradientRequest* gradientrequest 00331 = (GradientRequest*) request.request_data; 00332 const Color& top = gradientrequest->top; 00333 const Color& bottom = gradientrequest->bottom; 00334 00335 for(int y = 0;y < screen->h;++y) 00336 { 00337 Uint8 r = (Uint8)((((float)(top.red-bottom.red)/(0-screen->h)) * y + top.red) * 255); 00338 Uint8 g = (Uint8)((((float)(top.green-bottom.green)/(0-screen->h)) * y + top.green) * 255); 00339 Uint8 b = (Uint8)((((float)(top.blue-bottom.blue)/(0-screen->h)) * y + top.blue) * 255); 00340 Uint8 a = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-screen->h)) * y + top.alpha) * 255); 00341 Uint32 color = SDL_MapRGB(screen->format, r, g, b); 00342 00343 SDL_Rect rect; 00344 rect.x = 0; 00345 rect.y = y; 00346 rect.w = screen->w; 00347 rect.h = 1; 00348 00349 if(a == SDL_ALPHA_OPAQUE) { 00350 SDL_FillRect(screen, &rect, color); 00351 } else if(a != SDL_ALPHA_TRANSPARENT) { 00352 SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); 00353 00354 SDL_FillRect(temp, 0, color); 00355 SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a); 00356 SDL_BlitSurface(temp, 0, screen, &rect); 00357 SDL_FreeSurface(temp); 00358 } 00359 } 00360 }
void SDLRenderer::draw_filled_rect | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 363 of file sdl_renderer.cpp.
References Color::alpha, Color::blue, FillRectRequest::color, Color::green, DrawingRequest::pos, Color::red, DrawingRequest::request_data, screen, SCREEN_HEIGHT, SCREEN_WIDTH, FillRectRequest::size, Vector::x, and Vector::y.
00364 { 00365 const FillRectRequest* fillrectrequest 00366 = (FillRectRequest*) request.request_data; 00367 00368 SDL_Rect rect; 00369 rect.x = (Sint16)request.pos.x * screen->w / SCREEN_WIDTH; 00370 rect.y = (Sint16)request.pos.y * screen->h / SCREEN_HEIGHT; 00371 rect.w = (Uint16)fillrectrequest->size.x * screen->w / SCREEN_WIDTH; 00372 rect.h = (Uint16)fillrectrequest->size.y * screen->h / SCREEN_HEIGHT; 00373 if((rect.w == 0) || (rect.h == 0)) { 00374 return; 00375 } 00376 Uint8 r = static_cast<Uint8>(fillrectrequest->color.red * 255); 00377 Uint8 g = static_cast<Uint8>(fillrectrequest->color.green * 255); 00378 Uint8 b = static_cast<Uint8>(fillrectrequest->color.blue * 255); 00379 Uint8 a = static_cast<Uint8>(fillrectrequest->color.alpha * 255); 00380 Uint32 color = SDL_MapRGB(screen->format, r, g, b); 00381 if(a == SDL_ALPHA_OPAQUE) { 00382 SDL_FillRect(screen, &rect, color); 00383 } else if(a != SDL_ALPHA_TRANSPARENT) { 00384 SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); 00385 00386 SDL_FillRect(temp, 0, color); 00387 SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a); 00388 SDL_BlitSurface(temp, 0, screen, &rect); 00389 SDL_FreeSurface(temp); 00390 } 00391 }
void SDLRenderer::draw_inverse_ellipse | ( | const DrawingRequest & | request | ) | [virtual] |
void SDLRenderer::do_take_screenshot | ( | ) | [virtual] |
Implements Renderer.
Definition at line 399 of file sdl_renderer.cpp.
References log_debug, log_warning, and screen.
00400 { 00401 // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it? 00402 00403 SDL_Surface *screen = SDL_GetVideoSurface(); 00404 00405 // save screenshot 00406 static const std::string writeDir = PHYSFS_getWriteDir(); 00407 static const std::string dirSep = PHYSFS_getDirSeparator(); 00408 static const std::string baseName = "screenshot"; 00409 static const std::string fileExt = ".bmp"; 00410 std::string fullFilename; 00411 for (int num = 0; num < 1000; num++) { 00412 std::ostringstream oss; 00413 oss << baseName; 00414 oss << std::setw(3) << std::setfill('0') << num; 00415 oss << fileExt; 00416 std::string fileName = oss.str(); 00417 fullFilename = writeDir + dirSep + fileName; 00418 if (!PHYSFS_exists(fileName.c_str())) { 00419 SDL_SaveBMP(screen, fullFilename.c_str()); 00420 log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl; 00421 return; 00422 } 00423 } 00424 log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl; 00425 }
void SDLRenderer::flip | ( | ) | [virtual] |
Implements Renderer.
Definition at line 428 of file sdl_renderer.cpp.
References screen.
00429 { 00430 SDL_Flip(screen); 00431 }
void SDLRenderer::resize | ( | int | w, | |
int | h | |||
) | [virtual] |
void SDLRenderer::apply_config | ( | ) | [inline, virtual] |
SDLRenderer& SDLRenderer::operator= | ( | const SDLRenderer & | ) | [private] |
SDL_Surface* SDLRenderer::screen [private] |
Definition at line 42 of file sdl_renderer.hpp.
Referenced by do_take_screenshot(), draw_filled_rect(), draw_gradient(), draw_surface(), draw_surface_part(), flip(), and SDLRenderer().
int SDLRenderer::numerator [private] |
Definition at line 43 of file sdl_renderer.hpp.
Referenced by draw_surface(), draw_surface_part(), and SDLRenderer().
int SDLRenderer::denominator [private] |
Definition at line 44 of file sdl_renderer.hpp.
Referenced by draw_surface(), draw_surface_part(), and SDLRenderer().