#include "Blitter.h" #ifdef WITH_OPENGL // main GL blit on screen instructions void graphic::Blitter::GLBlit(Surface * src, Sint16 x_trans, Sint16 y_trans) { SDL_Rect * src_r = src->_rectangle; // update the src texture if it needs an update if(src->NeedTexUpdate()) src->UpdateTex(); glBindTexture(GL_TEXTURE_2D, src->_tex_num); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glOrtho(0, 2 * src->_wreal, 0, 2 * src->_hreal, -1, 1); glMatrixMode(GL_MODELVIEW); glColor4f(1.0f, 1.0f, 1.0f, src->_opacity / 255.0f); int xpad = (src->_wreal - src_r->w) / 2; int ypad = (src->_hreal - src_r->h) / 2; glPushMatrix(); glLoadIdentity(); // Move to the upper left coerner of the image glTranslated(x_trans, y_trans, 0); // Blitting glBegin(GL_QUADS); glTexCoord2d(xpad, ypad); glVertex2d(0, 0); glTexCoord2d(xpad + src_r->w, ypad); glVertex2d(src_r->w, 0); glTexCoord2d(xpad + src_r->w, ypad + src_r->h); glVertex2d(src_r->w, src_r->h); glTexCoord2d(xpad, ypad + src_r->h); glVertex2d(0, src_r->h); glEnd(); glPopMatrix(); } #endif // blit an entire surface on another one using surface position (NULL -> Rect) void graphic::Blitter::Blit(Surface * src, Surface * dest) { SDL_Rect * src_r = src->_rectangle; // SDL blit if(src->_graphic_mode == SDL_GRAPHIC) { SDL_Rect to; // copy src surface rect values into backup rect to.x = src_r->x; to.y = src_r->y; to.w = src_r->w; to.h = src_r->h; // blit on screen if(dest == NULL) SDL_BlitSurface(src->_surface, NULL, SDL_GetVideoSurface() , &to); // blit on surface else SDL_BlitSurface(src->_surface, NULL, dest->_surface, &to); } #ifdef WITH_OPENGL // GL blit else { // blit on screen if(dest == NULL) GLBlit(src, src_r->x, src_r->y); // blit on another surface else { // backup rect SDL_Rect to; // copy src surface rect values into backup rect to.x = src_r->x; to.y = src_r->y; to.w = src_r->w; to.h = src_r->h; // blit on dest SDL_BlitSurface(src->_surface, NULL, dest->_surface, &to); // request texture update dest->RequestTexUpdate(); } } #endif } // NULL -> Rect // blit an entire surface on another one NOT using surface position, but dest_rect one void graphic::Blitter::Blit(Surface * src, SDL_Rect & dest_rect, Surface * dest) { // SDL blit if(src->_graphic_mode == SDL_GRAPHIC) { // backup rect SDL_Rect to; // copy src surface rect values into backup rect to.x = dest_rect.x; to.y = dest_rect.y; to.w = dest_rect.w; to.h = dest_rect.h; // blit on screen if(dest == NULL) SDL_BlitSurface(src->_surface, NULL, SDL_GetVideoSurface(), &to); // blit on dest else SDL_BlitSurface(src->_surface, NULL, dest->_surface, &to); } #ifdef WITH_OPENGL // GL blit else { if(dest == NULL) GLBlit(src, dest_rect.x, dest_rect.y); else { // backup rect SDL_Rect to; // copy src surface rect values into backup rect to.x = dest_rect.x; to.y = dest_rect.y; to.w = dest_rect.w; to.h = dest_rect.h; // blit on dest SDL_BlitSurface(src->_surface, NULL, dest->_surface, &to); // request texture update dest->RequestTexUpdate(); } } #endif } // blit part of a surface on another one using surface position for // the destination (Rect -> rect) void graphic::Blitter::BlitPart(Surface * src, SDL_Rect & src_rect, Surface * dest) { SDL_Rect * src_r = src->_rectangle; // SDL blit if(src->_graphic_mode == SDL_GRAPHIC) { // backup rect SDL_Rect from, to; // copy src surface rect values into backup rect from.x = src_rect.x; from.y = src_rect.y; from.w = src_rect.w; from.h = src_rect.h; to.x = src_r->x; to.y = src_r->y; to.w = src_rect.w; to.h = src_rect.h; // blit on screen if(dest == NULL) SDL_BlitSurface(src->_surface, &from, SDL_GetVideoSurface(), &to); // blit on dest else SDL_BlitSurface(src->_surface, &from, dest->_surface, &to); } #ifdef WITH_OPENGL // GL blit else { if(dest == NULL) { // update the src texture if it needs an update if(src->NeedTexUpdate()) src->UpdateTex(); glBindTexture(GL_TEXTURE_2D, src->_tex_num); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glOrtho(0, 2 * src->_wreal, 0, 2 * src->_hreal, -1, 1); glMatrixMode(GL_MODELVIEW); glColor4f(1.0f, 1.0f, 1.0f, src->_opacity / 255.0f); int xpad = (src->_wreal - src_r->w) / 2; int ypad = (src->_hreal - src_r->h) / 2; glPushMatrix(); glLoadIdentity(); // Move to the upper left corner of the image part glTranslated(src_r->x, src_r->y, 0); // Blitting glBegin(GL_QUADS); glTexCoord2d(xpad + src_rect.x, ypad + src_rect.y); glVertex2d(0, 0); glTexCoord2d(xpad + src_rect.x + src_rect.w, ypad + src_rect.y); glVertex2d(src_rect.w, 0); glTexCoord2d(xpad + src_rect.x + src_rect.w, ypad + src_rect.y + src_rect.h); glVertex2d(src_rect.w, src_rect.h); glTexCoord2d(xpad + src_rect.x, ypad + src_rect.y + src_rect.h); glVertex2d(0, src_rect.h); glEnd(); glPopMatrix(); } else { // backup rect SDL_Rect from, to; // copy src surface rect values into backup rect from.x = src_rect.x; from.y = src_rect.y; from.w = src_rect.w; from.h = src_rect.h; to.x = src_r->x; to.y = src_r->y; to.w = src_r->w; to.h = src_r->h; // blit on dest SDL_BlitSurface(src->_surface, &from, dest->_surface, &to); // request texture update dest->RequestTexUpdate(); } } #endif } // blit part of a surface on part of another one NOT using surface position // for the destination, but dest_rect.x and dest_rect.y (Rect -> Rect) void graphic::Blitter::BlitPart(Surface * src, SDL_Rect & src_rect, SDL_Rect & dest_rect, Surface * dest) { #ifdef WITH_OPENGL SDL_Rect * src_r = src->_rectangle; #endif // SDL blit if(src->_graphic_mode == SDL_GRAPHIC) { // backup rect SDL_Rect from, to; // copy src surface rect values into backup rect from.x = src_rect.x; from.y = src_rect.y; from.w = src_rect.w; from.h = src_rect.h; // copy src surface rect values into backup rect to.x = dest_rect.x; to.y = dest_rect.y; to.w = dest_rect.w; to.h = dest_rect.h; // blit on screen if(dest == NULL) SDL_BlitSurface(src->_surface, &from, SDL_GetVideoSurface(), &to); // blit on dest else SDL_BlitSurface(src->_surface, &from, dest->_surface, &to); } #ifdef WITH_OPENGL // GL blit else { if(dest == NULL) { // update the src texture if it needs an update if(src->NeedTexUpdate()) src->UpdateTex(); glBindTexture(GL_TEXTURE_2D, src->_tex_num); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glOrtho(0, 2 * src->_wreal, 0, 2 * src->_hreal, -1, 1); glMatrixMode(GL_MODELVIEW); glColor4f(1.0f, 1.0f, 1.0f, src->_opacity / 255.0f); int xpad = (src->_wreal - src_r->w) / 2; int ypad = (src->_hreal - src_r->h) / 2; glPushMatrix(); glLoadIdentity(); // Move to the upper left corner of the destination rectangle glTranslated(dest_rect.x, dest_rect.y, 0); // Blitting glBegin(GL_QUADS); glTexCoord2d(xpad + src_rect.x, ypad + src_rect.y); glVertex2d(0, 0); glTexCoord2d(xpad + src_rect.x + src_rect.w, ypad + src_rect.y); glVertex2d(src_rect.w, 0); glTexCoord2d(xpad + src_rect.x + src_rect.w, ypad + src_rect.y + src_rect.h); glVertex2d(src_rect.w, src_rect.h); glTexCoord2d(xpad + src_rect.x, ypad + src_rect.y + src_rect.h); glVertex2d(0, src_rect.h); glEnd(); glPopMatrix(); } else { // backup rect SDL_Rect from, to; // copy src surface rect values into backup rect from.x = src_rect.x; from.y = src_rect.y; from.w = src_rect.w; from.h = src_rect.h; to.x = dest_rect.x; to.y = dest_rect.y; to.w = dest_rect.w; to.h = dest_rect.h; // blit on dest SDL_BlitSurface(src->_surface, &from, dest->_surface, &to); // request texture update dest->RequestTexUpdate(); } } #endif } // blit the part of screen limited by src_rect on the dest surface void graphic::Blitter::SaveScreen(SDL_Rect & src_rect, Surface * dest) { // SDL blit if(dest->_graphic_mode == SDL_GRAPHIC) { // backup rect SDL_Rect from; // copy src surface rect values into backup rect from.x = src_rect.x; from.y = src_rect.y; from.w = src_rect.w; from.h = src_rect.h; // blit from screen to dest SDL_BlitSurface(SDL_GetVideoSurface(), &from, dest->_surface, NULL); } } // blit part of screen limited by src_rect on part of the dest surface // limited by dest_rect void graphic::Blitter::SaveScreen(SDL_Rect & src_rect, SDL_Rect & dest_rect, Surface * dest) { // SDL blit if(dest->_graphic_mode == SDL_GRAPHIC) { // backup rect SDL_Rect from, to; // copy src surface rect values into backup rect from.x = src_rect.x; from.y = src_rect.y; from.w = src_rect.w; from.h = src_rect.h; // copy dest rect values into backup rect to.x = dest_rect.x; to.y = dest_rect.y; to.w = dest_rect.w; to.h = dest_rect.h; // blit from screen to dest SDL_BlitSurface(SDL_GetVideoSurface(), &from, dest->_surface, &to); } }