| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
mamntc02
Registrado: 30 Abr 2007 Mensajes: 277
| Publicado: 21/08/2007 4:36 am | | | Título: Cargar y mostrar BMPs con SDL |
| Hola de nuevo,
Vuelvo a estar bloqueado, supongo q me faltan ciertos conceptos básicos de la SDL y de como pinta. Ahí va mi duda: Estoy cargando una imagen de fondo (ningún problema en esto), y luego estoy cargando una serie de bolas, estas bolas las he hecho con Photophop y no son nada más q una imagen transparente de 30x30 px, añadiendo un círculo pintado encima. Bueno ahora quiero poner encima de la imagen de fondo cada bola, separada por 30px. Pues resulta q sólo me muestra la primera de ellas y sólo 1/4 de bola (la q correspondería al segundo cuadrante, no se si me explico). Este es el código q uso:| Código: |
SDL_Surface** ball = NULL; //Es una variable global const int PB_BALLS_PER_ROW = 8;
int loadBalls(const char* filename){ SDL_Rect offset; ball = new SDL_Surface*[8]; // Allocate 8 balls if (!ball){ fprintf(stderr, "Cannot allocate balls\n"); return -1; } // We load balls for(int i = 0; i < PB_BALLS_PER_ROW; i++){ ball[i] = SDL_LoadBMP(filename); if(!ball[i]) { fprintf(stderr, "Unable to Load ball %d in file %s\n", i, filename); return -1; } } // Drawing balls for (int i = 0; i < PB_BALLS_PER_ROW; i++){ offset.x = 15 + 30*i; offset.y = 15;
if(SDL_BlitSurface(ball[i], NULL, screen, &offset) < 0){ fprintf(stderr, "BlitSurface error on Ball %d: %s\n", i, SDL_GetError()); return -1; } SDL_UpdateRect(screen, 0, 0, ball[i]->w, ball[i]->h); } return 0; }
|
Creo q no acabo de tener claro q hace la función SDL_BlitSurface, y creo q también confundo las funciones q muestran o actualizan la pantalla, como SDL_UpdateRect ó SDL_Flip. Alguien me puede hacer alguna aclaración sobre esto o decirme donde está bien explicado. Tengo los manuales de SDL, pero no acabo de entender quien dibuja exactamente.
Muchas gracias.
PD: Por cierto, para empezar con la programación gráfica, estoy haciendo un Puzzle Bubble. Os acordais? Hehehe.... De momento, quiero hacer más o menos algo parecido al original, pero después tengo ciertas ideas de como mejorarlo..... Ya iré taladrando  |
| | Volver arriba | |  | _Martin_

Registrado: 03 Ago 2006 Mensajes: 165
| Publicado: 21/08/2007 5:27 am | | | Título: |
| Hola, bueno resulta que tienes un pequeño error en donde dice
| Código: | SDL_UpdateRect(screen, 0, 0, ball[i]->w, ball[i]->h);
|
Esta funcion actualiza la pantalla (screen) pero no la actualiza toda, sino que actualiza un rectangulo. Comenzando desde la posicion X e Y (en tu caso es 0;0) hasta alcanzar un ancho W y un alto H (en tu caso ball[i]->w y ball[i]->h)
Es aqui donde esta el error por que siempre acualizas el mismo rectangulo!!. Si bien los parametros W y H varian, los parametros X e Y no lo hacen!. Deberias poner algo asi
| Código: | SDL_UpdateRect(screen, offset.x, offset.y, ball[i]->w, ball[i]->h);
|
Otra cosilla, donde dice
| Código: | ball = new SDL_Surface*[8]; |
reempalzalo por
| Código: | ball = new SDL_Surface*[PB_BALLS_PER_ROW]; |
Saludos
Edito: Por si te interesa es una pagina que te puede resulatar utili, sobretodo el primer link. Si estas aprendiendo SDL a traves de internet me gustaria que me pases el link de tu curso para verlo.[/url] |
| | Volver arriba | |  | Killrazor
Registrado: 24 Ene 2006 Mensajes: 1182 Ubicación: Barcelona
| Publicado: 21/08/2007 6:05 am | | | Título: |
| | Código: | for(int i = 0; i < PB_BALLS_PER_ROW; i++){ ball[i] = SDL_LoadBMP(filename); if(!ball[i]) { fprintf(stderr, "Unable to Load ball %d in file %s\n", i, filename); return -1; } }
|
Se puede saber por que cargas 8 veces la misma imagen? Muy ineficiente
| Código: | ball = new SDL_surface; // We load balls ball = SDL_LoadBMP(filename); if(!ball[i]) { fprintf(stderr, "Unable to Load ball %d in file %s\n", i, filename); return -1; } // Drawing balls for (int i = 0; i < PB_BALLS_PER_ROW; i++){ offset.x = 15 + 30*i; offset.y = 15;
if(SDL_BlitSurface(ball, NULL, screen, &offset) < 0){ fprintf(stderr, "BlitSurface error on Ball %d: %s\n", i, SDL_GetError()); return -1; } SDL_UpdateRect(screen, 0, 0, ball[i]->w, ball[i]->h); } return 0; |
Yo creo que esto te deberia funcionar (lo he escrito a saco, sin probar, asi que puede dar problemas de compilacion pero creo que captas la idea ). Carga una sola vez la imagen y asignala. Recuerda que puedes escribir la misma imagen varias veces y no cargarla varias veces. _________________ I wanna heal i wanna feel like I'm close to something real. I wanna find something I've wanted all along somewhere i belong |
| | Volver arriba | |  | | mamntc02
Registrado: 30 Abr 2007 Mensajes: 277
| Publicado: 22/08/2007 12:07 am | | | Título: |
| Muchas gracias a ambos.
| _Martin_ escribió: | Es aqui donde esta el error por que siempre acualizas el mismo rectangulo!!. Si bien los parametros W y H varian, los parametros X e Y no lo hacen!. Deberias poner algo asi
| Código: | SDL_UpdateRect(screen, offset.x, offset.y, ball[i]->w, ball[i]->h);
|
|
Me ha funcionado perfectamente. Respecto lo q me comentas a la hora de reservar memoria ya soy consciente, ya q programar sí q sé , pero como estoy empezando un poco a trozos en esto de la programación gráfica, hay cosas q las pongo a saco. Igualmente se agracede pq es muy buen consejo.
| _Martin_ escribió: | | Por si te interesa es una pagina que te puede resulatar utili, sobretodo el primer link. Si estas aprendiendo SDL a traves de internet me gustaria que me pases el link de tu curso para verlo |
Muy interesante la URL. No estoy siguiendo ningun curso. Simplemente me he bajado la librería, su FAQ y su API. También me ayudo de una web q encontré en el sitio web de SDL, sección de tutoriales, q encuentro sencillo y fácil de seguir: http://lazyfoo.net/SDL_tutorials/index.php. Pero lo q es curso no sigo ninguno.
| Killrazor escribió: | | Se puede saber por que cargas 8 veces la misma imagen? Muy ineficiente |
Hehe, me lo imagino. Luego lo estuve pensando, pero de momento como estoy haciendo casi 'copy&paste' de lo q voy encontrado por manuales y tutoriales y no acostumbran a cargar ni mostrar la misma imagen varias veces, pues lo hice así. Por eso prengunté q hace exactamente q hacen SDL_BlitSurface ó SDL_UpdateRect, es decir quién pinta, quién actualiza, etc.... Tu ejemplo no lo acabo de entender. Creas una SDL_Surface sin definir tamaño, pero accedes al elmento i-ésimo? Pero si no lo tienes!!! Después haces lo mismo q yo pongo en el ejemplo, con lo q siempre pintas en la misma posición (sin tener en cuenta q no tienes ball[i]). No debo haberme explicado bien lo q quería hacer: Tengo una ventana de 480x640, y desde la posición (15, 15) de la pantalla (empezando arriba - izquierda), pinto una bola (de 30px de diámetro), luego pinto otran en la posición (45,15), etc... así hasta pintar 8 bolas. Ya las centraré más adelante. Ahora lo q estoy aprendiendo a moverme dentro de la librería y a hacer cosas.
Bueno lo dicho, muchas gracias y saludos. |
| | Volver arriba | |  | _Martin_

Registrado: 03 Ago 2006 Mensajes: 165
| Publicado: 22/08/2007 6:10 am | | | Título: |
| Hola, en el codigo de Kill, la primera parte, él reserva memoria para una superficie con new. Segun la documentacion de SDL, es preferible dejar que SDL reserve la memoria:
| Código: | SDL_Surface *img; img=SDL_LoadBMP("lala.bmp");
|
Tambien hay un pequeño error en SDL_UpdateRect ya que esta funcion tiene como objetivo "refrescar la pantalla" (en realidad podria refrescar cualquier superficie). Pero no la refresca en su totalidad sino que refresca un cuadrado cuyo vertice superior izquierdo es XY, extendiendose a lo ancho y alto (W y H) En la funcion de Kill, se varia los valores W y H pero no los X e Y
Saludos |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |