Ver la versión completa : Dudas de un novato en SDL
Puck2099
16/09/2005, 12:57
Hola,
Bueno, en lugar de inundar el foro con un tema nuevo cada vez que me surja una duda, he pensado que sería mejor ir posteando aquí todas las que vayan saliendo y así, además de que lo tenemos más ordenado, puede postear toda la gente con dudas sobre el SDL.
Bueno, aquí va mi primera duda, ésta muy sencillita: las imágenes que se carguen en un array de char, dentro de un fichero .h, ¿tienen que estar rotadas como en el SDK oficial?
Gracias :)
Bueno, aquí va mi primera duda, ésta muy sencillita: las imágenes que se carguen en un array de char, dentro de un fichero .h, ¿tienen que estar rotadas como en el SDK oficial?
En SDL lo mejor es meter en memoria el PNG tal cual, comprimido. Puedes utilizar un programita que convierte imagenes (png entre otras) a bin (vamos a arrais)
Y luego usar las funciones Load_PNG_fromMem o algo asi para cargar el png a una SDL_Surface.
Si usas las funciones de SDL para cargar imagenes no necesitas preocuparte por rotarlas ;)
Aiken
Puck2099
16/09/2005, 13:18
En SDL lo mejor es meter en memoria el PNG tal cual, comprimido. Puedes utilizar un programita que convierte imagenes (png entre otras) a bin (vamos a arrais)
Y luego usar las funciones Load_PNG_fromMem o algo asi para cargar el png a una SDL_Surface.
Si usas las funciones de SDL para cargar imagenes no necesitas preocuparte por rotarlas ;)
Aiken
Es buena idea, lo que pasa es que prefiero probar con una imagen no comprimida para comparar la velocidad pintando esa imagen con el SDK oficial y la misma imagen.
Para esto me valdría con usar un Load_BMP_fromMem, ¿no?
EDITO: Por cierto, ¿algún programa para Linux que convierta binarios en arrays de caracteres? :)
Saludos
Es buena idea, lo que pasa es que prefiero probar con una imagen no comprimida para comparar la velocidad pintando esa imagen con el SDK oficial y la misma imagen.
Para esto me valdría con usar un Load_BMP_fromMem, ¿no?
EDITO: Por cierto, ¿algún programa para Linux que convierta binarios en arrays de caracteres? :)
Saludos
bin2c?
Aiken
Para cargar la imágen desde el array
IMG_Load_RW(SDL_RWFromMem(&nombredeimagen,peso_de_imagen),0);
Para Linux tambien puedes usar Gimp, y salvar como *.c o *.h entre otros.
Puck2099
24/09/2005, 06:10
Otra duda, ¿cómo se manejan paletas e imágenes de 8 bits con el SDL?, ¿basta con usar SDL_SetPalette para definir la paleta y ya podemos "pintar" imágenes igual que con las de 16 bits?
Otra duda, ¿cómo se manejan paletas e imágenes de 8 bits con el SDL?, ¿basta con usar SDL_SetPalette para definir la paleta y ya podemos "pintar" imágenes igual que con las de 16 bits?
Si, supongo que si, de hecho yo siempre trabajo con 8bits asi que no se si con 16bit es igual :D
Aiken
Puck2099
24/09/2005, 06:31
Si, supongo que si, de hecho yo siempre trabajo con 8bits asi que no se si con 16bit es igual :D
Aiken
Aiken, ¿tienes un ejemplillo a mano en el que uses 8 bits para echarle un vistazo? :)
Gracias
:brindis: Algo asi:
title_scrdata = LoadImg("DATA\\TITLE.PNG");
plt = title_scrdata->format->palette;
SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, plt->colors, 0, 256);
La funcion LoadImg creo que es mia pero lo unico que hace por dentro es un loadpng (o como se llame :D) de SDL
Aiken
Puck2099
24/09/2005, 08:20
Para cargar la imágen desde el array
IMG_Load_RW(SDL_RWFromMem(&nombredeimagen,peso_de_imagen),0);
El peso de la imagen se da en bytes, ¿no?
Es que no consigo que funcione, modificando el ejemplo de sdlsega tengo lo siguiente:
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_mixer.h>
#ifdef GP32
#include <x_gp32.h>
#endif
#include "data.h"
#include "avionyazafata.h"
SDL_Surface *screen, *image;
Mix_Chunk *sound;
void waitEvent(void)
{
SDL_Event event;
while(SDL_PollEvent(&event))
SDL_Delay(10);
while(!SDL_PollEvent(&event))
SDL_Delay(100);
}
int main(int argn, char **argv)
{
#ifdef GP32
x_gp32_SetCPUSpeed_133();
#endif
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO))
return -1;
else
{
screen=SDL_SetVideoMode(320,240,8,SDL_HWSURFACE|SD L_DOUBLEBUF);
if (screen==NULL)
return -2;
else
{
int i;
SDL_Color colors[256];
for (i=0; i<256; i++) {
colors[i].r = header_data_cmap[i][0];
colors[i].g = header_data_cmap[i][1];
colors[i].b = header_data_cmap[i][2];
}
SDL_SetPalette(screen,SDL_LOGPAL|SDL_PHYSPAL,color s,0,256);
SDL_Surface *tmp=IMG_Load_RW(SDL_RWFromMem(&header_data,76800),0);
//SDL_Surface *tmp=SDL_LoadBMP("avionyazafata.bmp");
image=SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);
if (Mix_OpenAudio(44100, AUDIO_S16, 2, 512))
return -3;
else
{
SDL_Rect r;
sound=Mix_LoadWAV_RW(SDL_RWFromMem(&data_sound,SOUND_LEN),0);
Mix_PlayChannel(-1,sound,0);
r.w=320;
r.h=240;
r.x=0;
r.y=0;
SDL_FillRect(screen,NULL,0);
SDL_Flip(screen);
SDL_Delay(600);
SDL_BlitSurface(image,NULL,screen,&r);
SDL_Flip(screen);
waitEvent();
}
}
}
SDL_Quit();
return 0;
}
Pues bien, al cargar la imagen así me peta (me da un "segmentation fault"), sin embargo al comentar la línea en que la cargo y descomentar la de debajo, cargando directamente el bmp, sí que funciona.
El archivo avionyazafata.h lo he obtenido con el Gimp, mide 320x240 y es tal que:
static char header_data[] = {
75,57,57,100,99,75,100,57,82,141,141,141,141,82,14 1,141,
141,141,171,141,141,141,82,141,82,57,57,57,82,82,8 2,57,
57,57,57,100,57,57,100,100,57,100,100,100,99,99,99 ,99,
100,99,99,99,100,100,100,75,58,58,75,99,100,100,10 0,100,
100,100,75,75,75,99,99,75,75,179,58,142,45,161,161 ,161,
45,142,142,59,60,45,142,179,179,142,179,142,142,59 ,142,45,
142,142,184,60,61,179,147,142,179,184,59,142,179,1 42,184,60,
45,179,142,45,61,60,59,61,45,184,180,180,45,145,14 5,61,
61,59,60,59,142,142,142,142,147,180,179,142,121,12 1,121,60,
61,145,145,143,103,103,143,179,177,179,179,75,75,7 5,99,44,
99,99,44,99,44,44,44,44,44,44,82,82,82,82,56,56,
56,56,44,44,58,179,58,142,102,101,142,99,44,142,17 9,180,
101,58,142,179,58,82,44,99,99,99,99,56,56,56,56,56 ,
56,99,176,56,56,56,56,99,99,56,56,99,58,180,176,99 ........
¿Alguna idea de qué puede estar fallando?
En el archivo avionyazafata.h entre los corchetes creo que debería ir el peso de la imagen, quedando de este modo:
static char header_data[76800] = {
Puck2099
24/09/2005, 18:29
En el archivo avionyazafata.h entre los corchetes creo que debería ir el peso de la imagen, quedando de este modo:
static char header_data[76800] = {
Que va tío, eso también lo probé y sigue igual... ¿podría ser porque los valores de los colores de los pixels van en decimal en vez de hexadecimal? es que es lo único que se me ocurre...
Has probado con la misma imagen convertida con el GpBinConverter?
Puck2099
24/09/2005, 20:17
Has probado con la misma imagen convertida con el GpBinConverter?
¿El de Aquafish?, acabo de convertirla, voy a probar y te cuento.
Lo malo es que no hay versión linux y me toca estar arrancando el Windows para convertir imágenes...
Sí, él de Aquafish. Mira en el SDK replacement de Mirko, en el directorio de los ejemplos, creo recordar que había una utilidad que hacía lo mismo, y que además traía el código.
Supongo que os referis a este. Yo hasta que no use este no me funcionaba, probe con todo tipo de cosas :( :brindis:
Aiken
Puck2099
25/09/2005, 04:01
Supongo que os referis a este. Yo hasta que no use este no me funcionaba, probe con todo tipo de cosas :( :brindis:
Aiken
Nada, he probado con eso y tampoco... :(
Please, ¿podríais ponerme un ejemplo en el que se muestre un bmp que previamente ha sido convertido en un .h con ese programa?
Osea, no quiero cargar un bmp del disco, sino de la memoria.
Muchas gracias :)
Usando el gpbinconv yo los cargo de la siguiente forma
SDL_Surface *fondo;
SDL_Surface *tmp;
tmp=IMG_Load_RW(SDL_RWFromMem(&fondo_juego,1106036),0);
fondo=SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);
Renderiza( &fondo, pantalla);
Renderiza es una funcion mia, q no es mas q el blitsurface
http://ltkdemos.sourceforge.net/articulos/1_articulos.htm
No esta actualizado a la última versión de las SDL de Chui, por lo que:
Olvida:
#include <gpstdio.h>
#include <gpstdlib.h>
#include <gpgraphic.h>
#include <gpfont.h>
Y la ruta no es gp://, sino gpmm/
Puck2099
26/09/2005, 04:33
Hola de nuevo,
Ya he conseguido que me funcione con lo que me ha comentado Eskema y LTK666, pero sigo con problemas al intentar "encapsular" ese trozo de código en una función.
He definido la función:
void Blit (SDL_Surface * src, int x, int y, int w, int h, int x2, int y2, unsigned char * imagen, int tam) {
SDL_Surface *tmp=IMG_Load_RW(SDL_RWFromMem(&imagen, tam),0);
src=SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_Rect dest2;
dest2.w=w;
dest2.h=h;
dest2.x=x2;
dest2.y=y2;
SDL_BlitSurface(src, &dest2, screen ,&dest);
}
Pero cuando la llamo con un:
Blit (back, 0, 0, 320, 240, 0, 0, (unsigned char *) splash, 77880);
Me salta el "segmentation fault" de rigor, ¿alguna idea?
Gracias
Aprovecho este hilo porque yo también soy un novato con el SDL y estoy teniendo problemas con el sonido del xrick:
¿Hay alguna forma de que se grabe en la gp32 el fichero stderr.txt? Porque me estoy volviendo loco y sin saber qué es lo que va mal no voy a ninguna parte :(
Creo q te complicas mucho la vida con esa funcion, de hecho por lo que veo y q alguien me corrija, estas cargando la imagen a la vez que la intentas blitear por pantalla, supongo q de ahi el error. La imagen has de cargarla en otra funcion y en el blit pues simplemente eso blitear la imagen que previamente has cargado. Aqui te paso mi codigo supersecretotelojuroporsnoopy, y me funciona
//función para el renderizado de imágenes estáticas
void Renderiza(tObjeto *obj, SDL_Surface *salida)
{
SDL_Rect dest;
if (obj)
{
dest.x = obj->x;
dest.y = obj->y;
dest.w = obj->ancho;
dest.h = obj->alto;
SDL_BlitSurface(obj->imagen, NULL, salida, &dest);
}
}
tobjeto es un struct donde cargo la imagen que quiero e inicializo sus propiedades para el juego, ya sabes, vidas, x,y, movimientos y demas cosas tipicas de un struct ;)
Saludos,
Puck2099
26/09/2005, 05:42
El problema es que tampoco consigo cargar la imagen en una función externa...
No entiendo que puesto ese mismo código en el programa principal funcione y en una función no...
Puck2099
26/09/2005, 06:43
Venga, ¿nadie tiene unas funcioncitas para cargar imágenes de memoria que funcionen? :)
Puck2099
26/09/2005, 07:10
Otra cosa, he estado mirando códigos fuente de algunos juegos en SDL y sus programadores cargan cada imagen en una superficie distinta.
¿Esto hay que hacerlo así o se puede reutilizar una sola superficie (cargando la imagen y haciendo un "blit" a la superficie de la pantalla) para todas?
Me parece que no termino de pillarle el concepto al SDL...
Yo aún no he probado nada de todo esto pero por lo que he podido deducir de estas dos páginas:
http://jcatki.no-ip.org/SDL_image/SDL_image_8.html
http://www.kekkai.org/roger/sdl/rwops/rwops.html
deberías poner 1 en tu función IMG_Load_RW()
SDL_Surface *tmp=IMG_Load_RW(SDL_RWFromMem(&imagen, tam),1);
A ver si con esto te soluciona el problema.
Oankali.
Puck2099
26/09/2005, 17:45
Yo aún no he probado nada de todo esto pero por lo que he podido deducir de estas dos páginas:
http://jcatki.no-ip.org/SDL_image/SDL_image_8.html
http://www.kekkai.org/roger/sdl/rwops/rwops.html
deberías poner 1 en tu función IMG_Load_RW()
SDL_Surface *tmp=IMG_Load_RW(SDL_RWFromMem(&imagen, tam),1);
A ver si con esto te soluciona el problema.
Oankali.
Gracias, Oankali, a ver si llego a casa y lo pruebo, porque me estoy desesperando...
Con lo fácil que es usar el SDK oficial y lo complicado que hicieron el SDL...
Lo mismo pienso yo. Hasta he estado sospesando la posibilidad de pasar el SDK oficial a SDL, o sea el contrario de lo que hizo chui en un principio :).
Lo único que me consuela del SDL es saber que hay funciones bastantes interesantes que con el SDK oficial había que curarselas a pelo y que esté bien documentado.
Lo que no acabo de tener claro, es el rendimiento que debe de tener, con tantas máscaras y demás. Ya veremos.
Oankali.
Puck2099
26/09/2005, 18:31
Lo mismo pienso yo. Hasta he estado sospesando la posibilidad de pasar el SDK oficial a SDL, o sea el contrario de lo que hizo chui en un principio :).
Lo único que me consuela del SDL es saber que hay funciones bastantes interesantes que con el SDK oficial había que curarselas a pelo y que esté bien documentado.
Lo que no acabo de tener claro, es el rendimiento que debe de tener, con tantas máscaras y demás. Ya veremos.
Oankali.
Je, lo de pasar el SDK oficial a SDL también lo había pensado yo para portar/ayudar a portar las aplicaciones más fácilmente :)
Si te fijas, lo que quiero hacer es una función que funcione como el GpBitBlt, pero es que me da unos errores a los que no le encuentro lógica... :(
Supongo que metiendo cada imagen en una superficie me ahorraría muchos problemas, pero o no entiendo bien como funcionan estas superficies, o es un desperdicio de memoria brutal.
Lo que más me mosquea es que he leído en varios sitios que pintar un background es lentísimo, mientras que con el GPSDK yo pintaba el background en cada frame junto con un montón de cosas más e iba muy rápido...
Supongo que si el background tiene el mismo formato de píxel que la pantalla, irá igual de rápido que con el SDK oficial.
Pero si no son del mismo formato, el SDL tendrá que transformar el formato de cada píxel uno por uno. Y al blitear el background, estás bliteando un máximo de píxels.
Supongo que también depende del hardware y de la implementación del SDL para ese hardware.
Pues el rendimiento no te puedo decir cuanto puede perder, pero pienso q nada. Mi juego de guerra lleva scroll, 10 enemigos en pantalla, sus disparos, el prota con sus disparos y varios objetos mas tratados individualmente, con lo cual tengo unas 15 surfaces en total y a 60mhz aun va demasiado rapido.....
Eso si como dices yo tb probe a reutilizar un solo surface sin exito, saludos
Puck2099
26/09/2005, 19:24
Eso si como dices yo tb probe a reutilizar un solo surface sin exito, saludos
*****, pues a ver si va a ser eso lo que me pasa...
Igual hay q hacerlo de alguna forma distinta o bien q necesitas un surface para cada cosa q quieras pintar en pantalla. Aunque como te digo yo no he visto problemas de rendimiento, tal vez con 200,300, 1000 surfaces igual se nota algo no se.
Pues el rendimiento no te puedo decir cuanto puede perder, pero pienso q nada. Mi juego de guerra lleva scroll, 10 enemigos en pantalla, sus disparos, el prota con sus disparos y varios objetos mas tratados individualmente, con lo cual tengo unas 15 surfaces en total y a 60mhz aun va demasiado rapido.....
Eso si como dices yo tb probe a reutilizar un solo surface sin exito, saludos
¿Lo has probado con la GP32?
¿En 8 bits o 16 bits?
Mi juego a 8bits en la gp y a 60mhz va demasiado rapido y he tenido q controlar los fps para q vaya fino, eso si como digo a 8bits, a 16 se arrastra aunque lo pongas a 133mhz.
Aunque debo decir q cargo los graficos de la smc directamente en vez de tenerlos en memoria, ya q aun no he tenido tiempo de modificarlo para meterlo todo en el fxe, pero no creo q vaya a haber mucha diferencia
Puck2099
26/09/2005, 22:31
Nada, Oankali, ni poniendo el 1 funciona esto... al final voy a tener que optar por dejar cada imagen en una superficie, aunque me parece una cagada en cuanto a eficiencia... :(
EDITO: Acabo de conseguir que funcione, voy a echarme una siesta para despejarme un poco y luego analizo el porque y os lo cuento :)
Nada, Oankali, ni poniendo el 1 funciona esto... al final voy a tener que optar por dejar cada imagen en una superficie, aunque me parece una cagada en cuanto a eficiencia... :(
Ya lo tengo, no sé como no lo he visto antes, te sobra un &, ¿dónde será? :)
Aunque sigo pensando que hay que poner 1, o te vas quedar sin memória.
Oankali.
EDIT: vaya, por lo visto he llegado tarde y también lo has encontrado.
Puck2099
27/09/2005, 02:06
Sí, ya encontré el & que sobraba :p
Por cierto, estoy haciendo un "wrapper" para no tener que reescribir todas las funciones gráficas de mis juegos que usan el GPSDK y tengo el problema del "peso" del array que hay que pasarle a SDL_RWFromMem.
En la función principal puedo usar un sizeof(array) para que me de el peso, pero cuando paso este array como parámetro ya no funciona el sizeof dentro de la función. ¿Alguna idea?
Saludos
Sí, ya encontré el & que sobraba :p
Por cierto, estoy haciendo un "wrapper" para no tener que reescribir todas las funciones gráficas de mis juegos que usan el GPSDK y tengo el problema del "peso" del array que hay que pasarle a SDL_RWFromMem.
En la función principal puedo usar un sizeof(array) para que me de el peso, pero cuando paso este array como parámetro ya no funciona el sizeof dentro de la función. ¿Alguna idea?
Saludos
Dos soluciones: o pasas otro parámetro a tu función con el peso, o creas una estructura con el puntero del array y su peso, y solo pasas el puntero de la estructura a tu función.
Tienes que saber que sizeof() no es una función como las otras sino que funciona a nivel compilación. El compilador sabe el peso del array, pero para él el peso de un puntero siempre será 4 en 32 bits.
Oankali.
Puck2099
27/09/2005, 05:29
Dos soluciones: o pasas otro parámetro a tu función con el peso, o creas una estructura con el puntero del array y su peso, y solo pasas el puntero de la estructura a tu función.
Tienes que saber que sizeof() no es una función como las otras sino que funciona a nivel compilación. El compilador sabe el peso del array, pero para él el peso de un puntero siempre será 4 en 32 bits.
Oankali.
Joe, pues es un poco putada, porque lo que quería era hacer el "wrapper" para no tener que tocar las funciones GpBitBlt y compilar directamente, pero parece que no hay otro remedio que modificarlas todas... :(
Tú que estabas pensando hacer algo similar, ¿se te presentó también este problema?
Joe, pues es un poco putada, porque lo que quería era hacer el "wrapper" para no tener que tocar las funciones GpBitBlt y compilar directamente, pero parece que no hay otro remedio que modificarlas todas... :(
Tú que estabas pensando hacer algo similar, ¿se te presentó también este problema?
Lo único que llegué a programar pensando en ello es esto:
int GpBitBlt16(GPDRAWTAG *gptag, SDL_Surface *dst, int dx, int dy, int width, int height,
SDL_Surface *src, int sx, int sy, int imgw, int imgh)
{
SDL_Rect srcrect, dstrect;
// clip surface if needed
if (gptag)
{
SDL_Rect clip;
clip.x = gptag->clip_x;
clip.y = gptag->clip_y;
clip.w = gptag->clip_w;
clip.h = gptag->clip_h;
SDL_SetClipRect(dst, &clip);
}
else
SDL_SetClipRect(dst, NULL);
// set coordinates
srcrect.x = sx;
srcrect.y = sy;
srcrect.w = width;
srcrect.h = height;
dstrect.x = dx;
dstrect.y = dy;
SDL_BlitSurface(src, &srcrect, dst, &dstrect);
// unclip surface if clipped
if (gptag)
SDL_SetClipRect(dst, NULL);
return 0;
}
Como podrás comprobar es una mezcla de SDL y de GPSDK.
Pero no entiendo en dónde tienes el problema.
Otra solución sería pasar por una macrofunción.
Personalmente encuentro que tu función de bliteo és demasiado complicada y si va a ser muy lenta en la GP32. Puede que en la GP2X no, pero para la GP32 creo que hace demasiados calculos.
Oankali.
¿Puck como resolviste lo de crear una funcion para cargar las imagenes desde memoria? yo estoy probando pero no consigo q se muestre en pantalla nada,
void CargarImagen(SDL_Surface *imagen,unsigned char *nombre, int tamano)
{
SDL_Surface *tmp;
tmp =IMG_Load_RW( SDL_RWFromMem(nombre,tamano),1);
imagen=SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);
}
No muestra ningun error, pero tampoco me muestra nada en pantalla.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.