Al rotar con SDL_rotozoomSurface desaparece

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

Al rotar con SDL_rotozoomSurface desaparece

Notapor Shock » Vie May 18, 2007 6:18 pm

Aiya!

Antes de todo aiya, soy nuevo aquí. Os encontré buscando info de SDL_gfx. Parecéis un grupo interesante, y sabéis lo que estáis haciendo :P.

Bueno, estoy haciendo mi primer jueguecillo con SLD. El caso es que quiero rotar una imagen al pulsar una tecla, y esto es lo que he hecho.

Código: Seleccionar todo
void Cannon::Mover(bool dir) {
   switch(dir) {
      case 0: // Gira izquierda
         superficie=rotozoomSurface(superficie,10,0,0);
         break;
      case 1: // Gira derecha
         superficie=rotozoomSurface(superficie,-10,0,0);
         break;
   }
}


Es decir, se movería 10 grados al tocar una tecla. Pero la cosa es que, en vez de girar, la imagen desaparece completamente... el blitting es así:

Código: Seleccionar todo
SDL_BlitSurface(cannon.Superficie(),NULL,Gestor::ElGestor()->Pantalla(),&cannon.Destino());


¿Qué estoy haciendo mal? Gracias :).
Shock
 
Mensajes: 3
Registrado: Vie May 18, 2007 5:41 pm
Ubicación: Málaga (España)

Notapor rcaf » Vie May 18, 2007 6:46 pm

El problema está en el valor del parámetro zoom que le pasas a la función rotozoomSurface, recuerda que su prototipo es:

SDL_Surface * rotozoomSurface (SDL_Surface *src, double angle, double zoom, int smooth);


Por lo tanto para no hacer zoom y mantener el tamaño original debes pasar el valor 1.0 en el parámetro zoom, y no 0 (por eso no la ves!), es decir:

Código: Seleccionar todo
// Girado 10 grados y tamaño original
superficie2=rotozoomSurface(superficie, 10, 1.0, 0);


Otro consejo, la superficie que devuelve la función rotozoomSurface guardala en otra superficie.

La función que utilizo para dibujar imagenes rotadas o escalas en tiempo real es la siguiente:

Código: Seleccionar todo
void DrawSurface(SDL_Surface *src, int x, int y, float zoomx, float zoomy, float angle)
{
    // Superficie temporal con las modificaciones correspondientes
    SDL_Surface *tmp;

    // Posición donde dibujaremos la superficie en pantalla
    SDL_Rect pos={x, y, 0, 0};

    // Creamos superficie rotada y/o escalada sin anti-aliasing
    tmp=rotozoomSurfaceXY(src, angle, zoomx, zoomy, 0);

    // Arreglo posición de la imagen ya que la rotación
    // es con respecto al centro de la imagen
    pos.x -= (tmp->w - src->w) / 2;
    pos.y -= (tmp->h - src->h) / 2;

    // Dibujamos en pantalla la nueva superficie
    // Nota: screen es la variable que nos devolvió
    // la función SDL_SetVideoMode
    SDL_BlitSurface(tmp, NULL, screen, &pos);

    // Eliminamos de la memoria la superficie temporal
    SDL_FreeSurface(tmp);
}


Ojo, que la función anterior puede bajar el rendimiento si es llamada demasiadas veces dentro del game loop, ya que estamos realizando constantemente cálculos de rotación y escalado, y además creando y liberando memoria para superficies.

Una posible optimización al utilizar muchas transformaciones (rotación, escalado) en un juego, es generarlas antes del ciclo y almacenarlas en varias superficies.

Saludos!
Última edición por rcaf el Vie May 18, 2007 11:51 pm, editado 1 vez en total
Roberto Albornoz Figueroa
Mi Blog
Wiki
Avatar de Usuario
rcaf
 
Mensajes: 71
Registrado: Jue Ago 10, 2006 4:35 am
Ubicación: Concepción, Octava Región. Chile

Notapor Shock » Vie May 18, 2007 7:00 pm

Aiya!

Gracias, ya sí la veo, qué torpe :P.

Ahora me pasa otra cosa. Al rotar, además de rotar, se traslada, es decir, cuando le doy a izquierda o a derecha, además de rotar, se mueve hacia abajo-derecha. He visto el ejemplo de rotar y escalar que ponéis y no pasa eso, he revisado el código pero no veo la diferencia. ¿Qué pasa?

EDITO: Ahora que lo pienso debe de ser un problema externo a eso, ya que parece que afecta al rectángulo de destino, no a la superficie... Voy a ver.

EDITO 2: Pues parece que no es de los rectángulos destino... la verdad, no sé de qué es ._.
Shock
 
Mensajes: 3
Registrado: Vie May 18, 2007 5:41 pm
Ubicación: Málaga (España)

Notapor rcaf » Vie May 18, 2007 11:53 pm

Mira el código de arriba de nuevo, lo actualicé.

Me faltaba el código donde se modifica la posición de la imagen, de esta forma la rotación es con respecto al centro de la imagen.

S2!
Roberto Albornoz Figueroa
Mi Blog
Wiki
Avatar de Usuario
rcaf
 
Mensajes: 71
Registrado: Jue Ago 10, 2006 4:35 am
Ubicación: Concepción, Octava Región. Chile

Notapor Shock » Mar May 22, 2007 4:40 pm

Aiya!

No hay manera... he mirado por todos lados y no encuentro ningún error. Además de girar con el centro, se desplaza hacia arriba-izquierda cada vez que se mueve. Vamos a ver paso por paso:

Código: Seleccionar todo
Cannon::Cannon() {
superficie=Gestor::ElGestor()->CargarImagen("img/cannon.bmp",1);
   superficie_orig=superficie;
   
   dest.x=320;
   dest.y=240;
   dest.w=0;
   dest.h=0;
}


Este es el constructor de la clase Cannon, que tiene una instancia cannon. Es un cañón que gira dándole a los lados. dest es un SDL_Rect, como pos en tu código.

Código: Seleccionar todo
void Cannon::Mover(bool dir) {
   switch(dir) {
      case 0: // Gira izquierda
         superficie=rotozoomSurface(superficie_orig,10.0,1.0,1);
         break;
      case 1: // Gira derecha
         superficie=rotozoomSurface(superficie_orig,-10.0,1.0,1);
         break;
   }
   
   dest.x-=(superficie->w-superficie_orig->w)/2;
   dest.y-=(superficie->h-superficie_orig->h)/2;
}


Según la dirección a la que se mueve, se mueve 10 o -10 grados... no veo ningún error... al final he añadido lo del centro.

Código: Seleccionar todo
SDL_BlitSurface(cannon.Superficie(),NULL,Gestor::ElGestor()->Pantalla(),&cannon.dest);


El blitting... no tiene mucho secreto. cannon.Superficie() devuelve la variable superficie.

Me estoy desesperando porque no encuentro el fallo... ¿Alguna idea? ¿Algo? Gracias :).[/code]
Shock
 
Mensajes: 3
Registrado: Vie May 18, 2007 5:41 pm
Ubicación: Málaga (España)


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

cron