Doble buffer en sdl?

hola sabeis como activar el doble buffer en sdl? yo creo que lo tengo activado en una aplicación pero no me funciona correctamente... es posible que tenga que poner alguna forma especial de inicialización?
SDL_Surface * screen = SDL_SetVideoMode(width, height, bitsperpixel, SDL_HWSURFACE | SDL_DOUBLEBUF);

Pero te he de decir que lo he usado y no da unos resultados muy buenos o a mi no me lo parece.
es lo que estaba gastando pero me daba muchisimos fallos ... supongo que no estará soportado de todas maneras he pasado a la SWSURFACE y listo creo que lo único que hacía era dibujar en memoria ram en vez de memoria de video directamente.
Hay que tener cuidado con el double buffer y SDL. Para que exista double buffer la superficie tiene que ser hardware, si no no se activa.
Si no adquieres una superficie hardware, lo mejor es crear tu propia superficie como backbuffer y dibujar en ella, para luego hacer un blit de ella a la superficie de la pantalla, y obtienes el doble buffer. Claro que no es por hardware, pero al menos es algo.

El problema de las superficies hardware es que dependiendo de las operacionesleer píxels en superficie hardware es lento, pero a cambio obtienes aceleración hardware de blits, de blits con transparencia, etc, así que todo dependerá de lo que necesites.

Haz un par de proyectos de prueba con las opciones posibles y elige el que mejor rendimiento te de en tu caso, es el único modo de saber con toda seguridad cuál es la mejor opción.
de momento he hecho un proyecto ( luego publico...) y he usado software porque sino me daba problemas con los color key pese a mapear el color... pero buen ahora ya está todo hecho.
Cambiarlo sería un segundo, simplemente con hacer

SDL_Surface* screen = SDL_SetVideoMode(...)
SDL_Surface* buffer = screen;
//SDL_ConvertSurface crea una superficie nueva, aunque también puedes crear una
//superficie nueva directamente a mano con SDL_CreateSurface, pero por experiencia esta es la forma
//más cómoda
screen= SDL_ConvertSurface(screen, screen->format, screen-flags);


Así las operaciones de dibujo las sigues haciendo en screen, pero buffer es realmente el puntero a la pantalla.

Cuando toca actualizar los datos en pantalla ( es decir cuando llames a SDL_UpdateRect(screen, 0,0,0,0) ) lo sustituyes por un SDL_BlitSurface(screen,NULL,buffer,NULL)

No tengo código ahora pero con hacer eso debería funcionar y tener un doble buffer por soft, otra cosa es el rendimiento, que dependerá bastante de la resolución si dices que la superficie es por software.
creo que la solución que propones no sirve tampoco...

"creo" la idea del doble buffer es usarlo para que cuando esté lista la imagen a mostrar se cambie el buffer ,ok? pero si haces un blit dependerá del tiempo que te cueste el blit al ser de toda la pantalla le costará tiempo y es posible que lo pille a mitad con lo que igual se verían algunos fallos gráficos menores ....
saulotmalo escribió:creo que la solución que propones no sirve tampoco...

"creo" la idea del doble buffer es usarlo para que cuando esté lista la imagen a mostrar se cambie el buffer ,ok? pero si haces un blit dependerá del tiempo que te cueste el blit al ser de toda la pantalla le costará tiempo y es posible que lo pille a mitad con lo que igual se verían algunos fallos gráficos menores ....

Si, el propósito del doble buffer es justamente ese, pero en teoría un blitting es más rápido, aunque sea por software, y además modificas la pantalla en un único momento en vez de en varios durante el bucle del juego, por lo que eso se minimizaría.

Lo que estoy pensando es que puede que tengas razón, y no se si lo que estoy haciendo es redundante, porque en SDL si no llamas a UpdateRect(screen,0,0,0,0) para marcar la pantalla como "sucia" no cambia el dibujo en pantalla.
Vamos que es posible que SDL tenga ya por debajo un backbuffer "por soft" y lo controle. Eso tendría sentido, ya que SDL_Flip(), si no tienes una superficie con doble buffer por hardware lo que hace es llamar a UpdateRect() en realidad.

A ver si me bajo el código de SDL y le echo un vistazo.

EDITO: olvida esto que he dicho arriba, no tiene nada que ver con utilizar un backbuffer para hacer un double buffer por software, al menos lo que he podido entender del código fuente.
Lo que pasa es que si una superficie es software, ésta se aloja en la RAM, por tanto en algún momento se tiene que copiar a la VRAM para que pueda representarse por pantalla.
Ahí estaba mi fallo, y efectivamente lo que te comento es redundante, y sólo sirve para una cosa: gastar más memoria.

Efectivamente, no puedes tener double buffer si no es por hardware. Y el problema es que depende mucho ya no del hardware del sistema, sino del propio SO y drivers. Por ejemplo en windows no puedes obtener superficies hardware en modo ventana, tiene que ser a pantalla completa.
Y una vez tuve un problema que por alguna razón no me cargaba el driver de DirectX (para usar DDraw) y tampoco me pillaba superficies hardware, y la tontería es que había copiado las dll a windows/system, pero sin querer había vinculado el programa con una versión más nueva de la librería :P
No se exactamente cual es el problema q tienes o q buscas exactamente, en el port de sdl como ya te dije no hay muchas opciones, o usas el render por soft o por hard y para de contar. Tampoco se q pretendes portar, pero portar cosas de pc necesitan mas q un simple recompilado si quieres obtener velocidad en psp. Igual seria buena idea mirar el codigo de open transport tycoon q esta portado a psp por un español ;)
eskema no era para el port, el port ya está hecho :) por cierto voy a publicar ya :D era porque quería entender como funcionaba para los demás juegos, en el port aunque uso el soft no se nota mucho el hecho de no tener doble buffer ( por el tema de que el tamaño de la pantalla es pequeño) aún así era por saberlo...

zheo muchas gracias por la explicación ahora comprendo mejor lo que ya suponía nada de doblebuffer por soft :(

offtopic:
zheo como mola tu firma ;) be pointer my friend
9 respuestas