Manejar transparencias en elementos SDL_Rect

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

Manejar transparencias en elementos SDL_Rect

Notapor dehm » Dom Abr 28, 2013 12:15 am

Hola:

Desde hace una semana que os he descubierto, os he estado leyendo, y ha llegado la hora de escribir por fin para plantearos una duda.

El caso es que estaba haciendo un juego (un tetris, original que es uno) y quería implementar algo de transparencia para el diseño de cada pieza.
La idea es que cada cuadrito sea un SDL_Rect, y añadir en los bordes unas líneas a modo de chaflán (me explico como un libro cerrado). Esas líneas deberían ser de color blanco o negro, según la zona.....y semitransparentes, para que dejen ver el color de la pieza.

Pero no lo consigo.
Hago esto:
Código: Seleccionar todo
SDL_FillRect(fondo,&chaflan[i],SDL_MapRGBA(fondo->format,255,255,255,X));
(con X el valor de la transparencia), pero no me hace nada.

Por otro lado, la otra función que se encarga de estas cosas (SDL_SetAlpha) es para imágenes de ficheros, y no es lo que busco.

Ya se me han acabado las pocas ideas que tengo :)

Creo que lo he puesto en el subforo adecuado, pero si no es así, ruego lo mováis a donde corresponda.
dehm
 
Mensajes: 2
Registrado: Sab Abr 27, 2013 8:01 pm

Re: Manejar transparencias en elementos SDL_Rect

Notapor Barajas » Lun Abr 29, 2013 3:12 am

dehm escribió:La idea es que cada cuadrito sea un SDL_Rect, y añadir en los bordes unas líneas a modo de chaflán (me explico como un libro cerrado). Esas líneas deberían ser de color blanco o negro, según la zona.....y semitransparentes, para que dejen ver el color de la pieza.

Pero no lo consigo.
Hago esto:

Código: Seleccionar todo
SDL_FillRect(fondo,&chaflan[i],SDL_MapRGBA(fondo->format,255,255,255,X));

(con X el valor de la transparencia), pero no me hace nada.

Por otro lado, la otra función que se encarga de estas cosas (SDL_SetAlpha) es para imágenes de ficheros, y no es lo que busco.


El problema con SDL_FillRect es que ignora el canal alfa del color. Sí quieres hacerlo trasparente, tendrás que hacerlo con blit. Creas una superficie que permita el color alpha, después, llenarla del color, ponerle un valor alfa, y después dibujarla.

Aquí te dejo un código que hace eso, recuerda que si usas windows, modificar los includes y el main. Espero te sea útil.

using namespace std;
#include <SDL/SDL.h>
#include <stdio.h>
#include <iostream>
//constantes utiles...
const int PROFUNDIDAD = 32;
SDL_Surface * PANTALLA;
//algunos colores predefinidos...
const SDL_Color BLANCO = {255,255,255};
const SDL_Color VERDE = {0,255,0};
const SDL_Color AZUL = {0,0,255};
const SDL_Color ROJO = {255,0,0};
const SDL_Color AMARILLO = {255, 255, 0};
const SDL_Color GRIS = {(3*255)/4,(3*255)/4,(3*255)/4};
const SDL_Color GRIS2 = {(2*255)/4,(2*255)/4,(2*255)/4};
const SDL_Color GRIS3 = {255/4,255/4,255/4};
const SDL_Color NEGRO = {0,0,0};
const SDL_Color MAGENTA = {255, 0, 255};
//algunas cosas para frame rate
Uint32 waittime = 1000/60;
Uint32 framestarttime = 0;
Sint32 delaytime;
float SpeedFactor = 1;
//defino las variables para la entrada...
Uint8 *keys;
SDL_Event event;



//los prototipos de funciones que utilizaremos en este ejemplo...
SDL_Surface * Crea_superficie(int, int);
//llenar una surface de un color un color espesifico...
void fill(SDL_Surface *, SDL_Color);
void fill(SDL_Surface *, SDL_Color, SDL_Rect);
//dibujar una superficie en pantalla
void dibuja_surface(SDL_Surface *, SDL_Surface *, int, int);
void dibuja_surface(SDL_Surface *, SDL_Surface *, SDL_Rect, int, int);

int main(void){
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "No se pudo inicializar SDL" << endl;
exit(1);
}
int H = 200; //alto
int W = 220; //ancho
cout << "SDL iniciado " << endl;
// Activamos modo de video
PANTALLA = SDL_SetVideoMode(W,H,PROFUNDIDAD,SDL_DOUBLEBUF|SDL_HWSURFACE|SDL_ANYFORMAT);
if (PANTALLA == NULL) {
cout << "No se pudo crear la pantalla" << endl;
exit(1);
}
SDL_WM_SetCaption("Ejemplo",NULL);
//cremos las imagenes que usaremos...
//ancho, alto
SDL_Surface * image1 = Crea_superficie(100,100);
SDL_Surface * image2 = Crea_superficie(100,100);
SDL_Surface * image3 = Crea_superficie(100,100);
//las llenamos de un color que nos interese...
fill(image1,ROJO);
fill(image2,VERDE);
fill(image3,AZUL);
//el valor alfa...

int alpha = 120;
int aumento_alpha = 1;

bool done = false;
//_______________________________________
while(!done){
//lo siguiente mantiene el framerate constante...
delaytime = waittime - (SDL_GetTicks() - framestarttime);
if(delaytime > 0){
SDL_Delay((Uint32)delaytime);}
framestarttime = SDL_GetTicks();
//revisamos los eventos de entrada al sistema....
keys=SDL_GetKeyState(NULL);
while ( SDL_PollEvent(&event) ) {
if ( (event.type == SDL_KEYDOWN && keys[SDLK_ESCAPE]) || (event.type == SDL_QUIT) ){
done = 1;
}
}

//aumentamos el color alpha...
if(alpha<=0 || alpha>=255){
//si se pasa del los valores del alpha
//hacemos que cambie la direccion...
aumento_alpha = -aumento_alpha;
}
alpha+=aumento_alpha;

//les colocamos el valor de la trasparencia, o alfa
SDL_SetAlpha(image1,SDL_SRCALPHA,alpha);
SDL_SetAlpha(image2,SDL_SRCALPHA,alpha);
SDL_SetAlpha(image3,SDL_SRCALPHA,alpha);

//pintamos el fondo...
fill(PANTALLA, BLANCO);
//dibujamos las imagenes...
dibuja_surface(PANTALLA,image1,0,0);
dibuja_surface(PANTALLA,image2,75,50);
dibuja_surface(PANTALLA,image3,120,0);
SDL_Flip(PANTALLA);
}
//liberamos las imagenes...
SDL_FreeSurface(image1);
SDL_FreeSurface(image2);
SDL_FreeSurface(image3);
SDL_Quit();

return 1;
}

//el codigo de las funciones..

//--------------------------------------------

SDL_Surface * Crea_superficie(int w, int h){
SDL_Surface * temp;
//cout << ">> La imagen se esta creando..." << endl;
//usamos a pantalla como imagen de referencia...
temp = SDL_CreateRGBSurface(PANTALLA->flags, w, h, PANTALLA->format->BitsPerPixel, PANTALLA->format->Rmask, PANTALLA->format->Gmask, PANTALLA->format->Bmask, PANTALLA->format->Amask);
if(temp == NULL) {
cout << ">> No se pudo crear la imagen CreateRGBSurface FALLO: ";
cout << "... **\n\tInfo ERROR SDL:\t"<< SDL_GetError() << "\n... **" <<endl;
exit(1);
}
return temp;
};

//-----------------------------------------------------------

void fill(SDL_Surface * surf, SDL_Color color) {
//cout << ">> La imagen se llena de color " << surf->w << endl;
SDL_Rect Rect = {0,0,surf->w,surf->h};
SDL_FillRect(surf, &Rect, SDL_MapRGBA(surf->format,color.r,color.g,color.b,255) );
};
void fill(SDL_Surface * surf, SDL_Color color, SDL_Rect rect){
SDL_FillRect(surf, &rect, SDL_MapRGBA(surf->format,color.r,color.g,color.b,255) );
};

//-----------------------------------------------------------

void dibuja_surface(SDL_Surface * pantalla, SDL_Surface * image, int x, int y){
if(image != NULL){
SDL_Rect __Rect;
SDL_Rect __Pos;
__Rect.x = 0;
__Rect.y = 0;
__Rect.w = image->w;
__Rect.h = image->h;

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

SDL_BlitSurface(image, &__Rect, pantalla, &__Pos);
}
}
void dibuja_surface(SDL_Surface * pantalla, SDL_Surface * image, SDL_Rect __Rect, int x, int y){
if(image != NULL){
SDL_Rect __Pos;

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

SDL_BlitSurface(image, &__Rect, pantalla, &__Pos);
}
}
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: Manejar transparencias en elementos SDL_Rect

Notapor dehm » Lun Abr 29, 2013 10:35 am

Gracias Barajas:

Me has ayudado mucho más de lo que me merecía. :-)

La explicación de 10.

Saludos y gracias de nuevo!!
dehm
 
Mensajes: 2
Registrado: Sab Abr 27, 2013 8:01 pm


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados