SDLRenderer Class Reference

#include <sdl_renderer.hpp>

Inherits Renderer.

List of all members.

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 &)
SDLRendereroperator= (const SDLRenderer &)

Private Attributes

SDL_Surfacescreen
int numerator
int denominator


Detailed Description

Definition at line 24 of file sdl_renderer.hpp.


Constructor & Destructor Documentation

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 (  ) 

Definition at line 165 of file sdl_renderer.cpp.

00166 {
00167 }

SDLRenderer::SDLRenderer ( const SDLRenderer  )  [private]


Member Function Documentation

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]

Implements Renderer.

Definition at line 394 of file sdl_renderer.cpp.

00395 {
00396 }

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]

Implements Renderer.

Definition at line 434 of file sdl_renderer.cpp.

00435 {
00436     
00437 }

void SDLRenderer::apply_config (  )  [inline, virtual]

Implements Renderer.

Definition at line 39 of file sdl_renderer.hpp.

00039 {}

SDLRenderer& SDLRenderer::operator= ( const SDLRenderer  )  [private]


Member Data Documentation

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().


The documentation for this class was generated from the following files:
Generated on Mon Apr 14 03:38:43 2014 for SuperTux by  doxygen 1.5.1