// Effect cycle void CColorMerge::ponder(const float deltaT) { // Process the effect #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfaceAlphaMod( mpOldSurface.get(), 255-m_Alpha ); #else SDL_SetAlpha( mpOldSurface.get(), SDL_SRCALPHA, 255-m_Alpha ); #endif const int sum = m_Alpha + m_Speed; if(sum > 255) { m_Alpha = 255; mFinished = true; } else { m_Alpha += m_Speed; } }
//This method gets called at game start ONLY ! int build_board(board_graph *board,SDL_Renderer *renderer){ if((board != NULL) && (renderer != NULL)){ init_board(board); SDL_Surface* load_surface = NULL; load_surface = surface_from_path(renderer,"Resources/board.bmp"); //SDL_SetColorKey(load_surface,SDL_TRUE,SDL_MapRGB(load_surface->format,0,0,0)); //Map background elements to background surface before we convert it to texture SDL_SetSurfaceAlphaMod(load_surface,255); board->background_texture = SDL_CreateTextureFromSurface(renderer,load_surface); SDL_FreeSurface(load_surface); load_surface = NULL; load_surface = surface_from_path(renderer,"Resources/cards/cthulu_clear.bmp"); SDL_SetColorKey(load_surface,SDL_TRUE,SDL_MapRGB(load_surface->format,25,25,25)); board->cards_on_board[0].layout.texture = SDL_CreateTextureFromSurface(renderer,load_surface); SDL_FreeSurface(load_surface); load_surface = NULL; return 0; } }
/* sets the transparency value for the font in question. assumes that * we're in an OpenGL context. */ void DT_SetFontAlphaGL(int FontNumber, int a) { unsigned char val; BitFont *CurrentFont; unsigned char r_targ, g_targ, b_targ; int i, imax; unsigned char *pix; /* get pointer to font */ CurrentFont = DT_FontPointer(FontNumber); if(CurrentFont == NULL) { PRINT_ERROR("Setting font alpha for non-existent font!\n"); return; } if(CurrentFont->FontSurface->format->BytesPerPixel == 2) { PRINT_ERROR("16-bit SDL surfaces do not support alpha-blending under OpenGL\n"); return; } if(a < SDL_ALPHA_TRANSPARENT) val = SDL_ALPHA_TRANSPARENT; else if(a > SDL_ALPHA_OPAQUE) val = SDL_ALPHA_OPAQUE; else val = a; /* iterate over all pixels in the font surface. For each * pixel that is (255,0,255), set its alpha channel * appropriately. */ imax = CurrentFont->FontSurface->h * (CurrentFont->FontSurface->w << 2); pix = (unsigned char *)(CurrentFont->FontSurface->pixels); r_targ = 255; /*pix[0]; */ g_targ = 0; /*pix[1]; */ b_targ = 255; /*pix[2]; */ for(i = 3; i < imax; i += 4) if(pix[i - 3] == r_targ && pix[i - 2] == g_targ && pix[i - 1] == b_targ) pix[i] = val; /* also make sure that alpha blending is disabled for the font surface. */ SDL_SetSurfaceAlphaMod(CurrentFont->FontSurface, SDL_ALPHA_OPAQUE); }
/** * \brief Sets the opacity of this surface. * \param opacity the opacity (0 to 255). */ void Surface::set_opacity(uint8_t opacity) { if (software_destination // The destination surface is in RAM. || !Video::is_acceleration_enabled() // The rendering is in RAM. ) { if (internal_surface == NULL) { create_software_surface(); } // The surface must be 32-bit with alpha value for this function to work. convert_software_surface(); int error = SDL_SetSurfaceAlphaMod(internal_surface, opacity); if (error != 0) { Debug::error(SDL_GetError()); } is_rendered = false; // The surface has changed. } else { internal_opacity = opacity; } }
void DropDownConsole::render(float cameraX, float cameraY) { if (!(this->isVisible())) return; // Background SDL_FillRect(this->surface, NULL, SDL::convertColorFormat(this->background)); SDL_SetSurfaceAlphaMod(this->surface, this->background.a()); this->renderLines(); // Placing everything onscreen SDL_Rect crop; crop.x = 0; crop.y = this->height - this->topOffset; crop.w = this->width; crop.h = this->topOffset; SDL_Rect position; position.x = this->x - cameraX; position.y = this->y - cameraY; // SDL::renderSurface(this->surface, &crop, &position); // TODO BUG HACK // THIS IS VERY EXPENSIVE - CALLIGN EACH FRAME // MUST FIND A WAY OF DOING THIS ON SDL 2 SDL_Texture* texture = SDL_CreateTextureFromSurface(Window::renderer, this->surface); SDL::renderImage(texture, &crop, &position); SDL::freeImage(texture); // History text // Cursor }
/** * \brief Converts the software surface to the preferred pixel format * (32-bit with alpha channel). */ void Surface::convert_software_surface() { Debug::check_assertion(internal_surface != NULL, "Missing software surface to convert"); SDL_PixelFormat* pixel_format = Video::get_pixel_format(); if (internal_surface->format->format != pixel_format->format) { // Convert to the preferred pixel format. uint8_t opacity; SDL_GetSurfaceAlphaMod(internal_surface, &opacity); SDL_Surface* converted_surface = SDL_ConvertSurface( internal_surface, pixel_format, 0 ); Debug::check_assertion(converted_surface != NULL, "Failed to convert software surface"); SDL_FreeSurface(internal_surface); internal_surface = converted_surface; SDL_SetSurfaceAlphaMod(internal_surface, opacity); // Re-apply the alpha. } }
static void PrepTextureForCopy(const SDL_RenderCommand *cmd) { const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const SDL_BlendMode blend = cmd->data.draw.blend; SDL_Texture *texture = cmd->data.draw.texture; SDL_Surface *surface = (SDL_Surface *) texture->driverdata; const SDL_bool colormod = ((r & g & b) != 0xFF); const SDL_bool alphamod = (a != 0xFF); const SDL_bool blending = ((blend == SDL_BLENDMODE_ADD) || (blend == SDL_BLENDMODE_MOD)); if (colormod || alphamod || blending) { SDL_SetSurfaceRLE(surface, 0); } /* !!! FIXME: we can probably avoid some of these calls. */ SDL_SetSurfaceColorMod(surface, r, g, b); SDL_SetSurfaceAlphaMod(surface, a); SDL_SetSurfaceBlendMode(surface, blend); }
static SDL_Surface *create_surface(int width, int height, bool with_alpha) { Uint32 rmask,gmask,bmask,amask; SDL_Surface *bitmap; int flags=SDL_SWSURFACE; if ( with_alpha ) { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0x000000FF; gmask=0x0000FF00; bmask=0x00FF0000; amask=0xFF000000; } else { rmask=0xFF000000; gmask=0x00FF0000; bmask=0x0000FF00; amask=0x000000FF; } } else { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0x0000FF; gmask=0x00FF00; bmask=0xFF0000; } else { rmask=0xFF0000; gmask=0x00FF00; bmask=0x0000FF; } amask=0; } bitmap=SDL_CreateRGBSurface(flags,width,height, with_alpha ? 32:24, rmask,gmask,bmask,amask); if ( with_alpha ) { SDL_SetSurfaceAlphaMod(bitmap, 255); } return (void *)bitmap; }
//Set the alpha (blending) transparancy bool Surface::SetTransparency(int alpha) { if (_surface!=0) { if (alpha>SDL_ALPHA_OPAQUE){alpha=SDL_ALPHA_OPAQUE;}//Check if some limits are exceeded if (alpha<SDL_ALPHA_TRANSPARENT){alpha=SDL_ALPHA_TRANSPARENT;} if (_texture!=0) { if(SDL_SetTextureAlphaMod(_texture,alpha)==-1) { Error error(Log,"Failed to set transparency on texture",0,true); return false; };} else { if(SDL_SetSurfaceAlphaMod(_surface,alpha)==-1) { Error error(Log,"Failed to set transparency on surface",0,true); return false; }; } return true; } return false; };
// Process the flashing effect here void CFlash::ponder() { Uint32 ElapsedTime = g_pTimer->getTicks() - m_StartTime; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfaceAlphaMod(mpFadeSurface.get(), m_Alpha); #else SDL_SetAlpha(mpFadeSurface.get(), SDL_SRCALPHA, m_Alpha); #endif if(m_FadeDir == FADE_IN) { if(m_Alpha+m_Speed > m_MaxAlpha) m_Alpha = m_MaxAlpha; else m_Alpha+=m_Speed; } if(m_FadeDir == FADE_OUT) { if(m_Alpha+m_Speed < 0) m_Alpha = 0; else m_Alpha-=m_Speed; } if(m_Style == FADE_PULSE) { if(m_Alpha == 255) m_FadeDir = FADE_OUT; else if(m_Alpha == 0) m_FadeDir = FADE_IN; } else if(m_Style == FADE_NORMAL) { if(ElapsedTime >= m_RunTime/2 ) m_FadeDir = FADE_OUT; if(m_FadeDir == FADE_OUT && m_Alpha == 0) mFinished = true; } // The developer set a time in the constructor. This effect will last for the given time. if(ElapsedTime >= m_RunTime) mFinished = true; }
static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; SDL_Rect final_rect, tmp_rect; SDL_Surface *src_clone, *src_rotated, *src_scaled; SDL_Surface *mask = NULL, *mask_rotated = NULL; int retval = 0, dstwidth, dstheight, abscenterx, abscentery; double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; SDL_BlendMode blendmode; Uint8 alphaMod, rMod, gMod, bMod; int applyModulation = SDL_FALSE; int blitRequired = SDL_FALSE; int isOpaque = SDL_FALSE; if (!surface) { return -1; } if (renderer->viewport.x || renderer->viewport.y) { final_rect.x = (int)(renderer->viewport.x + dstrect->x); final_rect.y = (int)(renderer->viewport.y + dstrect->y); } else { final_rect.x = (int)dstrect->x; final_rect.y = (int)dstrect->y; } final_rect.w = (int)dstrect->w; final_rect.h = (int)dstrect->h; tmp_rect = final_rect; tmp_rect.x = 0; tmp_rect.y = 0; /* It is possible to encounter an RLE encoded surface here and locking it is * necessary because this code is going to access the pixel buffer directly. */ if (SDL_MUSTLOCK(src)) { SDL_LockSurface(src); } /* Clone the source surface but use its pixel buffer directly. * The original source surface must be treated as read-only. */ src_clone = SDL_CreateRGBSurfaceFrom(src->pixels, src->w, src->h, src->format->BitsPerPixel, src->pitch, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); if (src_clone == NULL) { if (SDL_MUSTLOCK(src)) { SDL_UnlockSurface(src); } return -1; } SDL_GetSurfaceBlendMode(src, &blendmode); SDL_GetSurfaceAlphaMod(src, &alphaMod); SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod); /* SDLgfx_rotateSurface only accepts 32-bit surfaces with a 8888 layout. Everything else has to be converted. */ if (src->format->BitsPerPixel != 32 || SDL_PIXELLAYOUT(src->format->format) != SDL_PACKEDLAYOUT_8888 || !src->format->Amask) { blitRequired = SDL_TRUE; } /* If scaling and cropping is necessary, it has to be taken care of before the rotation. */ if (!(srcrect->w == final_rect.w && srcrect->h == final_rect.h && srcrect->x == 0 && srcrect->y == 0)) { blitRequired = SDL_TRUE; } /* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */ if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) { applyModulation = SDL_TRUE; SDL_SetSurfaceAlphaMod(src_clone, alphaMod); SDL_SetSurfaceColorMod(src_clone, rMod, gMod, bMod); } /* Opaque surfaces are much easier to handle with the NONE blend mode. */ if (blendmode == SDL_BLENDMODE_NONE && !src->format->Amask && alphaMod == 255) { isOpaque = SDL_TRUE; } /* The NONE blend mode requires a mask for non-opaque surfaces. This mask will be used * to clear the pixels in the destination surface. The other steps are explained below. */ if (blendmode == SDL_BLENDMODE_NONE && !isOpaque) { mask = SDL_CreateRGBSurface(0, final_rect.w, final_rect.h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); if (mask == NULL) { retval = -1; } else { SDL_SetSurfaceBlendMode(mask, SDL_BLENDMODE_MOD); } } /* Create a new surface should there be a format mismatch or if scaling, cropping, * or modulation is required. It's possible to use the source surface directly otherwise. */ if (!retval && (blitRequired || applyModulation)) { SDL_Rect scale_rect = tmp_rect; src_scaled = SDL_CreateRGBSurface(0, final_rect.w, final_rect.h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); if (src_scaled == NULL) { retval = -1; } else { SDL_SetSurfaceBlendMode(src_clone, SDL_BLENDMODE_NONE); retval = SDL_BlitScaled(src_clone, srcrect, src_scaled, &scale_rect); SDL_FreeSurface(src_clone); src_clone = src_scaled; src_scaled = NULL; } } /* SDLgfx_rotateSurface is going to make decisions depending on the blend mode. */ SDL_SetSurfaceBlendMode(src_clone, blendmode); if (!retval) { SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle); src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); if (src_rotated == NULL) { retval = -1; } if (!retval && mask != NULL) { /* The mask needed for the NONE blend mode gets rotated with the same parameters. */ mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle); if (mask_rotated == NULL) { retval = -1; } } if (!retval) { /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ abscenterx = final_rect.x + (int)center->x; abscentery = final_rect.y + (int)center->y; /* Compensate the angle inversion to match the behaviour of the other backends */ sangle = -sangle; /* Top Left */ px = final_rect.x - abscenterx; py = final_rect.y - abscentery; p1x = px * cangle - py * sangle + abscenterx; p1y = px * sangle + py * cangle + abscentery; /* Top Right */ px = final_rect.x + final_rect.w - abscenterx; py = final_rect.y - abscentery; p2x = px * cangle - py * sangle + abscenterx; p2y = px * sangle + py * cangle + abscentery; /* Bottom Left */ px = final_rect.x - abscenterx; py = final_rect.y + final_rect.h - abscentery; p3x = px * cangle - py * sangle + abscenterx; p3y = px * sangle + py * cangle + abscentery; /* Bottom Right */ px = final_rect.x + final_rect.w - abscenterx; py = final_rect.y + final_rect.h - abscentery; p4x = px * cangle - py * sangle + abscenterx; p4y = px * sangle + py * cangle + abscentery; tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x)); tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y)); tmp_rect.w = dstwidth; tmp_rect.h = dstheight; /* The NONE blend mode needs some special care with non-opaque surfaces. * Other blend modes or opaque surfaces can be blitted directly. */ if (blendmode != SDL_BLENDMODE_NONE || isOpaque) { if (applyModulation == SDL_FALSE) { /* If the modulation wasn't already applied, make it happen now. */ SDL_SetSurfaceAlphaMod(src_rotated, alphaMod); SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod); } retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect); } else { /* The NONE blend mode requires three steps to get the pixels onto the destination surface. * First, the area where the rotated pixels will be blitted to get set to zero. * This is accomplished by simply blitting a mask with the NONE blend mode. * The colorkey set by the rotate function will discard the correct pixels. */ SDL_Rect mask_rect = tmp_rect; SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE); retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect); if (!retval) { /* The next step copies the alpha value. This is done with the BLEND blend mode and * by modulating the source colors with 0. Since the destination is all zeros, this * will effectively set the destination alpha to the source alpha. */ SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0); mask_rect = tmp_rect; retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect); if (!retval) { /* The last step gets the color values in place. The ADD blend mode simply adds them to * the destination (where the color values are all zero). However, because the ADD blend * mode modulates the colors with the alpha channel, a surface without an alpha mask needs * to be created. This makes all source pixels opaque and the colors get copied correctly. */ SDL_Surface *src_rotated_rgb; src_rotated_rgb = SDL_CreateRGBSurfaceFrom(src_rotated->pixels, src_rotated->w, src_rotated->h, src_rotated->format->BitsPerPixel, src_rotated->pitch, src_rotated->format->Rmask, src_rotated->format->Gmask, src_rotated->format->Bmask, 0); if (src_rotated_rgb == NULL) { retval = -1; } else { SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD); retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect); SDL_FreeSurface(src_rotated_rgb); } } } SDL_FreeSurface(mask_rotated); } if (src_rotated != NULL) { SDL_FreeSurface(src_rotated); } } } if (SDL_MUSTLOCK(src)) { SDL_UnlockSurface(src); } if (mask != NULL) { SDL_FreeSurface(mask); } if (src_clone != NULL) { SDL_FreeSurface(src_clone); } return retval; }
void RenderManagerSDL::init(int xResolution, int yResolution, bool fullscreen) { SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); // Set modesetting Uint32 screenFlags = 0; if (fullscreen) { screenFlags |= SDL_WINDOW_FULLSCREEN; } else { screenFlags |= SDL_WINDOW_RESIZABLE; } // Create window mWindow = SDL_CreateWindow(AppTitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, xResolution, yResolution, screenFlags); // Set icon #if !defined(MAC_OS_X) SDL_Surface* icon = loadSurface("Icon.bmp"); SDL_SetColorKey(icon, SDL_TRUE, SDL_MapRGB(icon->format, 0, 0, 0)); SDL_SetWindowIcon(mWindow, icon); SDL_FreeSurface(icon); #endif // Create renderer to draw in window mRenderer = SDL_CreateRenderer(mWindow, -1, 0); // Hide mousecursor SDL_ShowCursor(0); // Create rendertarget to make window resizeable mRenderTarget = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, xResolution, yResolution); // Load all textures and surfaces to render the game SDL_Surface* tmpSurface; // Create a 1x1 black surface which will be scaled to draw an overlay tmpSurface = SDL_CreateRGBSurface(0, 1, 1, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); // Because of SDL bug we can't check at the moment if color mod is available... no risk no fun ;) SDL_FillRect(tmpSurface, NULL, SDL_MapRGB(tmpSurface->format, 255, 255, 255)); mOverlayTexture = SDL_CreateTextureFromSurface(mRenderer, tmpSurface); SDL_FreeSurface(tmpSurface); // Create marker texture for mouse and ball tmpSurface = SDL_CreateRGBSurface(0, 5, 5, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); SDL_FillRect(tmpSurface, NULL, SDL_MapRGB(tmpSurface->format, 255, 255, 255)); mMarker[0] = SDL_CreateTextureFromSurface(mRenderer, tmpSurface); SDL_FillRect(tmpSurface, NULL, SDL_MapRGB(tmpSurface->format, 0, 0, 0)); mMarker[1] = SDL_CreateTextureFromSurface(mRenderer, tmpSurface); SDL_FreeSurface(tmpSurface); // Load background tmpSurface = loadSurface("backgrounds/strand2.bmp"); mBackground = SDL_CreateTextureFromSurface(mRenderer, tmpSurface); BufferedImage* bgImage = new BufferedImage; bgImage->w = tmpSurface->w; bgImage->h = tmpSurface->h; bgImage->sdlImage = mBackground; SDL_FreeSurface(tmpSurface); mImageMap["background"] = bgImage; // Load ball for (int i = 1; i <= 16; ++i) { char filename[64]; sprintf(filename, "gfx/ball%02d.bmp", i); tmpSurface = loadSurface(filename); SDL_SetColorKey(tmpSurface, SDL_TRUE, SDL_MapRGB(tmpSurface->format, 0, 0, 0)); SDL_Texture *ballTexture = SDL_CreateTextureFromSurface(mRenderer, tmpSurface); SDL_FreeSurface(tmpSurface); mBall.push_back(ballTexture); } // Load ball shadow tmpSurface = loadSurface("gfx/schball.bmp"); SDL_SetColorKey(tmpSurface, SDL_TRUE, SDL_MapRGB(tmpSurface->format, 0, 0, 0)); SDL_SetSurfaceAlphaMod(tmpSurface, 127); mBallShadow = SDL_CreateTextureFromSurface(mRenderer, tmpSurface); SDL_FreeSurface(tmpSurface); // Load blobby and shadows surface // Load streamed textures for coloring for (int i = 1; i <= 5; ++i) { // Load blobby surface char filename[64]; sprintf(filename, "gfx/blobbym%d.bmp", i); SDL_Surface* blobImage = loadSurface(filename); SDL_Surface* formatedBlobImage = SDL_ConvertSurfaceFormat(blobImage, SDL_PIXELFORMAT_ABGR8888, 0); SDL_FreeSurface(blobImage); SDL_SetColorKey(formatedBlobImage, SDL_TRUE, SDL_MapRGB(formatedBlobImage->format, 0, 0, 0)); for(int j = 0; j < formatedBlobImage->w * formatedBlobImage->h; j++) { SDL_Color* pixel = &(((SDL_Color*)formatedBlobImage->pixels)[j]); if (!(pixel->r | pixel->g | pixel->b)) { pixel->a = 0; } } mStandardBlob.push_back(formatedBlobImage); // Load blobby shadow surface sprintf(filename, "gfx/sch1%d.bmp", i); SDL_Surface* blobShadow = loadSurface(filename); SDL_Surface* formatedBlobShadowImage = SDL_ConvertSurfaceFormat(blobShadow, SDL_PIXELFORMAT_ABGR8888, 0); SDL_FreeSurface(blobShadow); SDL_SetSurfaceAlphaMod(formatedBlobShadowImage, 127); SDL_SetColorKey(formatedBlobShadowImage, SDL_TRUE, SDL_MapRGB(formatedBlobShadowImage->format, 0, 0, 0)); for(int j = 0; j < formatedBlobShadowImage->w * formatedBlobShadowImage->h; j++) { SDL_Color* pixel = &(((SDL_Color*)formatedBlobShadowImage->pixels)[j]); if (!(pixel->r | pixel->g | pixel->b)) { pixel->a = 0; } else { pixel->a = 127; } } mStandardBlobShadow.push_back(formatedBlobShadowImage); // Prepare blobby textures SDL_Texture* leftBlobTex = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, formatedBlobImage->w, formatedBlobImage->h); SDL_SetTextureBlendMode(leftBlobTex, SDL_BLENDMODE_BLEND); SDL_UpdateTexture(leftBlobTex, NULL, formatedBlobImage->pixels, formatedBlobImage->pitch); mLeftBlob.push_back(DynamicColoredTexture( leftBlobTex, Color(255, 255, 255))); SDL_Texture* rightBlobTex = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, formatedBlobImage->w, formatedBlobImage->h); SDL_SetTextureBlendMode(rightBlobTex, SDL_BLENDMODE_BLEND); SDL_UpdateTexture(rightBlobTex, NULL, formatedBlobImage->pixels, formatedBlobImage->pitch); mRightBlob.push_back(DynamicColoredTexture( rightBlobTex, Color(255, 255, 255))); // Prepare blobby shadow textures SDL_Texture* leftBlobShadowTex = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, formatedBlobShadowImage->w, formatedBlobShadowImage->h); SDL_SetTextureBlendMode(leftBlobShadowTex, SDL_BLENDMODE_BLEND); mLeftBlobShadow.push_back(DynamicColoredTexture( leftBlobShadowTex, Color(255, 255, 255))); SDL_UpdateTexture(leftBlobShadowTex, NULL, formatedBlobShadowImage->pixels, formatedBlobShadowImage->pitch); SDL_Texture* rightBlobShadowTex = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, formatedBlobShadowImage->w, formatedBlobShadowImage->h); SDL_SetTextureBlendMode(rightBlobShadowTex, SDL_BLENDMODE_BLEND); mRightBlobShadow.push_back(DynamicColoredTexture( rightBlobShadowTex, Color(255, 255, 255))); SDL_UpdateTexture(rightBlobShadowTex, NULL, formatedBlobShadowImage->pixels, formatedBlobShadowImage->pitch); // Load iOS specific icon (because we have no backbutton) #ifdef __APPLE__ #if !MAC_OS_X tmpSurface = loadSurface("gfx/flag.bmp"); SDL_SetColorKey(tmpSurface, SDL_TRUE, SDL_MapRGB(tmpSurface->format, 0, 0, 0)); mBackFlag = SDL_CreateTextureFromSurface(mRenderer, tmpSurface); SDL_FreeSurface(tmpSurface); #endif #endif } // Load font for (int i = 0; i <= 54; ++i) { char filename[64]; sprintf(filename, "gfx/font%02d.bmp", i); SDL_Surface* tempFont = loadSurface(filename); SDL_SetColorKey(tempFont, SDL_TRUE, SDL_MapRGB(tempFont->format, 0, 0, 0)); mFont.push_back(SDL_CreateTextureFromSurface(mRenderer, tempFont)); SDL_Surface* tempFont2 = highlightSurface(tempFont, 60); mHighlightFont.push_back(SDL_CreateTextureFromSurface(mRenderer, tempFont2)); SDL_FreeSurface(tempFont); SDL_FreeSurface(tempFont2); } // Load blood surface SDL_Surface* blobStandardBlood = loadSurface("gfx/blood.bmp"); SDL_Surface* formatedBlobStandardBlood = SDL_ConvertSurfaceFormat(blobStandardBlood, SDL_PIXELFORMAT_ABGR8888, 0); SDL_FreeSurface(blobStandardBlood); SDL_SetColorKey(formatedBlobStandardBlood, SDL_TRUE, SDL_MapRGB(formatedBlobStandardBlood->format, 0, 0, 0)); for(int j = 0; j < formatedBlobStandardBlood->w * formatedBlobStandardBlood->h; j++) { SDL_Color* pixel = &(((SDL_Color*)formatedBlobStandardBlood->pixels)[j]); if (!(pixel->r | pixel->g | pixel->b)) { pixel->a = 0; } else { pixel->a = 255; } } mStandardBlobBlood = formatedBlobStandardBlood; // Create streamed textures for blood SDL_Texture* leftBlobBlood = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, formatedBlobStandardBlood->w, formatedBlobStandardBlood->h); SDL_SetTextureBlendMode(leftBlobBlood, SDL_BLENDMODE_BLEND); mLeftBlobBlood = DynamicColoredTexture( leftBlobBlood, Color(255, 0, 0)); SDL_UpdateTexture(leftBlobBlood, NULL, formatedBlobStandardBlood->pixels, formatedBlobStandardBlood->pitch); SDL_Texture* rightBlobBlood = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, formatedBlobStandardBlood->w, formatedBlobStandardBlood->h); SDL_SetTextureBlendMode(rightBlobBlood, SDL_BLENDMODE_BLEND); mRightBlobBlood = DynamicColoredTexture( rightBlobBlood, Color(255, 0, 0)); SDL_UpdateTexture(rightBlobBlood, NULL, formatedBlobStandardBlood->pixels, formatedBlobStandardBlood->pitch); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); }
/** * \brief Sets the opacity of this surface. * \param opacity the opacity (0 to 255). */ void Surface::set_opacity(int opacity) { SDL_SetSurfaceBlendMode(internal_surface, SDL_BLENDMODE_BLEND); SDL_SetSurfaceAlphaMod(internal_surface, opacity); }
GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord) { GLuint texture; int w, h; SDL_Surface *image; SDL_Rect area; Uint8 saved_alpha; SDL_BlendMode saved_mode; /* Use the surface width and height expanded to powers of 2 */ w = power_of_two(surface->w); h = power_of_two(surface->h); texcoord[0] = 0.0f; /* Min X */ texcoord[1] = 0.0f; /* Min Y */ texcoord[2] = (GLfloat)surface->w / w; /* Max X */ texcoord[3] = (GLfloat)surface->h / h; /* Max Y */ image = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); if ( image == NULL ) { return 0; } /* Save the alpha blending attributes */ SDL_GetSurfaceAlphaMod(surface, &saved_alpha); SDL_SetSurfaceAlphaMod(surface, 0xFF); SDL_GetSurfaceBlendMode(surface, &saved_mode); SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); /* Copy the surface into the GL texture image */ area.x = 0; area.y = 0; area.w = surface->w; area.h = surface->h; SDL_BlitSurface(surface, &area, image, &area); /* Restore the alpha blending attributes */ SDL_SetSurfaceAlphaMod(surface, saved_alpha); SDL_SetSurfaceBlendMode(surface, saved_mode); /* Create an OpenGL texture for the image */ glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); SDL_FreeSurface(image); /* No longer needed */ return texture; }
SDL_Surface *MobileOpenGLScreenshotHelper::getScreenshot() { const int h = mainGraphics->mHeight; const int w = mainGraphics->mWidth - (mainGraphics->mWidth % 4); GLint pack = 1; SDL_Surface *const tmpImage = MSDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); if (tmpImage == nullptr) return nullptr; // Grap the pixel buffer and write it to the SDL surface mglGetIntegerv(GL_PACK_ALIGNMENT, &pack); mglPixelStorei(GL_PACK_ALIGNMENT, 1); mglReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels); const size_t lineSize = 3 * w; GLubyte *const buf = new GLubyte[lineSize]; SDL_Surface *const screenshot = MSDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000); if (screenshot == nullptr) { MSDL_FreeSurface(tmpImage); delete [] buf; return nullptr; } #ifdef USE_SDL2 SDL_SetSurfaceAlphaMod(tmpImage, SDL_ALPHA_OPAQUE); SDL_SetSurfaceBlendMode(tmpImage, SDL_BLENDMODE_NONE); #else // USE_SDL2 // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); #endif // USE_SDL2 if (SDL_MUSTLOCK(screenshot)) SDL_LockSurface(screenshot); SDL_BlitSurface(tmpImage, nullptr, screenshot, nullptr); MSDL_FreeSurface(tmpImage); // Flip the screenshot, as OpenGL has 0,0 in bottom left const int h2 = h / 2; for (int i = 0; i < h2; i++) { GLubyte *const top = static_cast<GLubyte*>( screenshot->pixels) + lineSize * i; GLubyte *const bot = static_cast<GLubyte*>( screenshot->pixels) + lineSize * (h - 1 - i); memcpy(buf, top, lineSize); memcpy(top, bot, lineSize); memcpy(bot, buf, lineSize); } delete [] buf; if (config.getBoolValue("usefbo")) graphicsManager.deleteFBO(&mFbo); mglPixelStorei(GL_PACK_ALIGNMENT, pack); if (SDL_MUSTLOCK(screenshot)) SDL_UnlockSurface(screenshot); return screenshot; }
static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; SDL_Rect final_rect, tmp_rect; SDL_Surface *surface_rotated, *surface_scaled; int retval, dstwidth, dstheight, abscenterx, abscentery; double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; if (!surface) { return -1; } if (renderer->viewport.x || renderer->viewport.y) { final_rect.x = (int)(renderer->viewport.x + dstrect->x); final_rect.y = (int)(renderer->viewport.y + dstrect->y); } else { final_rect.x = (int)dstrect->x; final_rect.y = (int)dstrect->y; } final_rect.w = (int)dstrect->w; final_rect.h = (int)dstrect->h; /* SDLgfx_rotateSurface doesn't accept a source rectangle, so crop and scale if we need to */ tmp_rect = final_rect; tmp_rect.x = 0; tmp_rect.y = 0; if (srcrect->w == final_rect.w && srcrect->h == final_rect.h && srcrect->x == 0 && srcrect->y == 0) { surface_scaled = src; /* but if we don't need to, just use the original */ retval = 0; } else { SDL_Surface *blit_src = src; Uint32 colorkey; SDL_BlendMode blendMode; Uint8 alphaMod, r, g, b; SDL_bool cloneSource = SDL_FALSE; surface_scaled = SDL_CreateRGBSurface(SDL_SWSURFACE, final_rect.w, final_rect.h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask ); if (!surface_scaled) { return -1; } /* copy the color key, alpha mod, blend mode, and color mod so the scaled surface behaves like the source */ if (SDL_GetColorKey(src, &colorkey) == 0) { SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey); cloneSource = SDL_TRUE; } SDL_GetSurfaceAlphaMod(src, &alphaMod); /* these will be copied to surface_scaled below if necessary */ SDL_GetSurfaceBlendMode(src, &blendMode); SDL_GetSurfaceColorMod(src, &r, &g, &b); /* now we need to blit the src into surface_scaled. since we want to copy the colors from the source to * surface_scaled rather than blend them, etc. we'll need to disable the blend mode, alpha mod, etc. * but we don't want to modify src (in case it's being used on other threads), so we'll need to clone it * before changing the blend options */ cloneSource |= blendMode != SDL_BLENDMODE_NONE || (alphaMod & r & g & b) != 255; if (cloneSource) { blit_src = SDL_ConvertSurface(src, src->format, src->flags); /* clone src */ if (!blit_src) { SDL_FreeSurface(surface_scaled); return -1; } SDL_SetSurfaceAlphaMod(blit_src, 255); /* disable all blending options in blit_src */ SDL_SetSurfaceBlendMode(blit_src, SDL_BLENDMODE_NONE); SDL_SetColorKey(blit_src, 0, 0); SDL_SetSurfaceColorMod(blit_src, 255, 255, 255); SDL_SetSurfaceRLE(blit_src, 0); /* don't RLE encode a surface we'll only use once */ SDL_SetSurfaceAlphaMod(surface_scaled, alphaMod); /* copy blending options to surface_scaled */ SDL_SetSurfaceBlendMode(surface_scaled, blendMode); SDL_SetSurfaceColorMod(surface_scaled, r, g, b); } retval = SDL_BlitScaled(blit_src, srcrect, surface_scaled, &tmp_rect); if (blit_src != src) { SDL_FreeSurface(blit_src); } } if (!retval) { SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle); surface_rotated = SDLgfx_rotateSurface(surface_scaled, angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); if(surface_rotated) { /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ abscenterx = final_rect.x + (int)center->x; abscentery = final_rect.y + (int)center->y; /* Compensate the angle inversion to match the behaviour of the other backends */ sangle = -sangle; /* Top Left */ px = final_rect.x - abscenterx; py = final_rect.y - abscentery; p1x = px * cangle - py * sangle + abscenterx; p1y = px * sangle + py * cangle + abscentery; /* Top Right */ px = final_rect.x + final_rect.w - abscenterx; py = final_rect.y - abscentery; p2x = px * cangle - py * sangle + abscenterx; p2y = px * sangle + py * cangle + abscentery; /* Bottom Left */ px = final_rect.x - abscenterx; py = final_rect.y + final_rect.h - abscentery; p3x = px * cangle - py * sangle + abscenterx; p3y = px * sangle + py * cangle + abscentery; /* Bottom Right */ px = final_rect.x + final_rect.w - abscenterx; py = final_rect.y + final_rect.h - abscentery; p4x = px * cangle - py * sangle + abscenterx; p4y = px * sangle + py * cangle + abscentery; tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x)); tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y)); tmp_rect.w = dstwidth; tmp_rect.h = dstheight; retval = SDL_BlitSurface(surface_rotated, NULL, surface, &tmp_rect); SDL_FreeSurface(surface_rotated); } } if (surface_scaled != src) { SDL_FreeSurface(surface_scaled); } return retval; }
int loadFonts() { TTF_Font *font = NULL; SDL_Surface *fontSurface = NULL; SDL_Surface *tmp = NULL; Uint32 saved_flags; Uint8 saved_alpha; static SDL_Color fontColour = {255,255,255}; char letter[2]; int i; char *p; letter[1] = 0; p = findFile(va("%s/%s", MISCDIR, video.fontFile)); if (!p) { conAdd(LERR, "Could not open font"); return 0; } font = TTF_OpenFont(p, video.fontSize); if (!font) { conAdd(LERR, "Could not open %s", p); return 0; } TTF_SetFontStyle(font, TTF_STYLE_NORMAL); #ifdef TTF_HINTING_NORMAL TTF_SetFontHinting(font, TTF_HINTING_NORMAL); #endif memset(fonts, 0, sizeof(fonts)); fontHeight = 0; for (i = 32; i < 128; i++) { letter[0] = i; fontSurface = TTF_RenderText_Blended(font, letter, fontColour); if (!fontSurface) { #ifdef WIN32 MessageBox(NULL, TTF_GetError(), "gravit: font engine error", MB_OK); #else printf("%s\n", TTF_GetError()); #endif TTF_CloseFont(font); return 0; } fonts[i].ow = fontSurface->w; fonts[i].oh = fontSurface->h; if (fonts[i].oh > fontHeight) fontHeight = (float)fonts[i].oh; fonts[i].w = gfxPowerOfTwo(fonts[i].ow); fonts[i].h = gfxPowerOfTwo(fonts[i].oh); if (fonts[i].w > fonts[i].h) fonts[i].h = fonts[i].w; if (fonts[i].h > fonts[i].w) fonts[i].w = fonts[i].h; tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, fonts[i].w, fonts[i].h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks depend on byteorder */ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); #endif if (!tmp) { TTF_CloseFont(font); SDL_FreeSurface(fontSurface); return 0; } /* Save the alpha blending attributes */ saved_flags = fontSurface->flags & (SDL_SRCALPHA|SDL_RLEACCELOK); #if SDL_VERSION_ATLEAST(1, 3, 0) SDL_GetSurfaceAlphaMod(fontSurface, &saved_alpha); SDL_SetSurfaceAlphaMod(fontSurface, 0xFF); #else saved_alpha = fontSurface->format->alpha; if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { SDL_SetAlpha(fontSurface, 0, 0); } #endif /* copy to texture surface */ if (SDL_BlitSurface(fontSurface, NULL, tmp, NULL)) { TTF_CloseFont(font); SDL_FreeSurface(tmp); SDL_FreeSurface(fontSurface); return 0; } glGenTextures(1, &fonts[i].id); glCheck(); glBindTexture(GL_TEXTURE_2D, fonts[i].id); glCheck(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fonts[i].w, fonts[i].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp->pixels); glCheck(); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glCheck(); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glCheck(); SDL_FreeSurface(tmp); SDL_FreeSurface(fontSurface); } TTF_CloseFont(font); return 1; }
/** * @brief Tests some more blitting routines. */ static void surface_testBlitBlend( SDL_Surface *testsur ) { int ret; SDL_Rect rect; SDL_Surface *face; int i, j, ni, nj; int mode; SDL_ATbegin( "Blit Blending Tests" ); /* Clear surface. */ ret = SDL_FillRect( testsur, NULL, SDL_MapRGB( testsur->format, 0, 0, 0 ) ); if (SDL_ATassert( "SDL_FillRect", ret == 0)) return; /* Create the blit surface. */ face = SDL_CreateRGBSurfaceFrom( (void*)img_face.pixel_data, img_face.width, img_face.height, 32, img_face.width*4, RMASK, GMASK, BMASK, AMASK ); if (SDL_ATassert( "SDL_CreateRGBSurfaceFrom", face != NULL)) return; /* Set alpha mod. */ ret = SDL_SetSurfaceAlphaMod( face, 100 ); if (SDL_ATassert( "SDL_SetSurfaceAlphaMod", ret == 0)) return; /* Steps to take. */ ni = testsur->w - face->w; nj = testsur->h - face->h; /* Constant values. */ rect.w = face->w; rect.h = face->h; /* Test None. */ if (surface_testBlitBlendMode( testsur, face, SDL_BLENDMODE_NONE )) return; if (SDL_ATassert( "Blitting blending output not the same (using SDL_BLENDMODE_NONE).", surface_compare( testsur, &img_blendNone )==0 )) return; /* Test Mask. */ if (surface_testBlitBlendMode( testsur, face, SDL_BLENDMODE_MASK )) return; if (SDL_ATassert( "Blitting blending output not the same (using SDL_BLENDMODE_MASK).", surface_compare( testsur, &img_blendMask )==0 )) return; /* Test Blend. */ if (surface_testBlitBlendMode( testsur, face, SDL_BLENDMODE_BLEND )) return; if (SDL_ATassert( "Blitting blending output not the same (using SDL_BLENDMODE_BLEND).", surface_compare( testsur, &img_blendBlend )==0 )) return; /* Test Add. */ if (surface_testBlitBlendMode( testsur, face, SDL_BLENDMODE_ADD )) return; if (SDL_ATassert( "Blitting blending output not the same (using SDL_BLENDMODE_ADD).", surface_compare( testsur, &img_blendAdd )==0 )) return; /* Test Mod. */ if (surface_testBlitBlendMode( testsur, face, SDL_BLENDMODE_MOD )) return; if (SDL_ATassert( "Blitting blending output not the same (using SDL_BLENDMODE_MOD).", surface_compare( testsur, &img_blendMod )==0 )) return; /* Clear surface. */ ret = SDL_FillRect( testsur, NULL, SDL_MapRGB( testsur->format, 0, 0, 0 ) ); if (SDL_ATassert( "SDL_FillRect", ret == 0)) return; /* Loop blit. */ for (j=0; j <= nj; j+=4) { for (i=0; i <= ni; i+=4) { /* Set colour mod. */ ret = SDL_SetSurfaceColorMod( face, (255/nj)*j, (255/ni)*i, (255/nj)*j ); if (SDL_ATassert( "SDL_SetSurfaceColorMod", ret == 0)) return; /* Set alpha mod. */ ret = SDL_SetSurfaceAlphaMod( face, (100/ni)*i ); if (SDL_ATassert( "SDL_SetSurfaceAlphaMod", ret == 0)) return; /* Crazy blending mode magic. */ mode = (i/4*j/4) % 4; if (mode==0) mode = SDL_BLENDMODE_MASK; else if (mode==1) mode = SDL_BLENDMODE_BLEND; else if (mode==2) mode = SDL_BLENDMODE_ADD; else if (mode==3) mode = SDL_BLENDMODE_MOD; ret = SDL_SetSurfaceBlendMode( face, mode ); if (SDL_ATassert( "SDL_SetSurfaceBlendMode", ret == 0)) return; /* Blitting. */ rect.x = i; rect.y = j; ret = SDL_BlitSurface( face, NULL, testsur, &rect ); if (SDL_ATassert( "SDL_BlitSurface", ret == 0)) return; } } /* Check to see if matches. */ if (SDL_ATassert( "Blitting blending output not the same (using SDL_BLEND_*).", surface_compare( testsur, &img_blendAll )==0 )) return; /* Clean up. */ SDL_FreeSurface( face ); SDL_ATend(); }
/** * @brief Tests some blitting routines. */ static void surface_testBlit( SDL_Surface *testsur ) { int ret; SDL_Rect rect; SDL_Surface *face; int i, j, ni, nj; SDL_ATbegin( "Blit Tests" ); /* Clear surface. */ ret = SDL_FillRect( testsur, NULL, SDL_MapRGB( testsur->format, 0, 0, 0 ) ); if (SDL_ATassert( "SDL_FillRect", ret == 0)) return; /* Create face surface. */ face = SDL_CreateRGBSurfaceFrom( (void*)img_face.pixel_data, img_face.width, img_face.height, 32, img_face.width*4, RMASK, GMASK, BMASK, AMASK ); if (SDL_ATassert( "SDL_CreateRGBSurfaceFrom", face != NULL)) return; /* Constant values. */ rect.w = face->w; rect.h = face->h; ni = testsur->w - face->w; nj = testsur->h - face->h; /* Loop blit. */ for (j=0; j <= nj; j+=4) { for (i=0; i <= ni; i+=4) { /* Blitting. */ rect.x = i; rect.y = j; ret = SDL_BlitSurface( face, NULL, testsur, &rect ); if (SDL_ATassert( "SDL_BlitSurface", ret == 0)) return; } } /* See if it's the same. */ if (SDL_ATassert( "Blitting output not the same (normal blit).", surface_compare( testsur, &img_blit )==0 )) return; /* Clear surface. */ ret = SDL_FillRect( testsur, NULL, SDL_MapRGB( testsur->format, 0, 0, 0 ) ); if (SDL_ATassert( "SDL_FillRect", ret == 0)) return; /* Test blitting with colour mod. */ for (j=0; j <= nj; j+=4) { for (i=0; i <= ni; i+=4) { /* Set colour mod. */ ret = SDL_SetSurfaceColorMod( face, (255/nj)*j, (255/ni)*i, (255/nj)*j ); if (SDL_ATassert( "SDL_SetSurfaceColorMod", ret == 0)) return; /* Blitting. */ rect.x = i; rect.y = j; ret = SDL_BlitSurface( face, NULL, testsur, &rect ); if (SDL_ATassert( "SDL_BlitSurface", ret == 0)) return; } } /* See if it's the same. */ if (SDL_ATassert( "Blitting output not the same (using SDL_SetSurfaceColorMod).", surface_compare( testsur, &img_blitColour )==0 )) return; /* Clear surface. */ ret = SDL_FillRect( testsur, NULL, SDL_MapRGB( testsur->format, 0, 0, 0 ) ); if (SDL_ATassert( "SDL_FillRect", ret == 0)) return; /* Restore colour. */ ret = SDL_SetSurfaceColorMod( face, 255, 255, 255 ); if (SDL_ATassert( "SDL_SetSurfaceColorMod", ret == 0)) return; /* Test blitting with colour mod. */ for (j=0; j <= nj; j+=4) { for (i=0; i <= ni; i+=4) { /* Set alpha mod. */ ret = SDL_SetSurfaceAlphaMod( face, (255/ni)*i ); if (SDL_ATassert( "SDL_SetSurfaceAlphaMod", ret == 0)) return; /* Blitting. */ rect.x = i; rect.y = j; ret = SDL_BlitSurface( face, NULL, testsur, &rect ); if (SDL_ATassert( "SDL_BlitSurface", ret == 0)) return; } } /* See if it's the same. */ if (SDL_ATassert( "Blitting output not the same (using SDL_SetSurfaceAlphaMod).", surface_compare( testsur, &img_blitAlpha )==0 )) return; /* Clean up. */ SDL_FreeSurface( face ); SDL_ATend(); }
SDL_Surface *OpenGLImageHelper::convertSurfaceNormalize(SDL_Surface *tmpImage, int width, int height) { if (!tmpImage) return nullptr; int realWidth = powerOfTwo(width); int realHeight = powerOfTwo(height); if (realWidth < width || realHeight < height) { reportAlways("Warning: image too large, cropping to %dx%d texture!", tmpImage->w, tmpImage->h); } #ifdef USE_SDL2 SDL_SetSurfaceAlphaMod(tmpImage, SDL_ALPHA_OPAQUE); #else // USE_SDL2 // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); #endif // USE_SDL2 // Determine 32-bit masks based on byte order uint32_t rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else // SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN if (tmpImage->format->BitsPerPixel != 32 || realWidth != width || realHeight != height || rmask != tmpImage->format->Rmask || gmask != tmpImage->format->Gmask || amask != tmpImage->format->Amask) { SDL_Surface *oldImage = tmpImage; #ifdef USE_SDL2 SDL_SetSurfaceBlendMode(oldImage, SDL_BLENDMODE_NONE); #endif // USE_SDL2 tmpImage = MSDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, 32, rmask, gmask, bmask, amask); if (!tmpImage) { reportAlways("Error, image convert failed: out of memory"); return nullptr; } SDL_BlitSurface(oldImage, nullptr, tmpImage, nullptr); } return tmpImage; }
/** * Helper that blits in a specific blend mode, -1 for basic blitting, -2 for color mod, -3 for alpha mod, -4 for mixed blend modes. */ void _testBlitBlendMode(int mode) { int ret; int i, j, ni, nj; SDL_Surface *face; SDL_Rect rect; int nmode; SDL_BlendMode bmode; int checkFailCount1; int checkFailCount2; int checkFailCount3; int checkFailCount4; /* Check test surface */ SDLTest_AssertCheck(testSurface != NULL, "Verify testSurface is not NULL"); if (testSurface == NULL) return; /* Create sample surface */ face = SDLTest_ImageFace(); SDLTest_AssertCheck(face != NULL, "Verify face surface is not NULL"); if (face == NULL) return; /* Reset alpha modulation */ ret = SDL_SetSurfaceAlphaMod(face, 255); SDLTest_AssertPass("Call to SDL_SetSurfaceAlphaMod()"); SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceAlphaMod(), expected: 0, got: %i", ret); /* Reset color modulation */ ret = SDL_SetSurfaceColorMod(face, 255, 255, 255); SDLTest_AssertPass("Call to SDL_SetSurfaceColorMod()"); SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceColorMod(), expected: 0, got: %i", ret); /* Reset color key */ ret = SDL_SetColorKey(face, SDL_FALSE, 0); SDLTest_AssertPass("Call to SDL_SetColorKey()"); SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetColorKey(), expected: 0, got: %i", ret); /* Clear the test surface */ _clearTestSurface(); /* Target rect size */ rect.w = face->w; rect.h = face->h; /* Steps to take */ ni = testSurface->w - face->w; nj = testSurface->h - face->h; /* Optionally set blend mode. */ if (mode >= 0) { ret = SDL_SetSurfaceBlendMode( face, (SDL_BlendMode)mode ); SDLTest_AssertPass("Call to SDL_SetSurfaceBlendMode()"); SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceBlendMode(..., %i), expected: 0, got: %i", mode, ret); } /* Test blend mode. */ checkFailCount1 = 0; checkFailCount2 = 0; checkFailCount3 = 0; checkFailCount4 = 0; for (j=0; j <= nj; j+=4) { for (i=0; i <= ni; i+=4) { if (mode == -2) { /* Set color mod. */ ret = SDL_SetSurfaceColorMod( face, (255/nj)*j, (255/ni)*i, (255/nj)*j ); if (ret != 0) checkFailCount2++; } else if (mode == -3) { /* Set alpha mod. */ ret = SDL_SetSurfaceAlphaMod( face, (255/ni)*i ); if (ret != 0) checkFailCount3++; } else if (mode == -4) { /* Crazy blending mode magic. */ nmode = (i/4*j/4) % 4; if (nmode==0) { bmode = SDL_BLENDMODE_NONE; } else if (nmode==1) { bmode = SDL_BLENDMODE_BLEND; } else if (nmode==2) { bmode = SDL_BLENDMODE_ADD; } else if (nmode==3) { bmode = SDL_BLENDMODE_MOD; } ret = SDL_SetSurfaceBlendMode( face, bmode ); if (ret != 0) checkFailCount4++; } /* Blitting. */ rect.x = i; rect.y = j; ret = SDL_BlitSurface( face, NULL, testSurface, &rect ); if (ret != 0) checkFailCount1++; } } SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_BlitSurface, expected: 0, got: %i", checkFailCount1); SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetSurfaceColorMod, expected: 0, got: %i", checkFailCount2); SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_SetSurfaceAlphaMod, expected: 0, got: %i", checkFailCount3); SDLTest_AssertCheck(checkFailCount4 == 0, "Validate results from calls to SDL_SetSurfaceBlendMode, expected: 0, got: %i", checkFailCount4); /* Clean up */ SDL_FreeSurface(face); face = NULL; }
int inline Surface::setAlphaMod(State & state, SDL_Surface * surface){ SDL_SetSurfaceAlphaMod(surface, (Uint8)state.stack->to<int>(1)); return 0; }
static int SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) { SDL_Surface *surface = (SDL_Surface *) texture->driverdata; return SDL_SetSurfaceAlphaMod(surface, texture->a); }
void SDL_TMXMap::Populate_Map(SDL_Renderer *Render) { if( MapSurf || getMapFile().length()) { if (!MapSurf) { std::ifstream *in_xml = new ifstream(getMapFile().c_str(), ifstream::in); if(!in_xml->is_open()) { std::cout << "No way to Populate Map. Quitting..." <<endl; return; } std::stringstream *ss_xml = new std::stringstream; *ss_xml << in_xml->rdbuf(); char *xml_data = new char[ss_xml->str().length()+1](); strcpy(xml_data, ss_xml->str().c_str()); in_xml->close(); delete ss_xml; Load_Map(xml_data); MapSurf = SDL_CreateRGBSurface(0, getWidth()*getTileWidth(), getHeight()*getTileHeight(), 32, rmask, gmask, bmask, amask); } string ResDir = "Resources\\"; SDL_Surface **TileSurf = new SDL_Surface*[getNumTilesets()]; for ( unsigned int fn = 0; fn < getNumTilesets(); fn++) { //eventually, there will be a means to load multiple images per tileset. TODO: Make a loop that allows it. //TODO: Write it so that it also works with string Filenname = ResDir + getTileset(fn).getImage(0).getFilename(); TileSurf[fn] = IMG_Load(Filenname.c_str()); if (!TileSurf[fn]) return; } unsigned long color = getTileset(0).getImage(0).getTrans(); SDL_Color CKey; CKey.r = (color & 0xFF0000) >> 16; CKey.g = (color & 0x00FF00) >> 8 ; CKey.b = (color & 0x0000FF) ; SDL_SetColorKey( MapSurf , SDL_TRUE , SDL_MapRGB(TileSurf[0]->format , CKey.r , CKey.g , CKey.b)); SDL_Rect SrcRect; SDL_Rect DstRect; DstRect.h = getTileHeight(); DstRect.w = getTileWidth(); unsigned char **in_data = new unsigned char* [getNumLayers()]; unsigned char **out_data = new unsigned char* [getNumLayers()]; unsigned int **tiledata = (unsigned int **) out_data; for(unsigned i = 0; i < getNumLayers(); i++) { in_data[i] = new unsigned char [getLayer(i).getData().getData().size()]; out_data[i] = new unsigned char [getWidth()*getHeight()*4]; memcpy( in_data[i] , getLayer(i).getData().getData().c_str() , getLayer(i).getData().getData().size() ); unsigned char *dec_data = new unsigned char[( getLayer(i).getData().getData().size())]; TMX_Decode( in_data[i] , dec_data , getLayer(i).getData().getData().size() ); TMX_Uncompress( dec_data , out_data[i] , ( getLayer(i).getData().getData().size() ), getWidth() * getHeight() * 4, getLayer(i).getData().getCompression().c_str()); } delete[]in_data; for (unsigned l = 0; l < TMX_Map::getNumLayers(); l++) { LayerSurf.push_back(SDL_CreateRGBSurface(0, getWidth()*getTileWidth(), getHeight()*getTileHeight(), 32, rmask, gmask, bmask, amask)); SDL_SetSurfaceAlphaMod(LayerSurf[l], getLayer(l).getOpacity() * 255); for(unsigned int y = 0; y < getHeight(); y++) { DstRect.y = y * getTileHeight(); for (unsigned int x = 0; x < getWidth(); x++) { if(tiledata[l][y*getWidth()+x]) { DstRect.x = x * getTileWidth(); unsigned tilesetindex = findTileset(tiledata[l][y*getWidth()+x]); unsigned srcindex = tiledata[l][y*getWidth()+x] - getTileset(tilesetindex).getGID(); SrcRect.h = getTileset(tilesetindex).getTileHeight(); SrcRect.w = getTileset(tilesetindex).getTileWidth(); float Float_TPL = (float) getTileset(tilesetindex).getImage(0).getWidth() / (getTileset(tilesetindex).getTileWidth() + getTileset(tilesetindex).getSpacing()); unsigned long Tiles_Per_Line = (long) ceil(Float_TPL); SrcRect.x = srcindex % Tiles_Per_Line * (getTileset(tilesetindex).getTileWidth() + getTileset(tilesetindex).getSpacing()); SrcRect.y = srcindex / Tiles_Per_Line * (getTileset(tilesetindex).getTileWidth() + getTileset(tilesetindex).getSpacing()); if( SDL_BlitSurface(TileSurf[tilesetindex], &SrcRect, LayerSurf[l], &DstRect) ) { cout << "SDL_BlitSurface Failed: " << SDL_GetError() << endl; // if for some reason the application does not implode and instead run this code, we need to know why it crapped us. exit (-2); } } } } if(getLayer(l).isVisible()) SDL_BlitSurface(LayerSurf[l],NULL, MapSurf, NULL); } delete[] tiledata; for (unsigned l = 0; l < getNumTilesets(); l++) SDL_FreeSurface(TileSurf[l]); MapTex = SDL_CreateTextureFromSurface(Render, MapSurf); SDL_FreeSurface(MapSurf); } else std::cout << "No way to Populate Map. Quitting..." << endl;