Problemas con SDL

Started by DCelso, February 18, 2010, 09:01:33 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

DCelso

Hola a todos,
esto va mas bien para Splinter, creo.
Tengo problemas al pintar en pantalla una imagen de 32 bits.
He buscado información por todas partes, he encontrado respuestas de lo más inverosímiles que he probado sin éxito.
el ejemplo es sencillísimo, cargar un bmp de 32 bits en una pantalla de 32 bits :D.
EL bmp es un simple circulo con un degradado blanco que tiene alfa a 255 en los pixeles que no pertenecen al círculo en sí.

/*
* main.c
*
*  Created on: 18/02/2010
*      Author: dcfernandez
*/
#include "SDL.h"
void ShowBMP(char *file, SDL_Surface *screen, int x, int y) {
SDL_Surface *image,* tmp;
SDL_Rect dest;
tmp = SDL_LoadBMP(file);
if (image == NULL) {
fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
return;
}
image = SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);

dest.x = x;
dest.y = y;
dest.w = image->w;
dest.h = image->h;

//SDL_SetAlpha( image , SDL_RLEACCEL | SDL_SRCALPHA , 200);
SDL_BlitSurface(image, NULL, screen, &dest);
SDL_UpdateRects(screen, 1, &dest);
}
int main(int argc, char * argv[]) {
int salir = 0;
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen;
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
ShowBMP("../resources/imagen.bmp", screen,0,0);
SDL_Event event;
do {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
salir = 1;
break;
}
break;
case SDL_QUIT:
salir = 1;
}
}
} while (!salir);
exit(0);
}

He quitado comprobaciones y demás para que ocupe lo mínimo, con las comprobaciones va exactamente igual, que conste.
la imagen es la que está adjunta. (No me deja subir bmps el sistema)
He probado sdl_setalpha, pero es una kk de función, establece el valor alpha dado a todos los píxeles de la imagen, por lo tanto no es lo que busco, yo busco que se usen los valores alpha de cada pixel que hay guardados en la imagen.
He leído por ahí que sdl_loadBMP no carga imágenes de 32 bits, pero mira que me extraña.
Voy a ver el mismo ejemplo con sdl_image a ver que me suelta.
Monstruos Diabólicos

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

DCelso

#1
probado el ejemplo con sdl_image, cambiando sdl_loadbmp por img_load. Y nada, el mismo resultado.
También he probado a poner un png de 32 bits en vez del bmp y nada, igual.
También he probado los parámetros SDL_RLEACCEL | SDL_SRCALPHA (aunque he leido que no están relaccionados con la componente alfa de los pixeles sino con toda la superficie de la imagen, es decir, la sdl_surface. ) en el screen pero tampoco sirven para nadada.
Edit:
Buscando más info, he encontrado como postparsear la imagen para usar la componente alfa de los píxeles.
He cambiado la funcion showbmp por esta otra

void ShowBMP(char *file, SDL_Surface *screen, int x, int y) {
SDL_Surface *image, *tmp;
SDL_Rect dest;
tmp = IMG_Load(file);
if (image == NULL) {
fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
return;
}

//Check the format
switch (tmp->format->BitsPerPixel) {
case 32:
//It's 32 bit, so convert only if it's ABGR (and really, check this pixel format!)
if (tmp->format->Rshift > tmp->format->Bshift) {
SDL_PixelFormat format = { NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24,
0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255 };
image = SDL_ConvertSurface(tmp, &format, SDL_SWSURFACE);
}
break;
default:
image = SDL_DisplayFormat(tmp);
}

SDL_FreeSurface(tmp);

dest.x = x;
dest.y = y;
dest.w = image->w;
dest.h = image->h;


SDL_BlitSurface(image, NULL, screen, &dest);
SDL_UpdateRects(screen, 1, &dest);
}

Ahora bien, este código va con una imagen bmp de 32 bits pero no va con imágenes PNG de 32 bits. No entiendo el porqué.
Monstruos Diabólicos

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

DCelso

Juas, pues sí es verdad que estaba el fallo en el SDL_loadBMP, he tenido que modificar su código para darle soporte de bmps 24/32 bits.
Ahora esto va de perlas.

Dejo el código fuente con un ejemplo de carga de imágenes de 8,24 y 32 bits con SDL_loadBMP_A, que he realizado por si a alguien le puede ayudar para algo. :D.
Monstruos Diabólicos

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

Windgate

Uuuhhh, lo he bajado, pero el Makefile me trae muy malos recuerdos... ¿No lo tienes en versión proyecto de CodeBlocks que use rutas relativas, compilar con un clic y listo?

Si es mucho pedir tranki, es sólo una sugerencia :D es que con la descripción que pones y sin verlo en ejecución no termino de entender muy bien lo que pretendes, ¿No estarás intentando mejorar las funciones de trabajo con gráficos de Bennu para darles soporte en 32 bits? Me refiero a map_block_copy y compañía... Si estás haciendo algo así te mereces un :-*
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

yo tampoco entendi mucho, cargar bmps de 32 bits?

pero como vi que se respondio solo, no dije nada...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

#5
sipo, la librería oficial de sdl 1.2.4 solo carga bmps nativamente pero no usa la componente alfa de los bmps de 32 bits RGBA(= 8bits por canal x 4 canales:rojo,verde,azul,alfa) así que como tenemos acceso al código fuente de sdl, he estado mirando la funcion SDL_loadBMP y he visto que tenía puesto Amask a 0 (Amask es una máscara que usa SDL internamente para calcular el canal alfa) así que investigando por allí y por allá he encontrado el valor correcto a poner en Rmask, Gmask,Bmask y Amask para cargar imágenes BMP de 32 bits.
Y con esa información he duplicado la funcion SDL_loadBMP cambiándole el nombre a SDL_loadBMP_A (de Alfa) dándole soporte para que contemple el valor de esta componente.
El ejemplo es muy simple, carga un bmp de 8 bits, un bmp de 24 bits y un bmp de 32 bits en posiciones distintas de la pantalla. En él se puede ver que el círculo solo se ve bien en 32 bits, ya que en el resto se ve el círculo sobre un fondo blanco (que es el que eliminé desde gimp para crear la imagen de 32 bits y se quedara transparente en el canal alfa).
Para compilarlo necesitas tener como mínimo instalado en windows mingw32 y la librería "dev" de sdl 1.2.4 descomprimida dentro del ming32.
Luego abres el makefile y cambias el valor de una variable si instalaste mingw32 en una ruta distinta de la de defecto  (tienes que poner la ruta del mingw), grabas y  desde la consola de comandos te vas al directorio del código fuente y ejecutas make,esto te crea un ejecutable para ver el resultado.

Hay que decir que esto ya lo hace la librería SDL_image, así que no es nada nuevo lo que aporto si no te importa instalarte una librería más con todas las dependencias que necesita :D.

Por cierto SpinterGU, ¿qué entiendes tu por cargar bmps de 32 bits? yo es que no le veo más entendimiento del que le doy yo, quizás tu le veas otro.

En cuanto a codeblocks, es muy rabuo pa mí, no me gusta que me organicen los archivos según su tipo, prefiero ver la ruta real física de cada archivo en el sistema de directorios. Yo uso eclipse CDT normalmente, o bien directamente por consola el gcc. De todas formas va adjutno también el proyecto para eclipse cdt, quizás codeblocks pueda importar proyectos eclipse CDT, míralo por si acaso.
Monstruos Diabólicos

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

SplinterGU

Amask es la mascara para el canal alpha, su valor depende del tipo de profundidad grafica, hay otros A* que sirven junto al anterior para obtener/setear los valores del canal alpha, tambien existen los R*, G* y B*...

Bennu usa un sistema similar, por no decir el mismo...

No entiendo tu pregunta de "¿qué entiendes tu por cargar bmps de 32 bits?", tiene mas de un sentido/ambiguo el cargar un bmp de 32bits?... tampoco entiendo el motivo de este hilo? o mejor dicho la relacion con Bennu? estas experimentando con SDL? si es eso, entonces queda clarisimo...

por favor, no lo tomes a mal, no es ironia ni nada, es una pregunta seria... curiosidad...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

Quote from: SplinterGU on February 18, 2010, 10:54:14 PM
yo tampoco entendi mucho, cargar bmps de 32 bits?

pero como vi que se respondio solo, no dije nada...

ah, creo que tu pregunta viene por esto...

lo que quise decir fue que quizas lo que querias hacer era cargar bmps de 32 bits (en bennu, supongo)... puede que se haya entendido con que preguntaba "que es cargar bmps de 32bits?", pero no, quise decir lo primero...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

El motivo de este post, es un compendio de todo lo que dices Splinter, primeramente está relaccionado en aprender SDL, en segundo lugar en entender el uso del canal alfa, en tercer lugar no está directamente relaccionado con bennu es por eso que está en offtopic el mensaje, en cuarto lugar esta indirectamente relaccionado porque estoy barajando la posibilidad de añadir soporte de imágenes de 32 bits a mod_mappy o a otro módulo que tengo en mente.

En cuanto a lo de la prengunta de carga bmps de 32 bits. pues no pretendía cargar bmps de 32 bits con bennu, porque ya se que lo hace, por las pruebas que hice para fpgedit2009. Era a cargarlos con la API nativa de SDL 1.2.4 llamada SDL_loadBMP, pero como ya he comentado, he visto el código fuente de esa función y he visto que no estaba programado el soporte de bmps de 32 bits apreciando la componente alfa de los píxeles, que es lo que ha dado lugar a todo este hilo.
Este código adjunto, podríamos decir que es un parche para la sdl 1.2.4 para darle soporte de carga de bmps de 32 bits y como he dicho es prácticamente innecesario si vas a utilizar la librería adicional SDL_image ya que ésta tiene programado ya esto mismo internamente.

Y nada, gracias por las preguntas y respuestas y colaborar en el tema a todos :D.
Monstruos Diabólicos

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

SplinterGU

ya, trasteando con SDL... bien, ahora si me queda claro...

esta muy bueno, podrias compartir este fix con la gente de SDL...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2