Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Canal Alpha En Sdl

Iniciado por AgeR, 07 de Marzo de 2006, 11:22:00 PM

« anterior - próximo »

AgeR

 Hola, me ha surgido el siguiente problema usando SDL.
Cargo una imagen con varios frames con transparencia con IMG_Load() en una surface.
En un momento dado quiero copiar un frame a una surface nueva, es decir, la creo primero con SDL_CreateRGBSurface del tamaño del frame, y después hago un SDL_BlitSurface cogiendo el frame que quiero.

Bien el problema es que al ir a mostrar ese nuevo surface, no me aparece nada en pantalla. El surface original es de 32 bits, ya que es un png con transparencia, el que se crea lo creo también de 32 bits con transparencia. Al hacer el Blit, debería quedarme en el nuevo surface el frame deseado con su transparencia, pero parece que no es así, o hay algo que no hago bien.

A ver si esos expertos en SDL me echan una mano  :lol: .

Código aproximado:

//Surface con todos los frames
aux = IMG_Load(strName);
aux2 = SDL_DisplayFormatAlpha(aux);
SDL_FreeSurface(aux);
// Surface nuevo, de w*h pixels, 32 bits, canal alpha, etc... (como viene en la docu de SDL).
aux3 = SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA|SDL_RLEACCEL, w, h, 32,
                                 rmask, gmask, bmask, amask);
m_Surface = SDL_DisplayFormatAlpha(aux3);

//Bliteamos (las coordenadas y demas estan bien)
SDL_BlitSurface(aux2, &orig, m_Surface, &dest);

Sacrifai

 Yo no soy un experto en SDL  :lol:  y no se me ocurre porqué no puede funcionar. ¿Has comprobado que el SDL_DisplayFormatAlpha no te devuelve NULL?
Otra cosa, en
aux3 = SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA|SDL_RLEACCEL, w, h, 32, rmask, gmask, bmask, amask);
prueba a colocar los mask iguales a los que uses para la superficie que vas a blitear ( no se si es lo que haces ya ) surface->format->rmask...

PD: Espero que te sirva de algo.

TheAzazel

 Me da en la nariz que vien por el SDL_SRCALPHA... porque no calcas el mismo mismisimo formato de la surface cargada?, un atajo en vez de hacerlo con SDL_CreateRGBSurface() y un monton de parametros...utiliza esto:


//Surface con todos los frames
aux = IMG_Load(strName);


// Surface nuevo, de w*h pixels, 32 bits, canal alpha, etc... (como viene en la docu de SDL).
aux3=SDL_ConvertSurface(aux,aux->format,aux->flags);

// Conversiones y liberamos antiguas
m_Surface = SDL_DisplayFormatAlpha(aux3);
SDL_FreeSurface(aux3);
aux2 = SDL_DisplayFormatAlpha(aux);
SDL_FreeSurface(aux);

//Bliteamos (las coordenadas y demas estan bien)
SDL_BlitSurface(aux2, &orig, m_Surface, &dest);


Con eso, te deberia funcionar, por supuesto yo añadiria una comprobacion en cada creacion/conversion de surface para asegurarme que no me viene un NULL y que la cosa pete.

Let me know it that works! :)

nsL

 Yo te informo que nunca fui capaz de conseguir hacer un blit sobre una surface creada por mi mismo :P

Tampoco me comi mucho el coco, pero no me salia na de na como a ti.

Saludos!
Yo no muero hasta la muerte -

AgeR

 TheAzazel: Pero de ese modo estoy creando una surface de igual tamaño a la anterior, no? Yo lo que quiero es una surface del tamaño justo de un único frame, no copiarla completamente. Por lo que he visto con SDL_ConvertSurface no hay forma de decirle la parte que quieres copiar.

TheAzazel

 Si, ese detalle se me escapo...

pero...para que quieres crear una superficie solo del tamaño del frame??? es mejor que dejes todos los frames en la superficie original y vayas volcando cada frame usando unos rect...

ahora mismo estoy que me caigo de sueño, pero mañana si no has dado con ello antes lo pruebo, en tu codigo ya te dije que me huele mal el SDL_SRCALPHA (y ademas, junto con el SDL_HWSURFACE... esos dos flags... digamos que no se llevan muy bien jeje y te ira la cosa muy lenta), prueba a quitarlo y dejar solo un SDL_SWSURFACE.

a ver si te rula asi...

AgeR

Cita de: "TheAzazel"pero...para que quieres crear una superficie solo del tamaño del frame??? es mejor que dejes todos los frames en la superficie original y vayas volcando cada frame usando unos rect...
Bueno, hasta ahora lo tenía así, el problema viene a la hora de hacer rotaciones. Teniendo los frames por separado, con un simple rotozoomSurface tengo ese frame rotado. Si los tengo todos juntos esto no se puede hacer (creo).

Voy a seguir peleándome un rato a ver si lo consigo  :angry: .

javiel

 Te voy a poner como lo hago yo. Yo lo uso pq cuando tengo un SDL_Surface creado de un PNG, si tiene partes transparentes, no puedo usar SDL_SetAlpha. Así que creo un sdl_Surface_copy, el pongo un color cantoso (255, 0, 255) y luego lo elimino con SetColorKey, y ya está.

El único problema es cuando tienes partes semitransparente, como por ejemplo sombras, que se ve el color ese un poco. Eso problema lo arreglé un poco hace un tiempo, pero no encuentro el código.

Bueno a ver si esto te ayuda

 
SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (aux->flags,
  aux->w, aux->h, aux->format->BitsPerPixel,
  aux->format->Rmask, aux->Gmask,
  aux->format->Bmask,
  0);
int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
SDL_FillRect(sdl_surface_copy, NULL, colorkey);
SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);

SDL_BlitSurface(aux, NULL, sdl_surface_copy, NULL);
SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
SDL_BlitSurface (sdl_surface_copy, &src, superficie_pantalla, &dest);


superficie_pantalla, es el screen de la pantalla para ya "pegarlo" en ella

saludos
uper-Tirititran: el superhéroe gaditano (http://www.super-tirititran.com)

AgeR

Cita de: "javiel"El único problema es cuando tienes partes semitransparente, como por ejemplo sombras, que se ve el color ese un poco. Eso problema lo arreglé un poco hace un tiempo, pero no encuentro el código.
Ese es precisamente el problema, igual no me he expresado bien  (nooo) .
Si la transparencia es total, se hace bien, de hecho tengo un sprite que tiene el fondo transparente y va bien. El problema viene cuando quiero tener partes semitransparentes, que la imagen no se dibuja.

Estoy haciendo un efecto de brillo semitransparente y quiero que pueda aparecer en diferentes lugares, respetando lo que tenga detrás.

Una posibilidad sería ir pixel a pixel tomando el color de una imagen y otra, pero creí que habría una forma más simple de hacerlo.  :(  

TheAzazel

 te refieres a cuando la superficie tiene alpha per pixel no?






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.