alguna idea para aumentar la velocidad de bliteo?

hola aquí el basto saulotmalo se le ha ocurrido hacer un juego y blitear una imagen de 480x272 en cada frame lo que hace que el juego vaya como el puto culo xD. el juego está en c++ orientado a objetos siendo el fondo un objeto con su método dibujar.

que os parece esta idea:

Una primera funcion inicializar escenario lo dibuja 1 vez completo
crear una lista de zonas que se han de dibujar del fondo a partir de los objetos dibujados en el frame anterior.
cada objeto envia información del cuadrado que estaban ocupando contando su posición y tamaño.
por último al dibujar solo se dibujan las partes que estan en la lista es decir que han sido manchadas...

he pensado que en el peor de los casos me ahorraré dibujar un 50% de los pixeles pero en un caso promedio casi un 75%

si alguien tiene alguna idea mejor que la exponga se aceptan comentarios muchas gracias...
------------------------------------------------------------------------------------

EDIT: He implementado el algoritmo descrito con una pila de cuadrados a blitear y tal y tengo que decir que la velocidad obtenida es... increible :) puedo seguir trabajando con PSP y sobrado de velocidad con 3 personajes en pantalla bliteandose y con todas las físicas
y podrias explicar un poco esa "tecnica"? pq no se me ocurre como hacer eso de los cuadros. Se supone q recortas al prota y repintas un cuadro del fondo del tamaño del prota u otro objeto q se mueva ¿no?
aunque ya te lo he explicado por el msn lo pondré aquí por si a alguien más le interesa la técnica.

la idea es quedarse con una pila que serán los cuadrados a limpiar. Para cada uno de estos lo desapilamos y lo limpiamos. hasta vaciar la pila en cada iteración. Para llenar la pila simplemente tenemos que decir que objetos no estáticos hemos pintado y pasarles su tamaño y coordenadas
ante todo gracias nuvalo, pero uso una pila porque es la estructura más rápida de hecho los compiladores suelen usar instrucciones especiales para su gestión. Bueno aún así la pila es lo más eficiente ya que siempre tengo que blitear todos los cuadrados sucios y solo meto en la pila los sucios.

Sobre lo que dices de dividir la pantalla en trozos está bien si tienes tiles pero en mi caso solo tengo algún que otro objeto tileable y lo compongo todo en una Surface en el escenario ya que son estáticos ( luego espero tener memoria de sobra para poner elementos dinámicos que serán tratados como personajes sin colisiones ( es decir fondo ;) ). Por eso lo que hago es un poco mejor que tu aproximación ya que no renderizo 2 cuadrados porque el personaje los toke sino solo renderizo los sucios por el personaje en el frame anterior.

Espero que a la gente con este problema le pueda ayudar ;)
Aparte de la lista de cuadros sucios,¿Has mirado el ejemplo del PSPSDK de blit?
En el ejemplo recuerdo que bliteaba de diferentes formas y conseguía unas velocidades altísimas, no se como, solo lo ejecuté.

Saludos
parrincrisis escribió:Aparte de la lista de cuadros sucios,¿Has mirado el ejemplo del PSPSDK de blit?
En el ejemplo recuerdo que bliteaba de diferentes formas y conseguía unas velocidades altísimas, no se como, solo lo ejecuté.

Saludos


el caso es que uso SDL así que del PSPSDK no me he mirado casi nada... de momento la cosa va sobrada ahora quiero poner colisiones a nivel de pixel para personajes con heurísticos de cajas para acelerar el proceso si después de esto no tengo problemas de velocidad con 4 personajes en pantalla no hará falta complicarme la vida con el bliteo sino ya pensaré algo más avanzado. De Momento ya digo va de putisima madre super fino :)
Bueno no me paso mucho por este foro pero bueno ya que he visto esto te intentaré dar alguan alternativa.

La técnica q describes es la de dirty rectangles, la usan a cascoporro en engines basados en tiles, y suele dar un buen rendimiento a menos q tengas scroll continuado (aunque se pueden hacer buenos apaños :D).

Hay una técnica algo más compleja y es la del SBUffer. La base consiste en ter un lista de segmentos de pixeles ordenados por Z (o layer si quiers si el juego es 2D). Se empieza pintando por la Z más próxima y se acaba por la ultima, y descartas todos los segmentos con pixeles q no se pintarian al estar debajo de los pixeles de layers mas cercanos.

Esto es a groso modo, busca info si quieres. Te he de advertir q han un pequeño problema con las transparencias pero se puede solucionar con un poco de vista.

Un saludo.
notbad.
HexDump escribió:Bueno no me paso mucho por este foro pero bueno ya que he visto esto te intentaré dar alguan alternativa.

La técnica q describes es la de dirty rectangles, la usan a cascoporro en engines basados en tiles, y suele dar un buen rendimiento a menos q tengas scroll continuado (aunque se pueden hacer buenos apaños :D).

Hay una técnica algo más compleja y es la del SBUffer. La base consiste en ter un lista de segmentos de pixeles ordenados por Z (o layer si quiers si el juego es 2D). Se empieza pintando por la Z más próxima y se acaba por la ultima, y descartas todos los segmentos con pixeles q no se pintarian al estar debajo de los pixeles de layers mas cercanos.

Esto es a groso modo, busca info si quieres. Te he de advertir q han un pequeño problema con las transparencias pero se puede solucionar con un poco de vista.

Un saludo.
notbad.


para esta técnica creo que lo ideal sería dividir la pantalla en segmentos y ver cuantos o cuales segmentos toca cada elemento que se tenga que redibujar y además ordenar por z y en caso de que un elemento ya haya limpiado ya no se ha de limpiar.... en realidad interesate para eliminar zonas de bliteo pero no sé si es lo más óptimo para mi juego debería de comprobar cuanto cuesta cada técnica igual la implemento... muchas gracias :)

Por cierto que curioso no sabía que esta técnica tenía nombre... fué la primera idea que se me ocurrió pero ya pensé que tenía optimizaciones.
Bueno, lo que se hace en lo que te comente, es tener listas de segmentos por lineas de pantalla, y se van haciendo merges de varios segmentos colindantes o que se pisan ejemplo:


PANTALLA

linea 0: |------seg 1 en layer 0 ------ |

linea 0: ___________________|--------- seg 2 en en layer 1 ---------- |

los "_" arriba son lugares sin pixeles que esto no me deja meter espacios.

Esto quedaría asi


PANTALLA

linea 0: |--------- seg 1 ----------------------------------------------|

osea, a medida que vas pintando se van fundiendo segmentos, de esta forma puedes pintar un huevo de sprites en pantalla o muchos layers sin mucho coste.

Esta técnica se usaba por ejemplo en Earth Worm Jim de pc, y no veas como iba, eso sí, es dificil implementarla bien para que corra lo que ha de correr. Mi primera implementación era un 10% más lenta que la de "Pinta todo".

Un saludo,
HexDump.
HexDump escribió:Bueno, lo que se hace en lo que te comente, es tener listas de segmentos por lineas de pantalla, y se van haciendo merges de varios segmentos colindantes o que se pisan ejemplo:


PANTALLA

linea 0: |------seg 1 en layer 0 ------ |

linea 0: ___________________|--------- seg 2 en en layer 1 ---------- |

los "_" arriba son lugares sin pixeles que esto no me deja meter espacios.

Esto quedaría asi


PANTALLA

linea 0: |--------- seg 1 ----------------------------------------------|

osea, a medida que vas pintando se van fundiendo segmentos, de esta forma puedes pintar un huevo de sprites en pantalla o muchos layers sin mucho coste.

Esta técnica se usaba por ejemplo en Earth Worm Jim de pc, y no veas como iba, eso sí, es dificil implementarla bien para que corra lo que ha de correr. Mi primera implementación era un 10% más lenta que la de "Pinta todo".

Un saludo,
HexDump.

Supongo que en mi caso podría hacer alguna operacion lógica en el caso de que se solapen y tengan colorkey pero pienso que no podría sacarle rendimiento, de momento la de dirty rectangles me va de maravilla y como de bliteo voy bastante bien de momento si más adelante tengo memoria de sobra para animar escenarios y tal ya me lo curraría más :)
Pues nada q vaya bien. No se para que plataforma estás haciendo eso, pero te aconsjeo que si es para una que tenga memoria de video dedicada, o la tenga mapeada a unas direcciones de memoria convencional, que intentes tener allí todas las cosas que vas a usar, y hagas los menos cambios posibles, el ancho de banda es importante.

Un saludo,
HexDump.
Es para psp y cierto el ancho de banda es muy importante... pero al estar usando una libreria de alto nivel ella se encarga de ponerlas donde debe (SDL). Gracias por la ayuda, en gráficos 3D pasa igual lo que más cuesta es pasar la info ( texturas y vertices) a la GU.

PD: que recuerdos de mis gráficos 3D ahora me gustaría hacer un 2.5D a ver si para el próximo...
12 respuestas