Tratamiento de archivos PNG en BennuGD

Started by DCelso, May 31, 2009, 11:46:19 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

DCelso

Abro este "topic", en consecencia al debate surgido con los cores en el topic de bennu wii, para recoger los post referentes a este tema.

Post que inició el debate.

Pues yo estoy sorprendido con el tema de transparencias en 8 bits de color.
He hecho mil pruebas y la única que me ha dado resultado es poner el color que quiero que sea transparente en la primera posición de la paleta y luego en las propiedades del png decirle que este color sea el transparente.

Si el color que eliijo como transparente está en otra posición, las aplicaciones como gimp, xnview y acdsee pillan bien la transparencia pero bennu no,sigue mostrando el color real y usa como transparente el color negro (0,0,0).

Si no elijo color transparente y dejo el color que quiero como transparente al principio de la paleta, bennu tampoco me lo pilla como transparente, pilla siempre como transparente el negro (0,0,0).

Osea que bien o usas imágenes de 8 bits de color usando el negro como fondo sin seleccionar ningun color como transparete

O bien pones al principio de la paleta el color que vas a usar como fondo y en las propiedades del png dices que es éste tu color transparente, supongo que esta información irá en la cabecera del png.

He visto que gimp también maneja pngs de 16 bits en el que 8 son para el color usando paleta y 8 para el canal alpha, estos ni papa de si van en bennu.

De esto se ha debatido ya varias veces y creía que me había quedado claro pero siempre aparece algo que pone en duda lo que sé. :D
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

yo tengo poca memoria, pero uds. me ganan...

ya se hablo mil veces que el color transparente es el 0 (no rgb(0,0,0), sino el valor de color "0")

en 8 bits = index de paleta 0
en 16 bits = valor "0", en el caso de los png, se convierte cualquier pixel cuyo alpha sea menor de 50% a valor "0"
en 32 bits = solo el valor "0" absoluto (teniendo en cuenta el alpha) es tranparente, eso igual que en 16 bits, pero la diferencia es que hay transparencias parciales (alphas diferentes en cada pixel).
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Prg

Quote from: DCelso on May 31, 2009, 11:46:19 AM
Pues yo estoy sorprendido con el tema de transparencias en 8 bits de color.
He hecho mil pruebas y la única que me ha dado resultado es poner el color que quiero que sea transparente en la primera posición de la paleta y luego en las propiedades del png decirle que este color sea el transparente.

Si el color que eliijo como transparente está en otra posición, las aplicaciones como gimp, xnview y acdsee pillan bien la transparencia pero bennu no,sigue mostrando el color real y usa como transparente el color negro (0,0,0).

Si no elijo color transparente y dejo el color que quiero como transparente al principio de la paleta, bennu tampoco me lo pilla como transparente, pilla siempre como transparente el negro (0,0,0).

Osea que bien o usas imágenes de 8 bits de color usando el negro como fondo sin seleccionar ningun color como transparete

O bien pones al principio de la paleta el color que vas a usar como fondo y en las propiedades del png dices que es éste tu color transparente, supongo que esta información irá en la cabecera del png.

He visto que gimp también maneja pngs de 16 bits en el que 8 son para el color usando paleta y 8 para el canal alpha, estos ni papa de si van en bennu.

De esto se ha debatido ya varias veces y creía que me había quedado claro pero siempre aparece algo que pone en duda lo que sé. :D
ja ja ja amigo :)
si tanto se les complica hacer esto, tienen una solución muy sencilla, aunque un poco tardada:

trabajar sobre el buffer, tomar todos los colores 0 y cambiarle el índice al del color que debe ser, o al más parecido, y el del color que podría ser el negro cambiarlo a 0, con eso debe funcionar, aunque es muy tardado, nada recomendable es una solución, haganse un programita que lo haga y exporte sus png y listo, ya tienes png con paletas correctas. :)
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

DCelso

#3
SplinterGU, no sé que versión de pngs soporta Bennu, me he vuelto a leer varias especificaciones de pngs y en todas ellas hablan de lo mismo. A un PNG indexado de 8 bits se le puede asignar que uno de los colores de su paleta sea el transparente.
Quote
El PNG admite, al igual que el GIF, imágenes indexadas con transparencia de 1 bit o "binaria". Este tipo de transparencia no requiere de un canal adicional y únicamente admite que un color de la paleta aparezca transparente al 100%.
Además si pruebas con diferentes visores de imágenes (como xnview o acdsee) ves que éste soporte es nativo, es decir el color que seleccionaste en la paleta que quisieras que fuera transparente no se ve.

Lo que hace bennu es obligar a que sea siempre el color que está en el índice 0. Por eso, si lees mi antiguo post, verás que la única prueba que me fué válida es en la que puse mi color que quería que fuera transparente (en este caso era el blanco) en el primer índice de la paleta y le dije al editor que lo usara como transparente. Es el único caso en que el blanco se ve transparente en los visores de imágenes png y en bennu.
Ejemplo práctico usando gimp:
creas tu imagen indexada de 256 colores, usas el verde clarito como fondo y empiezas a dibujar tu sprite, usas por ejemplo el negro para crearle los bordes del sprite, cuando terminas seleccionas el verde clarito y le das a añadir al canal alfa, desaparece y no se ve. Guardas el archivo en png.
Lo abres con xnview y no se ve el verde clarito, es decir, es transparente.
Lo abres con bennu y sí que se ve el verde, pero es más, si pones una imagen de fondo y mueves el sprite, verás que por los bordes se ve el fondo, esto es porque al guardar la imagen gimp pone el negro en el primer índice de la paleta. Por tanto bennu asigna automáticamente éste como color transparente.

Yo creo que habría que revisar cómo abre bennu los pngs de 8 bits, porque no utiliza la información de transparente que en ellos hay, lo suyo sería que usase esta información para respetar lo que hacen los demás programas externos, y si no encontrara la información de transparente entonces aplicar la lógica que hasta ahora hace. Así cumpliría el estándar png y habría compatibilidad hacia atrás.

Las imágenes de 16 bits ya es otra historia, porque las especificaciones de png no soportan RGB para este tipo. Bennu tiene que usar por pe...otas pngs de 24 bits para meter en su formato 16 bits. Estas imágenes png de 24 bits usan 8 bits para cada canal RGB, aquí no existe transparencia (ni siquiera binaria) así que bennu usa el absoluto 0 para transparente pero coincide con el rgb(0,0,0) así que el negro en imágenes de 24 bits es el transparente para bennu en densidad 16.
Prueba práctica, haces tu imagen con gimp poniendo el negro como fondo, eliminas el canal alfa en la sección de capas. Guardas la imagen, la abres con xnview y el fondo se ve negro.
La abres con bennu en densidad 16 bits y se ve transparente el negro.

Las imágenes de 32 bits funcionan perfectamente porque bennu se ajusta al formato png de 32 bits de forma adecuada(en este aspecto Splinter hizo un gran trabajo), en este formato hay 8 bits para cada canal RGB y 8 bits para el canal alfa, lo que supone poder usar colores semitransparentes. En este caso el color que usa bennu como transparente es el absoluto 0, éste coincide con el RGBA(0,0,0,0) (negro con alfa igual a cero) y solo con este, si intentáramos usar el blanco con alfa 0 no se vería el blanco pero sí daría colisión otro objeto con él.
Ejemplo práctico con gimp.
Creamos una imagen con gimp, usamos como fondo el negro, creamos un sprite con un borde bastante gordo de color blanco, añadimos el negro al canal alfa desde el menú de capas, añadimos el blanco al canal alfa de la misma forma, para nosotros se ven los dos transparentes pero en verdad por detrás son dos colores distintos. Guardamos nuestro sprite.
Abrimos con xnview y vemos que no se ve ni el fondo negro ni el borde blanco del sprite.
Abrimos con bennu en densidad 32 bits y apreciamos el mismo resultado, pero si pasamos un objeto cerca veremos que colisiona antes de tiempo, justo al llegar al borde blanco que no se ve, esto es debido a lo comentado anteriormente que transparente pero no es el color 0 absoluto sino el RGBA(255,255,255,0). En cambio con el negro que hicimos transparente no pasa porque coincide con el color 0 absoluto.

He probado todos los ejemplos antes de poner estas líneas por si alguien llega a pensar que es una fumada mía, si alguien está en desacuerdo que los realice con las mismas herramientas antes de opinar.

Como conclusión mía para bennu y viendo que se usa png como formato base:
1.- intentaría implementar la funcionalidad de 8 bits para que se ajuste al estándar png. Simplemente es saber donde guarda png la información del color transparente e interpretarla.
2.- eliminaría la densidad de 16 bits ya que es un arreglo impreciso para usar RGB (por eso de que un canal tenga un bit más que los otros en precisión) y no se ajusta al estándar png. Existe el formato 24 bits sin este fallo, en el que usando el negro podemos simular transparencia binaria.
3.- fomentar el uso del formato 32 bits ya que es el que soporta semitransparencias y estas dan mejor apariencia a nuestros juegos siempre que sepamos diseñar bien nuestros sprites y tengamos en cuenta que hay que añadir como transparente absoluto para no colisionar el negro.

Por cierto, Splinter seguro que insistes en que rgba(0,0,0,0) es distinto a 0 (ya me lo hiciste otras veces :D), mira por dentro el algoritmo que usa para generar el entero y tendrá que salir que al final es igual a 0 sino no funcionarían mis ejemplos.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

jajaja...

Pix, es necesario hacer una prueba bien controlada...

8 bits, png, fpg, fpg sin compresion, map, map sin compresion
16 bits lo mismo
32 bits lo mismo

probar solo seteando el modo de video (en cada uno) y hacer un simple while(!key(...) or joy...), etc, sin dibujar nada... ver si se cuelga... o no...

y todas pruebas controladas, y mostrando los resultados... asi, aunque no tenga la wii, puedo intentar deducir donde esta el problema....
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

#5
A ver... ya se hablo mucho de esto... vamos de nuevo...
Bennu solo soporta formato MAP... las lecturas png, etc, son solo importaciones donde el resultado final es un map... y bennu necesita que el valor 0 sea transparente (por muchos motivos que ya explique muchas veces, una cosa es un visor que muestra 1 imagen 1 vez y no necesita performance y otra es algo que tiene que dibujar el grafico continuamente y a la mayor velocidad posible, no se puede comparar)...
usar otro color significaria conversion de los pixels con ese color a 0, y que hacer entonces con el 0? como sea, estariamos generando un mapa totalmente diferente al creado, y si en la logica de nuestro juego usamos ese color "transparente" para algo, ya no estara con el mismo valor...
Resumiendo... no importa lo que diga el formato png, bennu necesita que el color transparente sea el "0".

Vamos de nuevo, por enesima vez, rgb(0,0,0) != 0 = 1

rgba es otra cosa
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

32 bits es otro mundo... 8 y 16 se heredan de fenix... y esta bien como estan implementados...



int gr_rgb( int r, int g, int b )
{
    int color ;

    color = (( r >> sys_pixel_format->Rloss ) << sys_pixel_format->Rshift ) |
            (( g >> sys_pixel_format->Gloss ) << sys_pixel_format->Gshift ) |
            (( b >> sys_pixel_format->Bloss ) << sys_pixel_format->Bshift ) ;

    if ( sys_pixel_format->depth == 32 ) return 0xff000000 | color ;

    if ( !color ) return 1 ;

    return color ;
}

/* --------------------------------------------------------------------------- */

int gr_rgba( int r, int g, int b, int a )
{
    int color = 0;

    if ( sys_pixel_format->depth == 32 )
    {
        color = (( r >> sys_pixel_format->Rloss ) << sys_pixel_format->Rshift ) |
                (( g >> sys_pixel_format->Gloss ) << sys_pixel_format->Gshift ) |
                (( b >> sys_pixel_format->Bloss ) << sys_pixel_format->Bshift ) |
                (( a >> sys_pixel_format->Aloss ) << sys_pixel_format->Ashift ) ;
    }
    else if ( sys_pixel_format->depth == 16 )
    {
        color = (( r >> sys_pixel_format->Rloss ) << sys_pixel_format->Rshift ) |
                (( g >> sys_pixel_format->Gloss ) << sys_pixel_format->Gshift ) |
                (( b >> sys_pixel_format->Bloss ) << sys_pixel_format->Bshift ) ;
    }

    if ( !color ) return 1 ;

    return color ;
}


Bueno, veo que hay un error en rgba para 32bits... ahora lo soluciono...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

#7
:D, yo me referia a la hora de cargar el png nada mas, no a cambiar el sistema de almacenamiento de bennu.
No veo que sea dificil mirar el dato del png para el color transparente y ponerlo el primero de la paleta cambiándolo en todas sus referencias. Solo al leer el png, luego ya guardado en map o lo que sea pues que siga igual. En fin que no lo vea dificil no quiere decir que no lo sea :D.
De todas formas es una sugerencia no tienes porqué hacerla pero ayudaría a no despistar por lo de que en otros visores se vea transparente y luego en bennu no. (quieras o no eso mosquea y da quebraderos de cabeza hasta que se descubren las entrañas y llegan a la conclusión de que hay que ponerlo al principio de la paleta del png :D)
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

DCelso

con esas funciones no puedes meter un color transparente nunca
RGB(0,0,0) devuelve 1 y RGBA(0,0,0,0) devuelve también 1.
No creo que sean las que use load_png para cargar la imagen porque sino no podrías leer la información de transparencia 0 para el negro de las imagenes png de 32 bits.
Y actualmente va bien, mi ejemplo funciona, es deci,r el pixel con información 0,0,0,0 no lo dibuja.
En 16 bits algo parecido, porque a mi el negro rgb 0,0,0 de mi png de 24 bits me lo pone transparente, voy a revisar mis ejemplos. pero para mi que estas funciones no son las que se usan en la carga del png al map.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

#9
no es dificil, sino es erratico, porque si, cambiamos todos los "color transparente" a 0, bien, pero que pasa con los 0 que ya existian? esos deben ser negros, no transparentes... entonces requiere ir swapeando el "transparente definido por el usuario" y el "0 absoluto" pixel a pixel... y esto ya estas cambiando los datos del grafico, y si esos datos se usan en la logica estamos haciendo cagadas... ni que hablar con la ruptura de compatibilidad con todo lo existente, hay rupturas que no son graves, pero esta creo que si lo es...

esas funciones no tienen nada que ver con el color transparente, digo que retornan 1.
rgba 0,0,0,0 en los programas graficos (y en bennu 32bits)... si, claro, son pixel = 0... pero no son rgba(0,0,0,0)...
esas funciones no se usan para la carga, claro que no... pero veo que es muy complicado explicarlo, y muy complicado entender los porque cuando no se conoce la filosofia de la transparencia div/fenix/bennu.

Por otro lado, es un requisito del motor, color 0 = transparente...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

#10
Killo, no nos entendemos, no quise decir eso, en fin, aceptamos barco en lo referente a 8 bits.
En cuanto a 16 o más, da igual como lo haga por dentro, la cosa es que va con lo que hago así que debemos tener razón los dos aunque lo veamos desde puntos de vista distintos.
En resumen, a nivel de vista de NO programador interno de bennu y de programador de juegos bennu:

Si usas modo 8 bits en bennu, las imágenes tienes que hacerlas en png indexado sabiendo que el primer color de la paleta será el transparente para bennu independientemente del color que elijas en el editor gráfico. Y todas las imágenes deben usar esa misma paleta, si las imágenes tienen paletas distintas, la primera imagen cargada será la que inserte su paleta para el resto, haciendo que las que usan paleta diferente a ella se vean usando ésta y a efectos visuales cambien sus colores.

Si usas modo 16 bits en bennu, las imágenes tienes que hacerlas en png 24 bits de color sabiendo que el negro 0,0,0 será el transparente para bennu.

Si usas modo 32 bits en bennu, las imágenes tienes que hacerlas en png 32 bits de color sabiendo que bennu usará el canal alfa para mostrar los semitransparentes y que el color negro transparente será el único que no causará colisión con otros colores.
No hay mas vuelta de hoja, mis ejemplos lo demuestran, no quiero pasarlos para no llevaros por mi camino y que cada uno lo descubra a su manera pero si hace falta los subo.

Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

exacto, asi es...

una cosa, en 16 bits, no solo el 0,0,0, sino aquellos pixels cuyo componente alpha es menor al 50%, es transparente o sea, 0...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

#12
Esa opción no la mencioné para no liar pero está, aunque no tengo la prueba, la tengo que hacer pero básicamente es:

En caso de usar 16 bits de profuncidad en bennu y usar imágenes png de 32 bits. Bennu pone a transparente todos los píxeles en que su componente alfa esté por debajo de 128.

Os recuerdo que en imágenes png de 24 bits no existe canal alfa. Solo son 8R 8G 8B =24 en contraoposición al 32 bits que son 8R 8G 8B 8A  = 32.

Quedan mas cruces de densidades en mis pruebas yo me basé en intentar usar la misma densidad para hacer la imagen que para cargar en bennu con la peculiaridad de que 16 bits en color RBG no existe en el png. (hay 16 bits divididos en un canal de 8 para escala de grises y un canal de 8 para alfa. También una escala de grises sin componente alfa de alta densidad de 16 bits. Pero nada para color, es decir, no existe en png un canal indexado de 8 bits de color mas un canal alfa de 8 bits)
Referencia:
http://es.wikipedia.org/w/index.php?title=Portable_Network_Graphics&action=submit

Intentaré hacer ejemplos para los cruces de densidades que faltan y sacar a la luz como actúa bennu en la práctica con estos.

bennu en 8 - pngs en 8  <-- ya visto. Primer color de paleta como transparente.
               - pngs en 24 <-- Supongo que no se podrá, falta probar.
               - pngs en 32 <-- Supongo que no se podrá, falta probar.

bennu en 16 - pngs en 8 <-- supongo que usará el color negro como transparente, falta probar.
                - pngs en 24 <-- ya visto. Color negro como transparente.
                - pngs en 32 <-- ya visto. Alfas menor a 128 como transparentes, falta probar.

bennu en 32 - pngs en 8  <-- supongo que usará el color negro como transparente, falta probar.
                - pngs en 24 <-- supongo que usará el color negro como transparente, falta probar.
               - pngs en 32 <-- ya visto. Usa componente alfa con semitransparentes.

PD: Splinter, voy a quitar estas cuestiones de este post, que wii ha sido el desencadenante por solo soportar por ahora 8 bits, pero es un poco offtopic, ¿no crees?
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

En base a esto, sugiero que se arme un post en el area de documentacion... sobre transparencias en Bennu... y que quede como tutorial, luego borramos todo esto...

Gracias DCelso por la molestia que te tomaste en abrir el thread y mover los hilos...
Saludos.

Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

Ok, te refieres en la wiki o aqui, porque esto ya está en documentación.

Por otro lado no hablé de 24 bits en bennu, este modo supongo que es clavadito al de 16 pero usando 8 bits para cada canal RGB en vezde 565. Me refiero a que se comportaría igual que en las pruebas a 16 bits mencionadas.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/