PDA

Ver la versión completa : Problema con funcion en SDL



Estopero
26/08/2006, 23:57
int i;
while (1==1){

putpixel(screen, x, y, color);
i++;
color.r = i % 255;
}

void putpixel(SDL_Surface *screen, int x, int y, SDL_Color color)
{

if(SDL_MUSTLOCK(screen))
SDL_LockSurface(screen);

// Convertimos color
Uint32 col=SDL_MapRGB(screen->format, color.r, color.g, color.b);

//Lo colocamos en la posicion correpondiente de la superficie
*((char*) screen->pixels + (screen->format->BytesPerPixel*x) + (screen->pitch*y)) = col;

if(SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);

SDL_UpdateRect(screen, 0, 0, 0, 0);

}

Bueno esta es la funcion, ya se que no tiene ninguna finalidad logica, pero esque estoy empezando xD. El caso es que claro al entrar en un bucle infinito, pues la aplicacion se vuelve tontaina y se joe,se ve como el pixel cambia de color muy rapido pero se cuelga, yo lo que quiero es poner algo dentro del bucle o de la funcion para evitar que pierda el control, es decir, que aunque se tire toda la vida haciendolo no cuelgue el ordenador. Lo he intentado con SDL_Delay(1000) para que diera una vuelta por segundo, pero no funciona, nose, algo parecido al frame; de fenix. Por ejemplo, si quisiese que cambie de color en cada vuelta y quiero q el pixel cambie cada segundo un poco, aunque sea hasta el infinito xD, ¿entendeis?. En fin espero qe alguien me comprenda porque ando perdiooo. Un saludo!

*Editado con lo que me han aconsejado xD

oankali
27/08/2006, 00:58
Esta función lo que hace es bloquear la superfície, luego entra en un bucle y hace lo siguiente hasta el infinito:
- convierte el color al formato actual de la pantalla
- actualiza la posición de memória que corresponde a las coordenadas con el color calculado.
Como que no sale del bucle, pues no hace otra cosa y tu no verás nada.
El bucle tendría que estar fuera de la función.
Además, si usas dos superfícies, en un momento u otro tendrás que usar SDL_Flip() para activar la superfície que acabas de actualizar.

Estopero
27/08/2006, 01:41
Esta función lo que hace es bloquera la superfície, luego entra en un bucle i hace lo siguiente hasta el infinito:
-convierte el color al formato actual de la pantalla
actualiza la posición de memória que corresponde a las -coordenadas con el color calculado.
Como que no sale del bucle, pues no hace otra cosa y tu no verás nada.
El bucle tendría que estar fuera de la función.
Además, si usas dos superfícies, en un momento y otro tendrás que usar SLD_Flip() para activar la superficie que acabas de actualizar.

vale he estao probandoy tal como lo habia escrito al principio no funcionaba, es cierto xD, ahora lo he editado y creo que si se ve un poco mejor lo que pretendo no? un saludo y muchas gracias!

oankali
27/08/2006, 06:05
int i;
while (1==1){

putpixel(screen, x, y, color);
i++;
color.r = i % 255;
}

void putpixel(SDL_Surface *screen, int x, int y, SDL_Color color)
{

if(SDL_MUSTLOCK(screen))
SDL_LockSurface(screen);

// Convertimos color
Uint32 col=SDL_MapRGB(screen->format, color.r, color.g, color.b);

//Lo colocamos en la posicion correpondiente de la superficie
*((char*) screen->pixels + (screen->format->BytesPerPixel*x) + (screen->pitch*y)) = col;

if(SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);

SDL_UpdateRect(screen, 0, 0, 0, 0);

}



Bueno, esta versión de ahora sí debería de funcionar.
El resultado debería de ser un pixel que está parpadeando, su componente roja va de 0 a 255 constantemente.

Se puede mejorar indicando a SDL_UpdateRect() los parámetros (x, y, 1, 1). Porque lo que le indicas es que actualice la pantalla completa a cada bucle, cuando en realidad lo que haces es cambiar un solo píxel.

En realidad, segun mi punto de vista para que la rutina putpixel() se pueda aprovechar más, el bloqueo/desbloqueo/update tendrian que estar fuera de la función putpixel().
En tu ejemplo, no ganarás nada pero si quieres dibujar una línea utilizando tu función, irá mucho más rápido si solo bloqueas la pantalla antes de dibujar el primer píxel, la desbloqueas después del último píxel y finalmente actualizas la pantalla.

Drumpi
27/08/2006, 08:21
Soy muy novato en la programacion "en serio", asi que si digo alguna burrada...
Pero cuando en clase programabamos en c++, usabamos delay(100) para hacer pausas en la ejecucion, creo que es una funcion de la libreria time.h

Zenzuke
27/08/2006, 10:31
Ke kabrón, si me has mangado código :O xDDDDDDDDDDDDD

Bueno, el mio era un batiburrillo de cosas pilladas por ahi tb, asi que te lo perdono.

Pero mira, Oankali me ha dado una idea de por qué puede ir tan mal la especie de demo de fuego que hice en gp2x :D

Ah, pues no, me he colao, ese código no es el mío, es el del ejemplo que estaba usando antes de cambiarlo, por eso me sonaba tanto xDDDDDDDDD

Y al final yo hago los bloqueos de pantalla fuera del putpixel tb, kawennn ¬__¬ asi que va lento porque va lento y ya esta xD

Por ciero, estopero, prueba este putpixel que da menos problemas, con ese no me las llegué a apañar:


void putpixel(int x, int y, int r, int g, int b)
{
Uint8 *p = (Uint8*)screen->pixels + y * screen->pitch + x*2;
*(Uint16 *)p = SDL_MapRGB(screen->format, r,g,b);
}

Y el updaterect lo puedes llamar en el bucle principal despues de llamar a la función, asi cuando te metas a añadir más pixeles no andará refrescando la pantalla a cada uno que metas.

Cualquiera diria que se C ¿eh? Y mira ke soy un mierda ke no ha exo na mas ke una kosa xD

oankali
28/08/2006, 05:22
Ke kabrón, si me has mangado código :O xDDDDDDDDDDDDD

Bueno, el mio era un batiburrillo de cosas pilladas por ahi tb, asi que te lo perdono.

Pero mira, Oankali me ha dado una idea de por qué puede ir tan mal la especie de demo de fuego que hice en gp2x :D

Ah, pues no, me he colao, ese código no es el mío, es el del ejemplo que estaba usando antes de cambiarlo, por eso me sonaba tanto xDDDDDDDDD

Y al final yo hago los bloqueos de pantalla fuera del putpixel tb, kawennn ¬__¬ asi que va lento porque va lento y ya esta xD

Por ciero, estopero, prueba este putpixel que da menos problemas, con ese no me las llegué a apañar:


void putpixel(int x, int y, int r, int g, int b)
{
Uint8 *p = (Uint8*)screen->pixels + y * screen->pitch + x*2;
*(Uint16 *)p = SDL_MapRGB(screen->format, r,g,b);
}

Y el updaterect lo puedes llamar en el bucle principal despues de llamar a la función, asi cuando te metas a añadir más pixeles no andará refrescando la pantalla a cada uno que metas.

Cualquiera diria que se C ¿eh? Y mira ke soy un mierda ke no ha exo na mas ke una kosa xD


Si quieres me puedes enviar el código de la demo de fuego para que la analice un poco y ver si se puede optimizar un poco. Ten en cuenta que de SDL no soy muy bueno, pero de C puro sí sé.

Estopero
28/08/2006, 06:54
finalmente la cosa queda asi:

while (1==1){

SDL_PollEvent (&event);
putpixel(screen, x, y, color);
i++;
color.r = i % 255;
SDL_Delay(10);
}

void putpixel(SDL_Surface *screen, int x, int y, SDL_Color color)
{

if(SDL_MUSTLOCK(screen))
SDL_LockSurface(screen);

// Convertimos color
Uint32 col=SDL_MapRGB(screen->format, color.r, color.g, color.b);

//Lo colocamos en la posicion correpondiente de la superficie
*((char*) screen->pixels + (screen->format->BytesPerPixel*x) + (screen->pitch*y)) = col;

if(SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);

SDL_UpdateRect(screen, 0, 0, 0, 0);

}

No esta optimizado con las cosas que me habeis dicho, ya lo ahre cuando haga cosas en serio jeje, pero el caso es que con ayuda de _newage_ hemos descubierto q el problema esta en que hay que poner "SDL_PollEvent (&event);" dentro del bucle, pero no lo entiendo muy bien sinceramente, se que es algo relacionado a que tiene que seguir escuchabndo lso eventos o algo asi, pero no entiendo porque es necesario =(, ¿alguien entiende porque si no se pone se queda frito el programa? muchas gracias por vuestros consejos!

Zenzuke
28/08/2006, 06:58
Si quieres me puedes enviar el código de la demo de fuego para que la analice un poco y ver si se puede optimizar un poco. Ten en cuenta que de SDL no soy muy bueno, pero de C puro sí sé.

Jue, oenkali, muchas gracias :D

Tienes un MP.

Theck
29/08/2006, 19:08
Wenas mandrileño, pues seguramente porque tiene que saber si hay algún evento pendiente de procesar, supongo que no puedes ignorarlos ;)

Así me gusta, haciendo lo que yo no, practicando, luego me vendrás a preguntar y sabrás más que yo xD