|
Appendice2 - funzioni di blitting personalizzate
Le seguenti sono due funzioni fondamentali in SDL_BlitSurface_transparent; il loro sorgente è in SDL_Example3.
La fonte è http://docs.huihoo.com/sdl/1.2/guidevideo.html - SDL Library Documentation
Uint32 getpixel(SDL_Surface *surface, int x, int y) ;
/*
* Imposta il pixel di coordinate (x, y)
* ATTENZIONE: la superficie deve essere bloccata prima di eseguire questa funzione
*/
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel) ;
Utilizzando getpixel e putpixel ho scritto SDL_BlitSurface_transparent, una funzione che mi era necessaria per la realizzazione di un motore di rendering che mi permettesse di disegnare immagini utilizzando la trasparenza. Per farlo è stato sufficiente disegnare l'immagine tralasciando i pixel di colore uguale a quello di (x, y)==(0, 0).
Oltre a questo la funzione permette di gestire altri aspetti, come il flip dell'immagine, la rotazione, la scala.
int SDL_BlitSurface_transparent(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, int ang_rotaz, int flip, int decentramento_y, int scala, int dec_scala, int fantasma)
/*
*src -> source - sorgente
*srcrect -> parte(rettangolo) della sorgente da copiare
*dst -> destinazione
*dstrect -> dove copio nella superficie di dst
ang_rotaz -> 0 - 360 rotazione immagine *** DA IMPLEMENTARE ***
flip -> 0 none
1 specchio orizzontalmente
2 specchio verticalmente
scala -> 1 normale
-2 metà
2 doppio
decimale -> come inserire 3.1: scala.decimale
concretamente disegno ogni volta che l'accumulo dei decimali mi dà 1
..
fantasma -> 0 normale
1 fantasma (immagine "tirata su")
2 + immagine sempre più tirata verso l'alto
*/
{
// SDL_Surface sono già sbloccate
int i,j,decimale=0,aggiunta;
int xs, ys, xd, yd, ystmp, ydtmp;
int condizione_x, condizione_y;
Uint32 color, trpcolor;
trpcolor=getpixel(src, 0, 0);
if ( (srcrect==NULL) && (dstrect==NULL) )
{
xs=0;
ystmp=0;
xd=0;
ydtmp=0+decentramento_y;
condizione_x=src->w;
condizione_y=src->h;
if (flip==1) // flip orizzontale
xd+=src->w;
}
else
if (srcrect==NULL)
{
xs=0;
ystmp=0;
xd=dstrect->x;
ydtmp=dstrect->y+decentramento_y;
condizione_x=src->w;
condizione_y=src->h;
if (flip==1) // flip orizzontale
xd+=src->w;
}
else
if (dstrect==NULL)
{
xs=srcrect->x;
ystmp=srcrect->y;
xd=0;
ydtmp=0+decentramento_y;
condizione_x=(srcrect->w + srcrect->x);
condizione_y=(srcrect->h + srcrect->y);
if (flip==1) // flip orizzontale
xd+=srcrect->w;
}
else
{
xs=srcrect->x;
ystmp=srcrect->y;
xd=dstrect->x;
ydtmp=dstrect->y+decentramento_y;
condizione_x=(srcrect->w + srcrect->x);
condizione_y=(srcrect->h + srcrect->y);
if (flip==1) // flip orizzontale
xd+=srcrect->w;
}
for (; xs<(condizione_x); xs++) // copio il pixel se all'interno della superficie e se != dal transparent color (lo intendo come il bit 0, 0 della sorgente)
{
if ( (xd>=0) && (xd<=dst->w) ) // disegno solo se all'interno della superficie
for (ys=ystmp, yd=ydtmp; ys<(condizione_y); ys++, yd+=scala+aggiunta)
{
if ( (yd>=0) && (yd<=dst->h) ) // disegno solo se all'interno della superficie
{
/* Scala decimale */
decimale+=dec_scala; // per la scala decimale
if (decimale>=10){
decimale-=10;
aggiunta=1;
}
else
aggiunta=0;
color=getpixel(src, xs, ys);
if ((color!=trpcolor) && (color!=getpixel(dst,xd,yd)) ){
for (i=0; i<scala+aggiunta; i++) // scala
for (j=0; j<scala+aggiunta; j++) // scala
putpixel(dst, xd+i, yd+j, color); // per l'effetto semi-trasparenza xd+1 xd-1 ****************************************************
yd-=fantasma;
}
}
}
if (flip==1) xd-=scala;
else xd+=scala;
}
return 0;
}
|
|