static void set_pixel(SDL_Surface *surface, int x, int y, Uint8 r2, Uint8 g2, Uint8 b2, Uint8 a2) { if(x<0 || y<0 || x>=surface->w || y>=surface->h) { return; } void *target_pixel = ((Uint8*)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel); Uint8 r1,g1,b1,a1; switch(surface->format->BytesPerPixel) { case 2: { SDL_GetRGBA(*(Uint16 *)target_pixel, surface->format, &r1, &g1, &b1, &a1); *(Uint16 *)target_pixel = SDL_MapRGBA(surface->format, (r1*(0xff-a2)/0xff) + (r2*a2/0xff), (g1*(0xff-a2)/0xff) + (g2*a2/0xff), (b1*(0xff-a2)/0xff) + (b2*a2/0xff), a2 + a1*(0xff-a2)/0xff ); break; } case 4: { SDL_GetRGBA(*(Uint32 *)target_pixel, surface->format, &r1, &g1, &b1, &a1); *(Uint32 *)target_pixel = SDL_MapRGBA(surface->format, (r1*(0xff-a2)/0xff) + (r2*a2/0xff), (g1*(0xff-a2)/0xff) + (g2*a2/0xff), (b1*(0xff-a2)/0xff) + (b2*a2/0xff), a2 + a1*(0xff-a2)/0xff ); break; } } }
inline void blend(void *pixel, SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { Uint8 old_r, old_g, old_b, old_a; Uint8 new_r, new_g, new_b, new_a; switch(fmt->BytesPerPixel) { case 1: SDL_GetRGBA(*(Uint8*)pixel,fmt,&old_r,&old_g,&old_b,&old_a); break; case 2: SDL_GetRGBA(*(Uint16*)pixel,fmt,&old_r,&old_g,&old_b,&old_a); break; case 3: { Uint32 buffer; buffer = ((Uint8*)pixel)[0] | (((Uint8*)pixel)[1] << 8) | (((Uint8*)pixel)[2] << 16); SDL_GetRGBA(buffer,fmt,&old_r,&old_g,&old_b,&old_a); } break; case 4: SDL_GetRGBA(*(Uint32*)pixel,fmt,&old_r,&old_g,&old_b,&old_a); break; } new_r = (Uint8) ((((Uint32)old_r << 8) + ((Uint32)r * a)) / (256 + a)); new_g = (Uint8) ((((Uint32)old_g << 8) + ((Uint32)g * a)) / (256 + a)); new_b = (Uint8) ((((Uint32)old_b << 8) + ((Uint32)b * a)) / (256 + a)); new_a = a + old_a; Uint32 new_color = SDL_MapRGBA(fmt,new_r,new_g,new_b,new_a); switch(fmt->BytesPerPixel) { case 1: *(Uint8*)pixel = (Uint8)new_color; break; case 2: *(Uint16*)pixel = (Uint16)new_color; break; case 3: { ((Uint8*)pixel)[0] = new_color; ((Uint8*)pixel)[1] = new_color >> 8; ((Uint8*)pixel)[2] = new_color >> 16; } break; case 4: *(Uint32*)pixel = (Uint32)new_color; break; } }
// Create a surface which has the RGB values of the base surface and the Alpha values made from an average between the RGB values of the alpha mask surface // Both input surfaces must have the same dimensions extern SDL_Surface *TransferAlpha( SDL_Surface *base, SDL_Surface *alpha ) { SDL_Surface *_outsurf = SDL_CreateRGBSurface(SDL_SWSURFACE,base->w,base->h,base->format->BitsPerPixel,base->format->Rmask,base->format->Gmask,base->format->Bmask,base->format->Amask); SDL_Surface *outsurf = SDL_DisplayFormatAlpha(_outsurf); SDL_FreeSurface(_outsurf); long int pix, piy; Uint32 pxx, pxx2, pxx3; Uint8 R,G,B,A; Uint8 A1,A2,A3,A4,A5; SDL_LockSurface(outsurf); SDL_LockSurface(base); SDL_LockSurface(alpha); pix = 0; piy = 0; while ( (pix < outsurf->w) && (piy < outsurf->h) ) { pxx = getpixel(base,pix,piy); pxx2 = getpixel(alpha,pix,piy); SDL_GetRGBA(pxx,base->format,&R,&G,&B,&A5); SDL_GetRGBA(pxx2,alpha->format,&A1,&A2,&A3,&A4); A = (A1/3)+(A2/3)+(A3/3); A = (int)((((float)A/255.0*(float)A4)/255.0)*(float)A5); pxx3 = SDL_MapRGBA(outsurf->format,R,G,B,A); putpixel(outsurf,pix,piy,pxx3); pix++; if ( pix < outsurf->w ) continue; pix = 0; piy++; } SDL_UnlockSurface(outsurf); SDL_UnlockSurface(base); SDL_UnlockSurface(alpha); return outsurf; }
/** * \fn int collisionSurfaceWithMap(SDL_Surface* pSurfaceMap, SDL_Surface* pSurfaceMotion, enum DIRECTION* pDirection) * \brief Detecte s'il y a collision entre deux surfaces selon le sens de déplacement du worms. * * \param[in] pSurfaceMap, pointer to the surface of the map. * \param[in] pSurfaceMotion, pointer to the surface in motion. * \param[in] pDirection, pointer to the object direction. * \returns int, indicateur de collision : 1 = collision, 0 sinon */ int collisionSurfaceWithMap(SDL_Surface* pSurfaceMap, SDL_Surface* pSurfaceMotion, enum DIRECTION* pDirection, int checkMode) { //Variables d'acquisitions Uint32 pixelS1 = 0; //Variable stockant le pixel en cours de lecture de la surface de la map Uint8 rS1 = 0, gS1 = 0, bS1 = 0, aS1 = 0; //Variables stockant les informations sur les couleurs du pixel lu de la surface de la map Uint32 pixelS2 = 0; //Variable stockant le pixel en cours de lecture de la surface en mouvement Uint8 rS2 = 0, gS2 = 0, bS2 = 0, aS2 = 0; //Variables stockant les informations sur les couleurs du pixel lu de la surface en mouvement int offset_xS2 = pSurfaceMotion->clip_rect.x; //Offset en x de la surface en mouvement dans la map int offset_yS2 = pSurfaceMotion->clip_rect.y; //Offset en y de la surface en mouvement dans la map SDL_PixelFormat* formatS1 = pSurfaceMap->format; //Pointeur du format de pixels de la surface de la map SDL_PixelFormat* formatS2 = pSurfaceMotion->format; //Pointeur du format de pixels de la surface en mouvement //Variables de balayage int x = 0, y = 0; //Variables de balayage des x, y int xStart = pSurfaceMotion->clip_rect.x, xEnd = pSurfaceMotion->clip_rect.x + pSurfaceMotion->clip_rect.w, xInc = 1; //Variables de début, de fin et d'incrément du balayage des x int yStart = pSurfaceMotion->clip_rect.y, yEnd = pSurfaceMotion->clip_rect.y + pSurfaceMotion->clip_rect.h, yInc = 1; //Variables de début, de fin et d'incrément du balayage des y int zone[4] = { 0, 0, 0, 0 }, balayageGen = 0; //Variable de collision int collision = 0; //Booleen de collision, 0 = pas de collision, 1 = collision /*Test des limites de la map et de la fenetre*/ if (collisionSurfaceWithMapLimits(pSurfaceMap, pSurfaceMotion)) //Detection d'un dépassement de la map return 1; /*Détermination de l'ordre des zones à balayer*/ calculOrdreBalayage(*pDirection, zone); for (balayageGen = 0; (balayageGen < 4) && (collision == 0); balayageGen += 1) { /*Détermination de yStart, yEnd, xStart et xEnd*/ calculXYBalayage(pSurfaceMotion, &xStart, &xEnd, &yStart, &yEnd, zone[balayageGen]); //Calcul des valeurs de balayage des boucles for pour optimiser la vitesse de traitement /*Calcul de la collision*/ for (y = yStart; (y < yEnd) && (collision == 0); y += yInc) { for (x = xStart; (x < xEnd) && (collision == 0); x += xInc) { /*Acquisition des pixels des surfaces 1 et 2*/ pixelS1 = ReadPixel(pSurfaceMap, MY_ABS(x), MY_ABS(y)); //Lecture du pixel de la map pixelS2 = ReadPixel(pSurfaceMotion, MY_ABS(x) - offset_xS2, MY_ABS(y) - offset_yS2); //Lecture du pixel de la surface en mouvement /*Récupération des composantes colorimétriques*/ SDL_GetRGBA(pixelS1, formatS1, &rS1, &gS1, &bS1, &aS1); //Informations sur les couleurs du pixel de la surface de la map SDL_GetRGBA(pixelS2, formatS2, &rS2, &gS2, &bS2, &aS2); //Informations sur les couleurs du pixel de la surface en mouvement /*Détermination de la collision*/ if (aS1 != 255 || aS2 != 255) //Si le pixel de la surface de la map ou le pixel de la surface en mouvement est transparent collision = 0; //Collision = 0 -> pas de collision else //Au moins l'un des pixels n'est pas transparent { collision = 1; //Collision = 1 -> collision *pDirection = calculDirectionCollision(*pDirection, zone[balayageGen], checkMode); //Calcul de la direction de la collision pour affiner le traitement } } } } formatS1 = NULL; //Remise à 0 des pointeurs de format formatS2 = NULL; //Remise à 0 des pointeurs de format return collision; }
static void SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, SDL_bool draw_end) { if (y1 == y2) { HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); } else if (x1 == x2) { VLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); } else if (ABS(x1 - x2) == ABS(y1 - y2)) { DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); } else { Uint8 _r, _g, _b, _a; const SDL_PixelFormat * fmt = dst->format; SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a); if (fmt->Rmask == 0x00FF0000) { if (!fmt->Amask) { AALINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888, draw_end); } else { AALINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888, draw_end); } } else { AALINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY4_BLEND_RGB, draw_end); } } }
ColorAlpha Texture::getPixel(int x, int y) { Uint32 pixel = *((Uint32*) m_surface->pixels + (m_surface->h - y) * m_surface->w + x); Uint8 r, g, b, a; SDL_GetRGBA(pixel, m_surface->format, &r, &g, &b, &a); return ColorAlpha(r, g, b, a); }
void Surface::setAlpha(int n_alpha) { if(n_alpha > 255 || n_alpha < 0) { return; } Uint8 r=0,g=0,b=0,a=0; for(int h=0; h<sdlSurface->h; h++) { for(int w=0; w<sdlSurface->w; w++) { Uint8 *pc = (Uint8 *)sdlSurface->pixels + h * sdlSurface->pitch + w * 4; Uint32 pval = *(Uint32 *)pc; SDL_GetRGBA(pval, sdlSurface->format, &r, &g, &b, &a); if(a > n_alpha) { Uint32 nc = SDL_MapRGBA(sdlSurface->format , r, g, b, n_alpha); *(Uint32 *)pc = nc; } } } }
void Image::getPixelRGBA(int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) { if ((x < 0) || (x >= m_surface->w) || (y < 0) || (y >= m_surface->h)) { r = 0; g = 0; b = 0; a = 0; return; } int bpp = m_surface->format->BytesPerPixel; Uint8 *p = (Uint8*)m_surface->pixels + y * m_surface->pitch + x * bpp; uint32_t pixel = 0; switch(bpp) { case 1: pixel = *p; case 2: pixel = *(Uint16 *)p; case 3: if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { pixel = p[0] << 16 | p[1] << 8 | p[2]; } else { pixel = p[0] | p[1] << 8 | p[2] << 16; } case 4: pixel = *(Uint32 *)p; } SDL_GetRGBA(pixel, m_surface->format, r, g, b, a); }
void LectorTerreno::crearMatrizRGBA(){ pixel pixActual; //vector<int> columnasInvalidas; //int cantErrores = 0; Uint32* vectorPixeles = (Uint32*)imagen->pixels; for(int i=0; i<altoMatriz; i++){ for(int j=0 ; j<anchoMatriz; j++){ SDL_GetRGBA(vectorPixeles[j + (i*imagen->w)], imagen->format, &pixActual.R, &pixActual.G, &pixActual.B, &pixActual.A); matrizTerreno[j][i] = pixActual; } } //hago una pasada columna por columna para chequear TCT //de haber errores, devuelvo las columnas //columnasInvalidas = chequearTCT(cantErrores); ////si hubo algun tipo de error con la imagen, lo logueo y genero matriz de terreno aleatorio. //if(cantErrores > 0){ // loguearErroresMatriz(columnasInvalidas); // generarTerrenoAleatorio(mascaraTerrenoDEF); //} }
/* Returns whether the SDL_Surface has any pixels that have a transparency that aren't completely clear or solid. */ int gfxUtil_SurfaceIsTranslucent( SDL_Surface* surface ) { Uint8 r, g, b, a; int bpp = surface->format->BytesPerPixel; for( int y = 0; y < surface->h; ++y ) { for( int x = 0; x < surface->w; ++x ) { Uint32 pixel; // pitch seems to be in bits, not bytes as the documentation says it should be Uint8 *pos = ( ( (Uint8*)surface->pixels ) + ( ( y * ( surface->pitch / 8 ) ) + ( x * bpp ) ) ); switch( bpp ) { case 3: if( SDL_BYTEORDER == SDL_BIG_ENDIAN ) { pixel = ( pos[0] << 16 ) | ( pos[1] << 8 ) | pos[2]; } else { pixel = pos[0] | ( pos[1] << 8 ) | ( pos[2] << 16 ); } break; case 4: pixel = *( (Uint32*)pos ); break; default: pixel = 0; break; } SDL_GetRGBA( pixel, surface->format, &r, &g, &b, &a ); if( ( a > 0x00 ) && ( a < 0xFF ) ) { return 1; } } } return 0; }
bool PicTryMakeTex(Pic *p) { SDL_DestroyTexture(p->Tex); p->Tex = TextureCreate( gGraphicsDevice.gameWindow.renderer, SDL_TEXTUREACCESS_STATIC, p->size, SDL_BLENDMODE_NONE, 255); if (p->Tex == NULL) { LOG(LM_GFX, LL_ERROR, "cannot create texture: %s", SDL_GetError()); return false; } if (SDL_UpdateTexture( p->Tex, NULL, p->Data, p->size.x * sizeof(Uint32)) != 0) { LOG(LM_GFX, LL_ERROR, "cannot update texture: %s", SDL_GetError()); return false; } // Check for alpha pixels - if none we can get away with no blending bool hasAlpha = false; for (int i = 0; i < p->size.x * p->size.y; i++) { const Uint32 pixel = p->Data[i]; color_t c; SDL_GetRGBA(pixel, gGraphicsDevice.Format, &c.r, &c.g, &c.b, &c.a); hasAlpha = hasAlpha || c.a < 255; } if (hasAlpha && SDL_SetTextureBlendMode(p->Tex, SDL_BLENDMODE_BLEND) != 0) { LOG(LM_GFX, LL_ERROR, "cannot set texture blend mode: %s", SDL_GetError()); return false; } return true; }
void DrawText(char *text,SDL_Surface *surface,int sx,int sy,Uint32 color,int size) { SDL_Surface *temp1 = NULL; SDL_Surface *fontpic = NULL; SDL_Color colortype,bgcolor; SDL_Rect dst; if((text == NULL)||(surface == NULL))return; SDL_GetRGBA(color, screen->format, &colortype.r, &colortype.g, &colortype.b, &colortype.unused); bgcolor.r = 0; bgcolor.g = 0; bgcolor.b = 0; bgcolor.unused = SDL_ALPHA_TRANSPARENT; switch(size) { case F_Small: if(SFont == NULL)return; temp1 = TTF_RenderText_Blended(SFont, text,colortype); break; case F_Medium: if(Font == NULL)return; temp1 = TTF_RenderText_Blended(Font, text,colortype); break; case F_Large: if(LFont == NULL)return; temp1 = TTF_RenderText_Blended(LFont, text,colortype); break; } fontpic = SDL_DisplayFormatAlpha(temp1); SDL_FreeSurface(temp1); dst.x = sx; dst.y = sy; SDL_SetColorKey(fontpic, SDL_SRCCOLORKEY , SDL_MapRGBA(screen->format, bgcolor.r,bgcolor.g,bgcolor.b,bgcolor.unused)); SDL_BlitSurface(fontpic,NULL,surface,&dst); SDL_FreeSurface(fontpic); }
uint8_t get_alpha(SDL_Surface* surface, int x, int y) { int bpp = surface->format->BytesPerPixel; uint8_t* p = (uint8_t*)surface->pixels + y * surface->pitch + x * bpp; uint32_t pixelColor; switch(bpp) { case(1): pixelColor = *p; break; case(2): pixelColor = *(uint16_t*)p; break; case(3): if(SDL_BYTEORDER == SDL_BIG_ENDIAN) pixelColor = p[0] << 16 | p[1] << 8 | p[2]; else pixelColor = p[0] | p[1] << 8 | p[2] << 16; break; case(4): pixelColor = *(uint32_t*)p; break; } uint8_t red, green, blue, alpha; SDL_GetRGBA(pixelColor, surface->format, &red, &green, &blue, &alpha); return alpha; }
unsigned char image_get(const Image& im, int x, int y, int c) { SDL_Surface* surface = im.surface; /* Extracting color components from a 32-bit color value */ SDL_PixelFormat *fmt; Uint32 pixel; Uint8 red, green, blue, alpha; fmt = surface->format; SDL_LockSurface(surface); pixel = ((Uint32*)surface->pixels) [((surface->h - 1 - y) * surface->w) + x]; SDL_UnlockSurface(surface); SDL_GetRGBA( pixel, fmt, &red, &green, &blue, &alpha); switch(c) { case 0: return red; case 1: return green; case 2: return blue; case 3: return alpha; default: return red; } //return SDL_Color( {red, green, blue, alpha} ); }
void loadTexture3() { void * rawData = (void *) malloc(W * H * 4); Uint8 * pixelSource; Uint8 * pixelDestination = (Uint8 *) rawData; Uint32 pix; SDL_LockMutex(sdlStruct3.sdlMutex); SDL_LockSurface(sdlStruct3.sdlSurface); for (unsigned int i = H; i > 0; i--) { for (unsigned int j = 0; j < W; j++) { pixelSource = (Uint8 *) sdlStruct3.sdlSurface->pixels + (i-1) * sdlStruct3.sdlSurface->pitch + j * 2; pix = *(Uint16 *) pixelSource; SDL_GetRGBA(pix, sdlStruct3.sdlSurface->format, &(pixelDestination[0]), &(pixelDestination[1]), &(pixelDestination[2]), &(pixelDestination[3])); pixelDestination += 4; } } SDL_UnlockSurface(sdlStruct3.sdlSurface); SDL_UnlockMutex(sdlStruct3.sdlMutex); // Building the texture glBindTexture(GL_TEXTURE_2D, textureId3); glTexImage2D(GL_TEXTURE_2D, 0, 4, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *) rawData); free(rawData); }
void view::Surface::createShadow() { bool mustBeLocked = SDL_MUSTLOCK(this->surface); if (mustBeLocked) SDL_LockSurface(this->surface); Uint32* shadowPixels; Uint32* sourceSinglePixel; Uint32* shadowSinglePixel; Uint32* sourcePixels = (Uint32 *) this->surface->pixels; Uint8 r, g, b, a; // nuestro transparente es r=255, g=0 y b=255 SDL_Surface* shadowSurface = NULL; //creo la sombra shadowSurface = SDL_CreateRGBSurface(SDL_HWSURFACE | SDL_SRCALPHA, this->surface->w, this->surface->h,32,0,0,0,0); shadowPixels = (Uint32*)shadowSurface->pixels; //la pinto de negro SDL_FillRect(shadowSurface, NULL, 0x00000000); for (int i = 0; i < this->surface->w; i++) { for (int j = 0; j < this->surface->h; j++) { sourceSinglePixel = sourcePixels + j*this->surface->pitch/4 + i; // Nota que trabajar con pixeles es un viaje de ida SDL_GetRGBA(*sourceSinglePixel, this->surface->format, &r, &g, &b, &a); //donde la imagen de origen era transparente pongo transparente la sombra if ((r==255) && (g == 0) && (b==255)){ shadowSinglePixel = shadowPixels + j*shadowSurface->pitch/4 + i; *shadowSinglePixel = SDL_MapRGB(shadowSurface->format,255,0,255); } } } if (mustBeLocked) SDL_UnlockSurface(this->surface); this->setShadowSurface(shadowSurface); SDL_FreeSurface(shadowSurface); }
void Interface::setSurfaceAlpha(SDL_Surface *surface, Uint8 alpha) { SDL_PixelFormat* fmt = surface->format; if(fmt->Amask == 0) { SDL_SetAlpha( surface, SDL_SRCALPHA, alpha ); } else { unsigned bpp = fmt->BytesPerPixel; float scale = alpha / 255.0f; SDL_LockSurface(surface); for (int y = 0; y < surface->h; ++y) { for (int x = 0; x < surface->w; ++x) { Uint32* pixel_ptr = (Uint32 *)( (Uint8 *)surface->pixels + y * surface->pitch + x * bpp); Uint8 r, g, b, a; SDL_GetRGBA( *pixel_ptr, fmt, &r, &g, &b, &a ); *pixel_ptr = SDL_MapRGBA( fmt, r, g, b, scale * a ); } } SDL_UnlockSurface(surface); } }
Color Surface::get_pixel(int x, int y) const { Uint8 *p = static_cast<Uint8 *>(get_surface()->pixels) + y * get_surface()->pitch + x * get_surface()->format->BytesPerPixel; Uint32 pixel; switch(get_surface()->format->BytesPerPixel) { case 1: pixel = *p; case 2: /* This will cause some problems ... */ pixel = *reinterpret_cast<Uint16*>(p); case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) pixel = p[0] << 16 | p[1] << 8 | p[2]; else pixel = p[0] | p[1] << 8 | p[2] << 16; case 4: pixel = *reinterpret_cast<Uint32*>(p); default: pixel = 0; /* shouldn't happen, but avoids warnings */ } Color color; SDL_GetRGBA(pixel, get_surface()->format, &color.r, &color.g, &color.b, &color.a); return color; }
GrayscaleBuffer::GrayscaleBuffer(SDL_Surface* surface) : width(surface->w), height(surface->h) { buffer = new unsigned char[width*height]; SDL_LockSurface(surface); int bpp = surface->format->BytesPerPixel; Uint8* data = static_cast<Uint8*>(surface->pixels); Uint8 r, g, b, a; for(int i = 0; i < width*height; ++i) { //if (i % width == 0) //std::cout << std::endl; SDL_GetRGBA(*reinterpret_cast<Uint32*>(data + (i*bpp)), surface->format, &r, &g, &b, &a); if (0) std::cout << "(" << std::setw(3) << int(r) << " " << std::setw(3) << int(g) << " " << std::setw(3) << int(b) << " " << std::setw(3) << int(a) << ") "; buffer[i] = (((255 - (r + g + b))/3 * a)/255); } //std::cout << std::endl; SDL_UnlockSurface(surface); }
// render a font with a vertical gradient (top-down) SDL_Surface* renderSolidTextGradient(FontResource& fr, const std::string& str, Gradient& g) { assert(fr.font != nullptr); std::string exceptionMessage{"Error rendering text gradient."}; Color tmpColor; SDL_Surface* textSurf = TTF_RenderText_Blended(fr.font, str.c_str(), {255, 255, 255, SDL_ALPHA_OPAQUE}); if (textSurf == nullptr) { SDL::logError("renderSolidTextGradient TTF_RenderText_Solid"); throw std::runtime_error(exceptionMessage); } assert(textSurf->w > 0); assert(textSurf->h > 0); auto colors = g.generate(textSurf->h); if (SDL_MUSTLOCK(textSurf)) SDL_LockSurface(textSurf); Uint32* pixels = static_cast<Uint32*>(textSurf->pixels); Uint32* pixel = pixels; Uint8 R, G, B, A; for (int y = 0; y < textSurf->h; ++y) { for (int x = 0; x < textSurf->w; ++x, ++pixel) { SDL_GetRGBA(*pixel, textSurf->format, &R, &G, &B, &A); *pixel = SDL::mapRGBA(textSurf->format, colors[static_cast<std::size_t>(y)], A); } } if (SDL_MUSTLOCK(textSurf)) SDL_UnlockSurface(textSurf); return textSurf; }
// Mirror a sprite horizontally extern SDL_Surface* MirrorSprite(SDL_Surface *base) { SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE,base->w,base->h,base->format->BitsPerPixel,base->format->Rmask,base->format->Gmask,base->format->Bmask,base->format->Amask); SDL_Surface *final = SDL_DisplayFormatAlpha(temp); SDL_FreeSurface(temp); SDL_LockSurface(base); SDL_LockSurface(final); long int px, py, nx, ny; uint32_t pux, pnx; uint8_t R,G,B,A; px = 0; py = 0; nx = base->w-1; ny = 0; do { pux = getpixel(base,px,py); SDL_GetRGBA(pux,base->format,&R,&G,&B,&A); pnx = SDL_MapRGBA(final->format,R,G,B,A); putpixel(final,nx,ny,pnx); nx--; px++; if ( px >= base->w ) { px = 0; nx = base->w-1; ny++; py++; } } while ( (px < base->w) && (py < base->h) ); SDL_UnlockSurface(final); SDL_UnlockSurface(base); return final; }
void blitMaskedSprite(SDL_Surface *dst, SDL_Surface *src, Uint32 color) { Uint16 x,y; Uint32 *srcpixel, *dstpixel; if(SDL_MUSTLOCK(dst)) SDL_LockSurface(dst); if(SDL_MUSTLOCK(src)) SDL_LockSurface(src); dstpixel = (Uint32*) dst->pixels; srcpixel = (Uint32*) src->pixels; for(y=0;y<dst->h;y++) { for(x=0;x<dst->w;x++) { Uint8 r,g,b,a; SDL_GetRGBA(*srcpixel,src->format, &r, &g, &b, &a); SDL_GetRGB(color, src->format, &r, &g, &b); *dstpixel = SDL_MapRGBA(dst->format, r, g, b, a); dstpixel++; srcpixel++; } } if(SDL_MUSTLOCK(src)) SDL_UnlockSurface(src); if(SDL_MUSTLOCK(dst)) SDL_UnlockSurface(dst); }
void Image::setAlpha(float alpha) { if (mAlpha == alpha) return; mAlpha = alpha; #ifdef USE_OPENGL if (mImage && !mUseOpenGL) #else if (mImage) #endif { if (SDL_MUSTLOCK(mImage)) SDL_LockSurface(mImage); // Set the alpha value this image is drawn at, pixel by pixel for (int i = 0; i < mImage->w * mImage->h; i++) { Uint8 r, g, b, a; SDL_GetRGBA(((Uint32*) mImage->pixels)[i], mImage->format, &r, &g, &b, &a); a = (Uint8) (mStoredAlpha[i] * mAlpha); ((Uint32 *)(mImage->pixels))[i] = SDL_MapRGBA(mImage->format, r, g, b, a); } if (SDL_MUSTLOCK(mImage)) SDL_UnlockSurface(mImage); } }
void gui_set_gamma(SDL_Surface *Surface, int FXshadow) { Uint32 pixel; Uint8 r, g, b, a; int x, y; // precalcul palette unsigned char precal_pal[256]; float FLshadow; FLshadow = (float) FXshadow / 100 ; for(x = 255; x > -1; --x) precal_pal[x] = x * FLshadow; for(y = 239; y > -1; y--) { for(x = 319; x > -1; x--) { pixel = getPixel(Surface, x, y); SDL_GetRGBA(pixel, Surface->format, &r, &g, &b, &a); //Ici, on mettra du code pour modifier les pixels. if(r) r = precal_pal[r]; if(g) g = precal_pal[g]; if(b) b = precal_pal[b]; //Et une fois qu'on les a modifiés : pixel = SDL_MapRGBA(Surface->format, r, g, b, a); //Et pour changer la valeur d'un pixel : SetPixel(Surface, x, y, pixel); } } }
void PicLoad( Pic *p, const Vec2i size, const Vec2i offset, const SDL_Surface *image) { p->size = size; p->offset = Vec2iZero(); p->Data = malloc(size.x * size.y * sizeof *((Pic *)0)->Data); // Manually copy the pixels and replace the alpha component, // since our gfx device format has no alpha int srcI = offset.y*image->w + offset.x; for (int i = 0; i < size.x * size.y; i++, srcI++) { const Uint32 pixel = ((Uint32 *)image->pixels)[srcI]; SDL_Color c; SDL_GetRGBA(pixel, image->format, &c.r, &c.g, &c.b, &c.a); // If completely transparent, replace rgb with black (0) too // This is because transparency blitting checks entire pixel if (c.a == 0) { p->Data[i] = 0; } else { p->Data[i] = WHITE; } if ((i + 1) % size.x == 0) { srcI += image->w - size.x; } } }
TextureBinary TextureLoaderSDLSurfaceImpl::load() { std::vector<float> pixels; std::size_t numChannels = 0; auto format = PixelFormat_None; switch (m_surface->format->format) { case SDL_PIXELFORMAT_RGB888: numChannels = 3; format = PixelFormat_RGB_32_F; break; case SDL_PIXELFORMAT_RGBA8888: numChannels = 4; format = PixelFormat_RGBA_32_F; break; default: Fail("Yet unsupported SDL Format"); } std::size_t numPixels = m_surface->w * m_surface->h * numChannels; pixels.reserve(numPixels); Uint8 r, g, b, a; for (auto y = m_surface->h - 1; y >= 0; y--) { for (auto x = 0; x < m_surface->w; x++) { auto offset = y * m_surface->pitch + x * m_surface->format->BytesPerPixel; uint8_t * pixel = &((uint8_t*)m_surface->pixels)[offset]; uint32_t value = *(uint32_t*)pixel; switch (m_surface->format->format) { case SDL_PIXELFORMAT_RGB888: SDL_GetRGB(value, m_surface->format, &r, &g, &b); pixels.push_back(r/255.0f); pixels.push_back(g/255.0f); pixels.push_back(b/255.0f); break; case SDL_PIXELFORMAT_RGBA8888: case SDL_PIXELFORMAT_ARGB8888: SDL_GetRGBA(value, m_surface->format, &r, &g, &b, &a); pixels.push_back(r/255.0f); pixels.push_back(g/255.0f); pixels.push_back(b/255.0f); pixels.push_back(a/255.0f); break; default: Fail(std::string("Yet unsupported SDL Format: ") + SDL_GetPixelFormatName(format)); } } } return TextureBinary(SurfaceBinary(std::move(pixels), m_surface->w, m_surface->h, format)); }
bool Spank::GetAlphaXY(Astroid* entity, int x, int y) { int bpp = entity->getSpriteSurface()->format->BytesPerPixel; Uint8* p = (Uint8*)entity->getSpriteSurface()->pixels + y * entity->getSpriteSurface()->pitch + x * bpp; Uint32 pixelColor; switch(bpp) { case(1): pixelColor = *p; break; case(2): pixelColor = *(Uint16*)p; break; case(3): if(SDL_BYTEORDER == SDL_BIG_ENDIAN) pixelColor = p[0] << 16 | p[1] << 8 | p[2]; else pixelColor = p[0] | p[1] << 8 | p[2] << 16; break; case(4): pixelColor = *(Uint32*)p; break; } Uint8 red, green, blue, alpha; SDL_GetRGBA(pixelColor, entity->getSpriteSurface()->format, &red, &green, &blue, &alpha); return alpha > 200; }
const Color4i alpha_pixel ( uint32 pixel, const SDL_PixelFormat* fmt ) { SDL_Color c; SDL_GetRGBA ( pixel, fmt, &c.r, &c.g, &c.b, &c.a ); return Color4i ( c.r, c.g, c.b, c.a ); }
Color32 Thing::getPixel(int x, int y) { unsigned char r,g,b,a; unsigned int* pixels = (unsigned int*)this->screen_ref->pixels; unsigned int* pixel = pixels + y*(this->screen_ref->pitch/4) + x; // offset of pointer SDL_GetRGBA(*pixel, this->screen_ref->format, &r, &g, &b, &a); return Color32(r,g,b,a); };
void CSprite::applyTranslucency(Uint8 value) { Uint8 *pixel; Uint32 colour = 0; Uint8 r,g,b,a; r = g = b = a = 0; if( !mpSurface || g_pVideoDriver->getZoomValue() > 1) return; if(m_alpha == value) return; SDL_PixelFormat *format = mpSurface->format; if(format->BitsPerPixel < 24) { mpSurface.reset(g_pVideoDriver->convertThroughBlitSfc(mpSurface.get()), &SDL_FreeSurface); #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfaceAlphaMod(mpSurface.get(), value); #else SDL_SetAlpha(mpSurface.get(), SDL_SRCALPHA, value); #endif m_alpha = value; return; } if(SDL_MUSTLOCK(mpSurface.get())) SDL_LockSurface(mpSurface.get()); pixel = (Uint8*)mpSurface->pixels; for( Uint8 y=0 ; y<m_ysize ; y++ ) { for( Uint8 x=0 ; x<m_xsize ; x++ ) { memcpy( &colour, pixel, format->BytesPerPixel ); SDL_GetRGBA( colour, format, &r, &g, &b, &a ); if(a!=0) a = value; colour = SDL_MapRGBA( format, r, g, b, a ); memcpy( pixel, &colour, format->BytesPerPixel ); pixel += format->BytesPerPixel; } } if(SDL_MUSTLOCK(mpSurface.get())) SDL_LockSurface(mpSurface.get()); m_alpha = value; }