PDA

Ver la versión completa : [SOURCE] Funcion de Filtrado Bilineal



hermes PS2R
19/06/2006, 05:19
Buenas,ultimamente no me prodigo mucho por estos foros, pero hoy me ha dado por programar un poco y una de las cosas que siempre me han interesado, es hacer una rutina que hiciese filtrado bilineal en una textura.

La teoria de este metodo, consiste en averiguar el color de un pixel intermedio en la textura de origen, usando los pixeles mas proximos y el resultado, es esta pequeña funcion que comparto con vosotros por si quereis darle utilidad.

La rutina no la he probado en la GP2X, asi que no puedo dar detalle sobre su funcionamiento ahi (si es rapida o lenta, por ejemplo)





static unsigned inline get_pix_rel(int x,int y, unsigned *text,int tx1,int ty1,int factx,int facty)
{

static unsigned dummy=0; // color dummy
unsigned a,b,c,rel;
unsigned char *t1=(unsigned char *) &dummy,*t2=(unsigned char *) &dummy;
unsigned char *t3=(unsigned char *) &dummy,*t4=(unsigned char *) &dummy;

// rel contiene la posicion relativa vertical de textura
rel=tx1*y;
// obtiene puntero color x,y en t1 */
if(!(x<0 || y<0 || x>=tx1 || y>=ty1)) t1=(unsigned char *) &text[x+rel];
x++;
// obtiene puntero color x+1,y en t2 */
if(!(x<0 || y<0 || x>=tx1 || y>=ty1)) t2=(unsigned char *) &text[x+rel];
y++;x--;rel+=tx1;
// obtiene puntero color x,y+1 en t3 */
if(!(x<0 || y<0 || x>=tx1 || y>=ty1)) t3=(unsigned char *) &text[x+rel];
x++;
// obtiene puntero color x+1,y+1 en t4 */
if(!(x<0 || y<0 || x>=tx1 || y>=ty1)) t4=(unsigned char *) &text[x+rel];

/* obtiene color R interpolado de t1 y t2 (horizontal)*/
a=(((t2[0]-t1[0])*factx)>>8)+t1[0];
/* obtiene color R interpolado de t3 y t4 (horizontal)*/
b=(((t4[0]-t3[0])*factx)>>8)+t3[0];
/* obtiene color R interpolando a y b (vertical) y lo almacena en c */
c=((((b-a)*facty)>>8)+a);

/* obtiene color G interpolado de t1 y t2 (horizontal)*/
a=(((t2[1]-t1[1])*factx)>>8)+t1[1];
/* obtiene color G interpolado de t3 y t4 (horizontal)*/
b=(((t4[1]-t3[1])*factx)>>8)+t3[1];
/* obtiene color G interpolando a y b (vertical) y lo almacena en c */
c+=((((b-a)*facty)>>8)+a)<<8;

/* obtiene color B interpolado de t1 y t2 (horizontal)*/
a=(((t2[2]-t1[2])*factx)>>8)+t1[2];
/* obtiene color B interpolado de t3 y t4 (horizontal)*/
b=(((t4[2]-t3[2])*factx)>>8)+t3[2];
/* obtiene color B interpolando a y b (vertical) y lo almacena en c */
c+=((((b-a)*facty)>>8)+a)<<16;

/* NOTA: el factor de interpolacion (decimal) tiene un rango de 0 a 255 */

return c; // retorna color interpolado

}

/* text_bilineal: Uso.

text-> textura origen (4 bytes)
tx1-> ancho de textura origen en pixels
ty1-> alto textura origen en pixels

text2-> textura destino (4 bytes)
tx2-> ancho textura destino en pixels
ty2-> alto textura origen en pixels
*/

void text_bilineal(unsigned *text,int tx1,int ty1,unsigned *text2,int tx2,int ty2)
{
int n,m;
int xx,yy,rel;
unsigned col1;
int fx,fy;

for(n=0;n<ty2;n++)
{

/* calcula coordenada Y en textura de origen usando enteros con 8 bits de coma fija */
fy=(((n*ty1)<<8)/ty2);

/* obtiene la Y de textura sin la parte 'decimal' */
yy=fy>>8;

/* deja en fy la parte 'decimal' de Y */
fy&=255;

/* calcula en rel la posicion relativa Y en textura destino*/
rel=n*tx2;

for(m=0;m<tx2;m++)
{

/* calcula coordenada X en textura de origen usando enteros con 8 bits de coma fija */
fx=(((m*tx1)<<8)/tx2);

/* obtiene la X de textura sin la parte 'decimal' */
xx=fx>>8;

/* deja en fx la parte 'decimal' de X */
fx&=255;

/* llama a la funcion que obtiene el color medio en textura origen */
col1=get_pix_rel(xx, yy, text, tx1,ty1, fx, fy);

/* escribe el color calculado en textura destino */
text2[m+rel]=col1;
}
}
}


COMO SE USA

El uso es muy sencillo, la funcion es text_bilineal() y recibe como entrada una textura de color 32 bit color y su ancho y alto en pixeles y una textura de salida tambien a 32 bits, junto con su ancho y alto correspondiente (se calculan solo los 24 bits mas bajos correspondientes a R,G,B)

No creo que tengais mucho problema en poder adaptar la rutina para una textura de entrada de 8 bits (con paleta) o 16 bits, para una salida a 16-32 bits (como se obtienen colores intermedios, no seria muy conveniente usar 8 bits color de salida), o eso espero ;)

lib
19/06/2006, 05:48
yo poco se de programacion pero te doy las gracias por compartir y acordarte de la gp2x :) que algun dia sera la portatil perfecta ya lo veras.

un saludo

Segata Sanshiro
19/06/2006, 07:38
Una duda, ¿esto es compatible con el escalado por hardware que usan muchos emuladores?

K-teto
19/06/2006, 08:42
No, no lo es.
Ya se que es una mierda de post, pero es que es lo unico que puedo decir XD

hermes PS2R
20/06/2006, 02:02
No, no es compatible con el reescalado hardware (mas bien, es lo que debería hacer el hardware y no hace...)

Si se adapta, se podria usar en los emuladores, aunque evidentemente, la rutina chupa CPU, lo cual no quita que la rutina tenga otros usos

Zenzuke
20/06/2006, 02:37
Hombre, por ejemplo en el AlexKidd de puck vendria estupendamente, porque va sobrado de velocidad y el escalado keda un poco como el culo (que ya se que no es culpa de puck, pero es asi xD)

Hermes, tiu, se te exaba de menos por los foros. Sobre todo a tus programas, todo hay que decirlo, que en conjunto deben ser el 70% del tiempo que paso con la gp2x :D

Lo que me mosquea del asunto es que estoy casi seguro de que los vídeos, la consola me los saca filtrados. El caso es... no hay ninguna manera de aprovechar el filtrado ese del procesador de vídeo para el escalado? Esque manda webs que haya tan poca información sobre ese apartado tan jugoso en concreto, de la consola xD

Y ahora una pregunta... esto valdría para hacer filtrado de MAS resolución a MENOS? Porque muchos juegos de cps1 por ejemplo, no se ven todo lo bien que podrían, aunque claro, emulando una placa asi de potente a lo mejor era un poco overkill hacer eso xD

Franxis
20/06/2006, 05:43
Hombre, estaria genial utilizar el segundo micro para hacer un escalado bilineal... al menos ya le dariamos un uso...

xDDDD

Zenzuke
20/06/2006, 06:19
Ya que te pasaste por aquí, franxis. ¿Como va el model 3? ya pasa de 50 fps? xDDDDDD

Va, me callo que al final la gente se lo termina tomando en serio xDD