Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Tileset vs PAK

Iniciado por Ubermann, 06 de Marzo de 2011, 01:37:32 PM

« anterior - próximo »

Ubermann

Aún sigo trasteando con dx_lib32 antes de ponerme en serio a hacer algo que tengo planeado.

Ahora le ha tocado el turno al manejo de imágenes.
Como nunca antes había manejado tilesets, pues me puse a ello para ver qué ventajas y desventajas tenía.
Pues bién, tras haber probado con un programilla sencillo (simplemente abrir un tileset y mostrar uno de los tiles de 16x16), me he dado cuenta de que usar un PAK o simplemente un directorio con cada imagen, desde mi punto de vista, me parece mucho más útil.

Para empezar, el tileset parece ser menos eficiente en cuanto a memoria usada. Hay que darse cuenta que para usarlo hay que cargar toda la imagen entera en memoria. Para imágenes pequeñas no es un problema, pero cuando hay que usar muchas imágenes y de tamaño considerable, el consumo de memoria puede ser elevado (en mi proyecto tengo que usar más de 20 tilesets y cada uno de 512x512)

Por otro lado, con el tileset no hay manera de organizar mediante un nombre descriptivo y un índice cada conjunto de imágenes dentro del propio tileset. Lo único que se puede hacer es saber en qué fila/columna está tal o cual tile y mediante bastantes líneas de código, acceder a dicha "celda" dependiendo de lo que quieras mostrar.

Otro problema que veo: los tilesets que puedo usar y que representan suelos y paredes NO están ordenados, por lo que podría ser horrible tener que averiguar en cada momento dónde está tal o cual tipo de "suelo" o "pared".




Sin embargo, si nos fijamos en un PAK o un directorio, podremos tener varios subdirectorios cada uno con un tipo de imagen, y cada imagen con un nombre descriptivo y un índice, como por ejemplo "player1.png", "player2.png", "player3.png", o incluso "sueloMetal1.png", "sueloMetal2.png", etc...

Por lo tanto el acceso a una imagen en concreto es realmente fácil.

Además, en cuanto al consumo de memoria, es destacablemente inferior al de los tileset, ya que solamente hay que cargar en memoria la/s imagen/es que necesitemos usar, que, en mi caso, son de 32x32.



La cuestión es: ¿qué ventaja, si es que hay alguna, tienen los tilesets frente al uso de PAKs y/o directorios?


Ah, y claro, estamos hablando de un juego 2D tipo plataforma, o RPG o shooter, es decir, cosas relativamente sencillas y que necesitan usar multitud de imágenes diferentes si tener que usar ese mismo número de variables.

[EX3]

Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Para empezar, el tileset parece ser menos eficiente en cuanto a memoria usada. Hay que darse cuenta que para usarlo hay que cargar toda la imagen entera en memoria. Para imágenes pequeñas no es un problema, pero cuando hay que usar muchas imágenes y de tamaño considerable, el consumo de memoria puede ser elevado (en mi proyecto tengo que usar más de 20 tilesets y cada uno de 512x512)
Craso error, es mas optimo usar una textura con todos los tiles o fotogramas de una animacion y dibujar secciones de dicha textura que tener varias texturas en memoria por tile y dibujarlas independientemente. A la tarjeta grafica le resulta mas costoso ir cambiando la textura a dibujar que acceder a una sola textura y dibujar una seccion de ella. dx_lib32 de hecho optimiza esta tarea al trabajar con tilesets ya que detecta si la textura a dibujar es la msima aun siendo disttinto los parametros de dibujo, por lo cual evita el cambio de textura y su coste de rendimiento.

Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Por otro lado, con el tileset no hay manera de organizar mediante un nombre descriptivo y un índice cada conjunto de imágenes dentro del propio tileset. Lo único que se puede hacer es saber en qué fila/columna está tal o cual tile y mediante bastantes líneas de código, acceder a dicha "celda" dependiendo de lo que quieras mostrar.
Si lo hay, de hecho mi ultima version del motor trabajaba un formato de archivo que era una tabla de tiles al que asignabas nombres e incluso podias definir secuencias de animacion mediante dichas claves, todo ello a traves de la siguiente herramienta que tuve que hacerme:



Una lista o diccionario de rectangulos (X, Y, Width, Height) con una clave y el manejo de tilesets veras que es mas sencillo de lo que pensabas ;)

Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Otro problema que veo: los tilesets que puedo usar y que representan suelos y paredes NO están ordenados, por lo que podría ser horrible tener que averiguar en cada momento dónde está tal o cual tipo de "suelo" o "pared".
No entiendo. Un tileset solo es una textura que contiene tiles, no informacion sobre si es suelo o una animacion o si es fisico o no. Tienes que separar graficos de logica, que un tile sea o no suelo no lo define el grafico si no la programacion que tenga detras tu elemento en pantalla que dibuje el tile.

Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Sin embargo, si nos fijamos en un PAK o un directorio, podremos tener varios subdirectorios cada uno con un tipo de imagen, y cada imagen con un nombre descriptivo y un índice, como por ejemplo "player1.png", "player2.png", "player3.png", o incluso "sueloMetal1.png", "sueloMetal2.png", etc...
Exactamente igual que la tabla de antes mencionada.

Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Además, en cuanto al consumo de memoria, es destacablemente inferior al de los tileset, ya que solamente hay que cargar en memoria la/s imagen/es que necesitemos usar, que, en mi caso, son de 32x32.
Es mas organizacion que optimizacion en cuanto a programacion. Yo uso tilesets y no los cargo todos. Yo agrupo los tiles de un conjunto de estilos por texturas, si tengo un escenario que va a ser jungla solo cargo el set de tiles que tienen los graficos de jungla, si tengo un escenario que es un hangar solo cargo el set de tiles que tiene los graficos del hangar. Con los personajes igual, solo tengo un set de tiles por personaje, por ejemplo:



Mi personaje es procedural. No esta formado directamente por frames completos si no por "piezas" (fijate en mi avatar) ya que asi doto de multiples acciones que con pocos sprites puedo programarlas, por ejemplo, que apunte en un angulo segun la posicion del raton, y que de esta forma me permite juntar acciones con otras, por ejemplo, usar cualquier arma con la animacion de carrera y con el casco que quiera. Esta organizacion junto a una programacion generica me permite usar multiples configuraciones para mostrar por ejemplo distintos tipos de soldados en pantalla usando un unico tilset. Aqui solo estoy usando una  unica textura que a la vez pueden usar distintas instancias del marine que no han de ser el player por ejemplo, podrian ser npc's o enemigos inclusive. En este caso la tarjeta grafica solo estaria accediendo a una unica textura todo el tiempo para representar todos los marines en pantalla que quiera poner en mi juego y no a distintas texturas por fotograma de animacion por cada instancia del marine (1 textura = 1 acceso = multiples marines, varias texturas = multiples accesos x (n) marines). El escenario seria otro buen ejemplo, una o dos texturas con los sets que uses en el escenario, 1 solo acceso por textura al dibujar todos los tiles que lo forman.

Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
La cuestión es: ¿qué ventaja, si es que hay alguna, tienen los tilesets frente al uso de PAKs y/o directorios?
A modo resumen, principalmente el rendimiento y optimizacion de memoria a parte de las posibilidades que ofrece el trabajar con tilesets (el ejemplo del marine). Piensa que los tilesets se llevan usando desde el principio de los desarrollos de juegoos con sprites en maquinas tan limitadas como los Spectrum, las Atari, las NES, Commodore64 y cualquier maquina que tuviera que trabajar con gran cantidad de graficos bitmap en tiempo real, algunas de esas maquinas apenas no tenian potencia suficiente como para andar cambiando de tilesets en tiempo de juego como la NES, que solo usa un mapa completo de tiles para representar los juegos (en cualquier emulador puedes ver esto mediante los exploradores de tiles que tienen):



Cierto es, tambien, que si tu juego va a ser pequeño y no va a usar una cantidad ingente de graficos pues separar cada tile en una textura suelta tampoco va a ser un problema serio, pero vamos, un RPG o un Shooter desde luego no son el tipo de juegos que usen pocos graficos :)

Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Ah, y claro, estamos hablando de un juego 2D tipo plataforma, o RPG o shooter, es decir, cosas relativamente sencillas y que necesitan usar multitud de imágenes diferentes si tener que usar ese mismo número de variables.
Un RPG o un shooter no son precisamente juego sencillos, ni si quiera un plataformas. Que sea 2D no implica que sea mas sencillo que un juego 3D en cuanto a programacion (no siempre). Recuerda que yo llevo años tratando de sacar un juego tipo Prince of Persia (1989) / Another World (1991) / FlashBack (1992) y estos tienen mucha complejidad detras los graficos que muestran y sobre todo contando para las maquinas para las que se desarrollaron por entonces :)

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Hechelion

#2
Tal como te dijo Ex3, las tileset permiten un desarrollo más optimo y sobre todas las desventajas que dices. tanto para un PAK como una textura necesitas tener información extra para ordenarlas, una textura es una textura y para que el juego use una pared o un suelo es necesario informarle que textura o parte de la textura será pared o suelo. Así que en cualquier caso, al final el orden pasa por el desarrollar, no por la herramienta.

Si trabajar con  texturas enteras, tu unidad  mínima de indice es el nombre y posición del archivo.
En una tile, tu unidad queda definido como nombre + posición + coordenada dentro de la textura.

Me explico, puedes tener una carpeta "suelo" y dentro los archivos "suelo1, "suelo2" etc. Pero para graficar igual necesitas un archivo de información que le diga cual archivo usar y de que forma.
Si usas tile, puedes ordenar como quieras las texuras, la única diferencia es que archivo de información debe informar además las coordenadas dentro de la textura.

Así que todo depende de que como implementes la lógica con que vas a usar los recursos, si no me crees, yo mismo he escrito un par de clases para usar escenarios a partir de tiles:
http://www.youtube.com/watch?v=6MQhajvfLM4
http://www.youtube.com/watch?v=_EQFsUstoZA
http://www.youtube.com/watch?v=IAimoa2KnqU

Puedes hacer exactamente lo mismo usando como unidad mínima un archivo completo, pero difícilmente el código resultante será más simple que el necesario para construir un mapa basado en tiles y por cierto, si necesitas 20 texturas de 512*512 (Lo que es la nada de la nada en memoria para un equipo actual), es porque eso ocupa la información gráfica de tu juego. Si haces todo como archivos separados, seguramente tendrás 2000 archivos  de 32*32, lo que en total pesa lo mismo que lo anterior (valor al ojo), así que no reduces el total de información, sólo puedes optimizar cargando los gráficos que vas a usar, pero eso lo puedes hacer tanto en tileset como usando texturas por separado.

Lo que yo veo, es que estás confundiendo formas de ordenar la información gráfica sobre formas de empaquetar los recursos, porque nada te impide usar PAK y tileset junto por ejemplo.


Ubermann

Creo que nos hemos entendido mal y creo que yo soy el culpable: he programado siempre en entornos y con gente en Inglés, y algunos conceptos pueden no ser correctos.
Vayamos por partes:

Cita de: [EX3] en 06 de Marzo de 2011, 08:55:59 PM
Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Para empezar, el tileset parece ser menos eficiente en cuanto a memoria usada. Hay que darse cuenta que para usarlo hay que cargar toda la imagen entera en memoria. Para imágenes pequeñas no es un problema, pero cuando hay que usar muchas imágenes y de tamaño considerable, el consumo de memoria puede ser elevado (en mi proyecto tengo que usar más de 20 tilesets y cada uno de 512x512)
Craso error, es mas optimo usar una textura con todos los tiles o fotogramas de una animacion y dibujar secciones de dicha textura que tener varias texturas en memoria por tile y dibujarlas independientemente. A la tarjeta grafica le resulta mas costoso ir cambiando la textura a dibujar que acceder a una sola textura y dibujar una seccion de ella. dx_lib32 de hecho optimiza esta tarea al trabajar con tilesets ya que detecta si la textura a dibujar es la msima aun siendo disttinto los parametros de dibujo, por lo cual evita el cambio de textura y su coste de rendimiento.

No me refería a eso.
Su pongamos que, como en mi caso, necesito usar gran cantidad de texturas de suelos, paredes y sprites  (para usar como animaciones o como decoraciones).
Si uso tilesets, por supuesto que puedo tener varios tilesets que contengan un tipo determinado de gráficos, por ejemplo "tilesteSueloCiudad.png", "tilesetSueloBosque.png", etc...
La cosa es que si en uno de los supuestos mapas sólo tengo que usar tres tipos de tiles que estan dentro de "tilesetSueloCiudad", más otros tres tiles diferentes de "tilesetSueloBosque", pues estoy obligado a cargar en memoria todo el tileset entero, a pesar de que voy a usar solamente un par o tres tiles de cada uno de ellos. Se ve claramente que hay un uso innecesario de memoria RAM. Puede que para un RPG que usa sólo dos o tres tilesets, no signifique mucho, pero los gráficos que yo tengo que usar podrían llegar a los 150 ó 200 Mb entre todos. Si a ello le sumamos los sonidos más la música (son MP3s de unos 25-30 Megas), podríamos alcanzar los 300Mb sin ni siquiera darnos cuenta.

Sin embargo, con un PAK o un directorio y subdirectorios, simplemente cargaremos las imágenes que necesitemos exclusivamente.
Sé que es peor cargar y leer "cada dos por tres", pero tampoco es ese el caso, ya que los gráficos a usar se cargan solamente en memoria cuando se inicia el nivel, por lo tanto de estar usando 150Mb pasaríamos a usar poco más de 20Mb. Además con la potencia actual de los ordenadores apenas serían unos segundos de carga. Otra cosa, y esto es indiscutible, es que tuviera que cargar y "descargar" gráficos de memoria a cada frame.

Cita de: [EX3] en 06 de Marzo de 2011, 08:55:59 PM
Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Por otro lado, con el tileset no hay manera de organizar mediante un nombre descriptivo y un índice cada conjunto de imágenes dentro del propio tileset. Lo único que se puede hacer es saber en qué fila/columna está tal o cual tile y mediante bastantes líneas de código, acceder a dicha "celda" dependiendo de lo que quieras mostrar.
Si lo hay, de hecho mi ultima version del motor trabajaba un formato de archivo que era una tabla de tiles al que asignabas nombres e incluso podias definir secuencias de animacion mediante dichas claves, todo ello a traves de la siguiente herramienta que tuve que hacerme:

<imagen_no_quoteada>

Una lista o diccionario de rectangulos (X, Y, Width, Height) con una clave y el manejo de tilesets veras que es mas sencillo de lo que pensabas ;)

No sería posible para tilesets que no pueden tener un orden o tamaño definidos, por ejemplo, yo tengo tres "animaciones" de monstruos. Cada animación posee "frames" y "states".
Un frame es cada uno de las imágenes que conforman una parte de la animación (como por ejemplo, mover el pié izquierdo cuando camina). Es quizás otra manera de llamar a los tiles.
Un state es cada uno de los tipos de "animación", por ejemplo, el state "atacar", el state "correr", etc...

En teoría, no habría problema si todos los monstruos tuviesen sus tiles del mismo tamaño y en posiciones relativas equivalentes, pero como no es así, resultaría imposible mediante un método "universal" conocer exactamente qué posición y qué dimensiones tiene cada tile de cada monstruo.

Sin embargo, con directorios o PAKs, simplemente hago una llamada a un método que carge la imagen cuyo archivo se llama, por ejemplo, "zombieWalk01.png", y así con todos los frames de "zombieWalk".

Cita de: [EX3] en 06 de Marzo de 2011, 08:55:59 PM
Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Otro problema que veo: los tilesets que puedo usar y que representan suelos y paredes NO están ordenados, por lo que podría ser horrible tener que averiguar en cada momento dónde está tal o cual tipo de "suelo" o "pared".
No entiendo. Un tileset solo es una textura que contiene tiles, no informacion sobre si es suelo o una animacion o si es fisico o no. Tienes que separar graficos de logica, que un tile sea o no suelo no lo define el grafico si no la programacion que tenga detras tu elemento en pantalla que dibuje el tile.

No me has entendido. Se supone que si usas tilesets, a cada uno de ellos les pondrás un nombre descriptivo. Ya sé que son imágenes xD

Cita de: [EX3] en 06 de Marzo de 2011, 08:55:59 PM
Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Además, en cuanto al consumo de memoria, es destacablemente inferior al de los tileset, ya que solamente hay que cargar en memoria la/s imagen/es que necesitemos usar, que, en mi caso, son de 32x32.
Es mas organizacion que optimizacion en cuanto a programacion. Yo uso tilesets y no los cargo todos. Yo agrupo los tiles de un conjunto de estilos por texturas, si tengo un escenario que va a ser jungla solo cargo el set de tiles que tienen los graficos de jungla, si tengo un escenario que es un hangar solo cargo el set de tiles que tiene los graficos del hangar. Con los personajes igual, solo tengo un set de tiles por personaje, por ejemplo:

<imagen_que_no_voy_a_quotear>

Pues más organizado que un directorio y subdirectorios no encuentro yo otra manera, y mças aún si dentro de "suelosBosque" puede haber varios tipos diferentes, como por ejemplo "hierba", "árboles", "agua", "tierra" y dentro de cada uno de ellos más clasificaciones todavía.

Cita de: [EX3] en 06 de Marzo de 2011, 08:55:59 PM
Mi personaje es procedural. No esta formado directamente por frames completos si no por "piezas" (fijate en mi avatar) ya que asi doto de multiples acciones que con pocos sprites puedo programarlas, por ejemplo, que apunte en un angulo segun la posicion del raton, y que de esta forma me permite juntar acciones con otras, por ejemplo, usar cualquier arma con la animacion de carrera y con el casco que quiera. Esta organizacion junto a una programacion generica me permite usar multiples configuraciones para mostrar por ejemplo distintos tipos de soldados en pantalla usando un unico tilset. Aqui solo estoy usando una  unica textura que a la vez pueden usar distintas instancias del marine que no han de ser el player por ejemplo, podrian ser npc's o enemigos inclusive. En este caso la tarjeta grafica solo estaria accediendo a una unica textura todo el tiempo para representar todos los marines en pantalla que quiera poner en mi juego y no a distintas texturas por fotograma de animacion por cada instancia del marine (1 textura = 1 acceso = multiples marines, varias texturas = multiples accesos x (n) marines). El escenario seria otro buen ejemplo, una o dos texturas con los sets que uses en el escenario, 1 solo acceso por textura al dibujar todos los tiles que lo forman.

Pero es que el problema de eficiencia aparece cuando tienes que usar tiles de diferentes tilesets: no sólo se desperdicia RAM si no que también tienes que realizar varios accesos a disco, uno por cada tileset cargado.

Cita de: [EX3] en 06 de Marzo de 2011, 08:55:59 PM
Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
La cuestión es: ¿qué ventaja, si es que hay alguna, tienen los tilesets frente al uso de PAKs y/o directorios?
A modo resumen, principalmente el rendimiento y optimizacion de memoria a parte de las posibilidades que ofrece el trabajar con tilesets (el ejemplo del marine). Piensa que los tilesets se llevan usando desde el principio de los desarrollos de juegoos con sprites en maquinas tan limitadas como los Spectrum, las Atari, las NES, Commodore64 y cualquier maquina que tuviera que trabajar con gran cantidad de graficos bitmap en tiempo real, algunas de esas maquinas apenas no tenian potencia suficiente como para andar cambiando de tilesets en tiempo de juego como la NES, que solo usa un mapa completo de tiles para representar los juegos (en cualquier emulador puedes ver esto mediante los exploradores de tiles que tienen):

<imagen_no_quoteada>

Cierto es, tambien, que si tu juego va a ser pequeño y no va a usar una cantidad ingente de graficos pues separar cada tile en una textura suelta tampoco va a ser un problema serio, pero vamos, un RPG o un Shooter desde luego no son el tipo de juegos que usen pocos graficos :)

Ese es el problema: que la clasificación de gráficos con tilesets no la veo tan óptima como con PAKs/Dirs.
Además, usando tilesets, tu programa tiene una modabilidad (no sé si en español sería algo así como "capacidad de ser modificados los gráficos y demás") limitada, ya que el motor de tu juego sólo podrá trabajar con tilesets que usen una distribución idéntica a la original, para la cual ha sido pensada. Alguien que quiera usar un tileset diferente no podrá.

Cita de: [EX3] en 06 de Marzo de 2011, 08:55:59 PM
Cita de: Ubermann en 06 de Marzo de 2011, 01:37:32 PM
Ah, y claro, estamos hablando de un juego 2D tipo plataforma, o RPG o shooter, es decir, cosas relativamente sencillas y que necesitan usar multitud de imágenes diferentes si tener que usar ese mismo número de variables.
Un RPG o un shooter no son precisamente juego sencillos, ni si quiera un plataformas. Que sea 2D no implica que sea mas sencillo que un juego 3D en cuanto a programacion (no siempre). Recuerda que yo llevo años tratando de sacar un juego tipo Prince of Persia (1989) / Another World (1991) / FlashBack (1992) y estos tienen mucha complejidad detras los graficos que muestran y sobre todo contando para las maquinas para las que se desarrollaron por entonces :)

Salu2...

Me refiero a comparar juegos de ese tipo con juegos con IA más compleja y un desarrollo gráfico más avanzado.

Un saludo y gracias por tu opinión. :-)

P.D. Hechelion, perdona, pero no tengo tiempo de responderte en este momento. Editaré el mensaje en cuanto pueda para poder responder.

[EX3]

Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
No me refería a eso.
Su pongamos que, como en mi caso, necesito usar gran cantidad de texturas de suelos, paredes y sprites  (para usar como animaciones o como decoraciones).
Si uso tilesets, por supuesto que puedo tener varios tilesets que contengan un tipo determinado de gráficos, por ejemplo "tilesteSueloCiudad.png", "tilesetSueloBosque.png", etc...
La cosa es que si en uno de los supuestos mapas sólo tengo que usar tres tipos de tiles que estan dentro de "tilesetSueloCiudad", más otros tres tiles diferentes de "tilesetSueloBosque", pues estoy obligado a cargar en memoria todo el tileset entero, a pesar de que voy a usar solamente un par o tres tiles de cada uno de ellos. Se ve claramente que hay un uso innecesario de memoria RAM. Puede que para un RPG que usa sólo dos o tres tilesets, no signifique mucho, pero los gráficos que yo tengo que usar podrían llegar a los 150 ó 200 Mb entre todos. Si a ello le sumamos los sonidos más la música (son MP3s de unos 25-30 Megas), podríamos alcanzar los 300Mb sin ni siquiera darnos cuenta.

Sin embargo, con un PAK o un directorio y subdirectorios, simplemente cargaremos las imágenes que necesitemos exclusivamente.
Sé que es peor cargar y leer "cada dos por tres", pero tampoco es ese el caso, ya que los gráficos a usar se cargan solamente en memoria cuando se inicia el nivel, por lo tanto de estar usando 150Mb pasaríamos a usar poco más de 20Mb. Además con la potencia actual de los ordenadores apenas serían unos segundos de carga. Otra cosa, y esto es indiscutible, es que tuviera que cargar y "descargar" gráficos de memoria a cada frame.
Ahi estas teniendo un problema de diseño si has de cargar 300mb o mas datos en memoria (aunque sea repartida entre la memoria grafica de la GPU y la memoria RAM del sistema). Si usas tilesets es para organizar que necesitas cargar en memoria y que no, no para cargar todo. Obviamente si usas tilesets no vas a cargarlos para leer 3 texturas de uno y 3 de otro, se trata de que las organices de forma que con un tileset grande tengas todos los tiles de un escenario por ejemplo. Si yo tengo que definir un escenario que es un hangar lo mas seguro es que tenga todos los tiles de la tematica hangar en el mismo tileset y no repartidos en varios como suelo, paredes, etc... esto es puro tema de diseño al crear los tilesets, no de que no sean óptimos.

Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
No sería posible para tilesets que no pueden tener un orden o tamaño definidos, por ejemplo, yo tengo tres "animaciones" de monstruos. Cada animación posee "frames" y "states".
Un frame es cada uno de las imágenes que conforman una parte de la animación (como por ejemplo, mover el pié izquierdo cuando camina). Es quizás otra manera de llamar a los tiles.
Un state es cada uno de los tipos de "animación", por ejemplo, el state "atacar", el state "correr", etc...

En teoría, no habría problema si todos los monstruos tuviesen sus tiles del mismo tamaño y en posiciones relativas equivalentes, pero como no es así, resultaría imposible mediante un método "universal" conocer exactamente qué posición y qué dimensiones tiene cada tile de cada monstruo.
Si te fijas en el tileset del marine, ningun tile es del mismo tamaño, las piernas no tienen el mismo tamaño entre si por ejemplo, puedes comprobarlo :) Ese editor permitia definir tiles del tamaño que fuesen y en la posicion que estuvieran dentro de la textura. Tu en un mismo tileset puedes tener tranquilamente distintas animaciones del mismo personaje de los tamaños que quieras y ordenarlas como quieras en tu lista de frames, una cosa es como venga distribuidos los tiles en la textura y otra como ordenes tu la lista de frames.

Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Sin embargo, con directorios o PAKs, simplemente hago una llamada a un método que carge la imagen cuyo archivo se llama, por ejemplo, "zombieWalk01.png", y así con todos los frames de "zombieWalk".
Con tilesets igual. La textura por un lado y tu archivo que defina la tabla de tiles y animaciones por otro. Ventajas? En dicho archivo puedes definir parametros de tu animacion, tiempos de lapso entre frames, sentido predefinido de la animacion, si es bucle o no, puntos de control para definir puntos calientes en tus tiles (si has programado con Div Game Studio sabras de que te hablo) y cualquier cosa que necesites. Esa flexibilidad el archivo PAK no te lo da. Tu "zombiewalk" seria sencillamente una animacion con un nombre definida en la tabla de animaciones que internamente no dejaria de ser una lista de las claves de los tiles que la forman, en que orden van y que tiempo de lapso tiene entre ellas.

Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Pues más organizado que un directorio y subdirectorios no encuentro yo otra manera, y mças aún si dentro de "suelosBosque" puede haber varios tipos diferentes, como por ejemplo "hierba", "árboles", "agua", "tierra" y dentro de cada uno de ellos más clasificaciones todavía.
Bueno, esto es discutible, para mi es mas organizado tener un tileset con todos los graficos de "arboles de bosque", por otro tener "arboles de costa", etc... aqui puede ser mas gusto que otra cosa. Esa organizacion de directorios yo lo aplico pero en un nivel por encima de lo que es un tileset, osea, lo usaria para organizar los tilesets en si, asi como el resto de recursos (sonidos, mapas, etc...), pero yo es que yo no considero un tile un recurso si no parte de un recurso (esto es como si dijeras de en vez de usar fuentes de texto crearas un grafico por cada caracter de la fuente en si, seria lo mismo).

Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Pero es que el problema de eficiencia aparece cuando tienes que usar tiles de diferentes tilesets: no sólo se desperdicia RAM si no que también tienes que realizar varios accesos a disco, uno por cada tileset cargado.
Lo primero que con accesos no me refiero a disco (cargar la textura desde el disco duro) si no a la accion que realiza la GPU al dibujar una textura que es cambiar la textura del buffer por otra. Ese acceso tiene un coste de rendimiento a la larga. Un par de ejemplos:

Un tileset (el del marine que te mostre mas arriba), 100 marines en pantalla con distintas configuraciones, contando con que cada marine tiene, digamos, 4 partes (piernas, brazos, torso, cabeza), por cada marine solo accedo una vez a la textura a la hora de dibujarlo aun cambiando el tile de animación o estado (disparo, carrera, etc...) ya que todas las partes estan dentro de la misma textura. 1 x 100 = 100 accesos, si dibujo todos los marines de una tacada no hay cambio de textura al dibujar, entonces solo tendria un solo acceso a la textura para dibujar los 100 marines.

Una textura por tile (texturas de brazos, piernas, cabezas, armas, etc...), 100 marines (igual configuración, 4 piezas) por cada marine tendría que acceder en un solo frame (sin animar) a 4 texturas distintas (4 x 100 = 400 cambios de textura al dibujar los 100 marines) y siendo animado multiplica esos 400 accesos por fotogramas que tenga la animacion. Aunque dibujes todos los marines de una tacada seguirías teniendo 400 accesos a texturas en memoria.

Entonces, que metodo realiza mas accesos por frame? Cual consume mas proceso para hacer lo mismo?

Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Ese es el problema: que la clasificación de gráficos con tilesets no la veo tan óptima como con PAKs/Dirs.
Además, usando tilesets, tu programa tiene una modabilidad (no sé si en español sería algo así como "capacidad de ser modificados los gráficos y demás") limitada, ya que el motor de tu juego sólo podrá trabajar con tilesets que usen una distribución idéntica a la original, para la cual ha sido pensada. Alguien que quiera usar un tileset diferente no podrá.
Falso. Si alguien quiere usar su propio tileset con mi motor sencillamente tendria que usar la misma herramienta que use yo, que es la te mostre mas arriba, tendria que cargar su textura, definir los tiles y organizarlos a su antojo, definir sus puntos de control si los necesita, y las animaciones que tuviera o necesitara. Despues solo daria a un boton para generar el archivo con la tabla de tiles y animaciones listo para ser usado al momento en el motor (que dicho sea, la clase Sprite que usaba mi motor realizaba todo el proceso en una sola y unica llamada, al cargar dicho archivo se preparaba toda la informacion de tiles y animaciones de forma automatica, mas facil imposible).






Si has dedicado tiempo alguna vez haciendo mods para juegos como Half-Life veras que el uso de archivos paquete se utiliza para cosas mas practicas como control de versiones, esto es, yo distribuyo el juego con unos recursos pero mañana tengo que actualizar parte de ellos y en vez de pasarte un unico archivo paquete con todos los recursos + los modificados solo te paso un paquete con los recursos modificados, que al ser mas actuales el motor toma en cuenta a la hora de buscarlos en el arbol de recursos que genera al iniciarse el juego (listas todos los recursos ordenando los paquetes que haya disponibles bien por fecha o bien por nombre como hacia el Half-Life). Mas alla de esto, motores como Half-Life al final usaban tambien tilsets para sus texturas (un formato de archivo que contenia el mapa de texturas y la tabla de referencia a las mismas) y asi tecnologias actuales siguen funcionando con la misma mecanica. Por algo sera, no? :)

Lo que si seria practico con un archivo PAK es hacerte un formato contenedor que, por ejemplo (y es lo que hacia tambien Half-Life con los modelos 3D) es contener  la definicion de tu personaje, sus animaciones, que partes lo forman y el tileset que usa. Eso seria practico por que asi no tendrias archivos sueltos en un directorio si no solidamente en un archivo, pero claro, esto al final no afecta al rendimiento del motor, esto, como lo de los paquetes, es puro mantenimiento para el desarrollador, ya que de esto no se beneficia para nada el jugador ni el juego en si y en estos temas hay que medirse y saber hasta que punto merece la pena invertir esfuerzo en mantenimiento y cuanto en desarrollo del juego en si. Yo, por ejemplo, en mi version actual de XNA ya no uso tilesets con frames de distintos tamaños si no el tileset tradicional de todos los frames en fila y con el mismo tamaño. Esto me ha evitado tener que programarme otro editor de tiles con todas las funciones que veias y el codigo de logica de las animaciones se ha reducido a un par de lineas y a interpretar un XML que autogenera el juego a modo de editor en una simple llamada. Sencillez ante todo.

Si tu consideras que organizarte por paquetes es mas beneficioso para ti que usar tilesets adelante pues, puede serte mas o menos comodo separar tiles por textura que andar definiendo tablas de tiles y una sola textura pero desde luego no es optimo por como funcionan las tarjetas graficas a la hora de acceder a su contenido como ya te hemos explicado y no es cuestion solo de enfocarse en gastar poca memoria o en optimizar hasta el maximo si no de tener un equilibrio entre ambos.

Salu2... ;)

P.D.: Lo que si seria interesante a medio camino de tu idea de los paquetes y los tilesets seria que al cargar los tiles que necesitas los unieras en memoria bajo una misma textura (respetando el tamaño de potencia de 2) que fuera la que usaras como tileset autogenerado para dibujar en el juego, seguirias manteniendo tu sistema de organizacion por directorios en los paquetes y tendrias optimizado la parte del acceso a las texturas en memoria, lo mejor de ambos mundos aunque con un coste de desarrollo mayor :)
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Ubermann

Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
No me refería a eso.
Su pongamos que, como en mi caso, necesito usar gran cantidad de texturas de suelos, paredes y sprites  (para usar como animaciones o como decoraciones).
Si uso tilesets, por supuesto que puedo tener varios tilesets que contengan un tipo determinado de gráficos, por ejemplo "tilesteSueloCiudad.png", "tilesetSueloBosque.png", etc...
La cosa es que si en uno de los supuestos mapas sólo tengo que usar tres tipos de tiles que estan dentro de "tilesetSueloCiudad", más otros tres tiles diferentes de "tilesetSueloBosque", pues estoy obligado a cargar en memoria todo el tileset entero, a pesar de que voy a usar solamente un par o tres tiles de cada uno de ellos. Se ve claramente que hay un uso innecesario de memoria RAM. Puede que para un RPG que usa sólo dos o tres tilesets, no signifique mucho, pero los gráficos que yo tengo que usar podrían llegar a los 150 ó 200 Mb entre todos. Si a ello le sumamos los sonidos más la música (son MP3s de unos 25-30 Megas), podríamos alcanzar los 300Mb sin ni siquiera darnos cuenta.

Sin embargo, con un PAK o un directorio y subdirectorios, simplemente cargaremos las imágenes que necesitemos exclusivamente.
Sé que es peor cargar y leer "cada dos por tres", pero tampoco es ese el caso, ya que los gráficos a usar se cargan solamente en memoria cuando se inicia el nivel, por lo tanto de estar usando 150Mb pasaríamos a usar poco más de 20Mb. Además con la potencia actual de los ordenadores apenas serían unos segundos de carga. Otra cosa, y esto es indiscutible, es que tuviera que cargar y "descargar" gráficos de memoria a cada frame.
Ahi estas teniendo un problema de diseño si has de cargar 300mb o mas datos en memoria (aunque sea repartida entre la memoria grafica de la GPU y la memoria RAM del sistema). Si usas tilesets es para organizar que necesitas cargar en memoria y que no, no para cargar todo. Obviamente si usas tilesets no vas a cargarlos para leer 3 texturas de uno y 3 de otro, se trata de que las organices de forma que con un tileset grande tengas todos los tiles de un escenario por ejemplo. Si yo tengo que definir un escenario que es un hangar lo mas seguro es que tenga todos los tiles de la tematica hangar en el mismo tileset y no repartidos en varios como suelo, paredes, etc... esto es puro tema de diseño al crear los tilesets, no de que no sean óptimos.

No, si ya entiendo eso lo que comentas de que cada tileset tiene su propia clasificación, pero ¿qué ocurre si tienes que usar texturas de bosque y texturas de nave espacial? Seguramente tengas un tileset para bosque y otra para nave espacial, por lo cual vas a tener que cargar en memoria ambos tilesets para acceder a las texturas correspondientes.
Y la cosa se podría complicar si tienes que usar texturas de nave espacial, de bosque y de ciudad (por ejemplo para simular un escenario urbano con naturaleza y elementos como naves espaciales pequeñas).

Lógicamente, y es imposible estar en desacuerdo contigo, se organizará la cosa lo mejor posible.

Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
No sería posible para tilesets que no pueden tener un orden o tamaño definidos, por ejemplo, yo tengo tres "animaciones" de monstruos. Cada animación posee "frames" y "states".
Un frame es cada uno de las imágenes que conforman una parte de la animación (como por ejemplo, mover el pié izquierdo cuando camina). Es quizás otra manera de llamar a los tiles.
Un state es cada uno de los tipos de "animación", por ejemplo, el state "atacar", el state "correr", etc...

En teoría, no habría problema si todos los monstruos tuviesen sus tiles del mismo tamaño y en posiciones relativas equivalentes, pero como no es así, resultaría imposible mediante un método "universal" conocer exactamente qué posición y qué dimensiones tiene cada tile de cada monstruo.
Si te fijas en el tileset del marine, ningun tile es del mismo tamaño, las piernas no tienen el mismo tamaño entre si por ejemplo, puedes comprobarlo :) Ese editor permitia definir tiles del tamaño que fuesen y en la posicion que estuvieran dentro de la textura. Tu en un mismo tileset puedes tener tranquilamente distintas animaciones del mismo personaje de los tamaños que quieras y ordenarlas como quieras en tu lista de frames, una cosa es como venga distribuidos los tiles en la textura y otra como ordenes tu la lista de frames.

Creo que ya entiendo cómo has implementado lo de los tiles: si mal no he entendido, básicamente usas dos ficheros: uno con los tiles (uno o los que sean) y otro con los índices de posiciones y demás info.

Siendo así, ya lo veo más viable, pero aún así, no sé hasta qué punto podría ser interesante el uso de tilesets para juegos que usan una gran cantidad de gráficos, todos ellos diferentes entre sí.

Pero de todas maneras, intentaré experimentar con algo como lo que tú hiciste (tileset/s + fichero de índices), pero con mis propias rutinas.
Quizás pueda conseguir una solución interesante...

Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Sin embargo, con directorios o PAKs, simplemente hago una llamada a un método que carge la imagen cuyo archivo se llama, por ejemplo, "zombieWalk01.png", y así con todos los frames de "zombieWalk".
Con tilesets igual. La textura por un lado y tu archivo que defina la tabla de tiles y animaciones por otro. Ventajas? En dicho archivo puedes definir parametros de tu animacion, tiempos de lapso entre frames, sentido predefinido de la animacion, si es bucle o no, puntos de control para definir puntos calientes en tus tiles (si has programado con Div Game Studio sabras de que te hablo) y cualquier cosa que necesites. Esa flexibilidad el archivo PAK no te lo da. Tu "zombiewalk" seria sencillamente una animacion con un nombre definida en la tabla de animaciones que internamente no dejaria de ser una lista de las claves de los tiles que la forman, en que orden van y que tiempo de lapso tiene entre ellas.

Es decir, lo que he comentado justo arriba.

Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Pues más organizado que un directorio y subdirectorios no encuentro yo otra manera, y mças aún si dentro de "suelosBosque" puede haber varios tipos diferentes, como por ejemplo "hierba", "árboles", "agua", "tierra" y dentro de cada uno de ellos más clasificaciones todavía.
Bueno, esto es discutible, para mi es mas organizado tener un tileset con todos los graficos de "arboles de bosque", por otro tener "arboles de costa", etc... aqui puede ser mas gusto que otra cosa. Esa organizacion de directorios yo lo aplico pero en un nivel por encima de lo que es un tileset, osea, lo usaria para organizar los tilesets en si, asi como el resto de recursos (sonidos, mapas, etc...), pero yo es que yo no considero un tile un recurso si no parte de un recurso (esto es como si dijeras de en vez de usar fuentes de texto crearas un grafico por cada caracter de la fuente en si, seria lo mismo).

Supongamos un juego de plataformas "sidescroll" (osea, tipo mario bros). En el nivel 1, el jugador empieza a la izquierda de todo en un ambiente costero (tiles de arena, de agua, de árboles de costa, etc...). A medida que avanza hacia la derecha, se va transformando en bosque (hierba, árboles de bosque, tierra, etc...) y finalmente se convierte en una ciudad futurista (tiles de edificios, de asfalto, partes metálicas, lices de neon, etc...).
En esta caso, y que es bastante normal, tendrías que cargar tres tilesets diferentes.
Si cada tileset ocupa 5 Mb, pues ya estás consumiendo 25Mb, sólo para buscar 10 o 15 tiles diferentes.

Pero por otro lado, con PAKs sólo consumes la memoria de los gráficos que necesites. Claro que vas a realizar más accesos a disco y demás.

Es decir, lo que uno tiene de ventaja, otro lo tiene de desventaja.
Creo que podría ser cuestión de gustos :-P

Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Pero es que el problema de eficiencia aparece cuando tienes que usar tiles de diferentes tilesets: no sólo se desperdicia RAM si no que también tienes que realizar varios accesos a disco, uno por cada tileset cargado.
Lo primero que con accesos no me refiero a disco (cargar la textura desde el disco duro) si no a la accion que realiza la GPU al dibujar una textura que es cambiar la textura del buffer por otra. Ese acceso tiene un coste de rendimiento a la larga. Un par de ejemplos:

Un tileset (el del marine que te mostre mas arriba), 100 marines en pantalla con distintas configuraciones, contando con que cada marine tiene, digamos, 4 partes (piernas, brazos, torso, cabeza), por cada marine solo accedo una vez a la textura a la hora de dibujarlo aun cambiando el tile de animación o estado (disparo, carrera, etc...) ya que todas las partes estan dentro de la misma textura. 1 x 100 = 100 accesos, si dibujo todos los marines de una tacada no hay cambio de textura al dibujar, entonces solo tendria un solo acceso a la textura para dibujar los 100 marines.

Una textura por tile (texturas de brazos, piernas, cabezas, armas, etc...), 100 marines (igual configuración, 4 piezas) por cada marine tendría que acceder en un solo frame (sin animar) a 4 texturas distintas (4 x 100 = 400 cambios de textura al dibujar los 100 marines) y siendo animado multiplica esos 400 accesos por fotogramas que tenga la animacion. Aunque dibujes todos los marines de una tacada seguirías teniendo 400 accesos a texturas en memoria.

Entonces, que metodo realiza mas accesos por frame? Cual consume mas proceso para hacer lo mismo?

Pero, hablando de PAKs/Dirs, se pueden cargar todos los frames del marine (creo que son 50 o así), al principio del nivel, mientras éste se carga, por lo que ya tendrías en memoria todos los frames de susodicho marine.

Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Cita de: Ubermann en 07 de Marzo de 2011, 04:29:24 PM
Ese es el problema: que la clasificación de gráficos con tilesets no la veo tan óptima como con PAKs/Dirs.
Además, usando tilesets, tu programa tiene una modabilidad (no sé si en español sería algo así como "capacidad de ser modificados los gráficos y demás") limitada, ya que el motor de tu juego sólo podrá trabajar con tilesets que usen una distribución idéntica a la original, para la cual ha sido pensada. Alguien que quiera usar un tileset diferente no podrá.
Falso. Si alguien quiere usar su propio tileset con mi motor sencillamente tendria que usar la misma herramienta que use yo, que es la te mostre mas arriba, tendria que cargar su textura, definir los tiles y organizarlos a su antojo, definir sus puntos de control si los necesita, y las animaciones que tuviera o necesitara. Despues solo daria a un boton para generar el archivo con la tabla de tiles y animaciones listo para ser usado al momento en el motor (que dicho sea, la clase Sprite que usaba mi motor realizaba todo el proceso en una sola y unica llamada, al cargar dicho archivo se preparaba toda la informacion de tiles y animaciones de forma automatica, mas facil imposible).

Sí, eso sí, pero si la persona que quiere hacer alguna modificación tendrá que crear también el fichero de índices, además de tener que usar ese programa que has puesto arriba para organizar los tilesets y sus tiles.

Pero con ficheros dentro de PAKs/Dirs, simplemente habría que nombrar a los archivos con un nombre cualquiera más un índice, sin necesidad de usar otras herramientas.





Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Si has dedicado tiempo alguna vez haciendo mods para juegos como Half-Life veras que el uso de archivos paquete se utiliza para cosas mas practicas como control de versiones, esto es, yo distribuyo el juego con unos recursos pero mañana tengo que actualizar parte de ellos y en vez de pasarte un unico archivo paquete con todos los recursos + los modificados solo te paso un paquete con los recursos modificados, que al ser mas actuales el motor toma en cuenta a la hora de buscarlos en el arbol de recursos que genera al iniciarse el juego (listas todos los recursos ordenando los paquetes que haya disponibles bien por fecha o bien por nombre como hacia el Half-Life). Mas alla de esto, motores como Half-Life al final usaban tambien tilsets para sus texturas (un formato de archivo que contenia el mapa de texturas y la tabla de referencia a las mismas) y asi tecnologias actuales siguen funcionando con la misma mecanica. Por algo sera, no? :)

No es por desmerecer tu opinión, pero si hablamos de juegos modernos, no sé cuál usa tilesets o algún método análogo para almacenar los gráficos.

De hecho, creo que desde Wolfenstein3D hasta hoy en día, el 90% de los juegos, bién sean 3D ó 2D, usan algún sistema de almacenamiento de gráficos como PAKs, ZIPs, directorios o similares.


Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Lo que si seria practico con un archivo PAK es hacerte un formato contenedor que, por ejemplo (y es lo que hacia tambien Half-Life con los modelos 3D) es contener  la definicion de tu personaje, sus animaciones, que partes lo forman y el tileset que usa. Eso seria practico por que asi no tendrias archivos sueltos en un directorio si no solidamente en un archivo, pero claro, esto al final no afecta al rendimiento del motor, esto, como lo de los paquetes, es puro mantenimiento para el desarrollador, ya que de esto no se beneficia para nada el jugador ni el juego en si y en estos temas hay que medirse y saber hasta que punto merece la pena invertir esfuerzo en mantenimiento y cuanto en desarrollo del juego en si. Yo, por ejemplo, en mi version actual de XNA ya no uso tilesets con frames de distintos tamaños si no el tileset tradicional de todos los frames en fila y con el mismo tamaño. Esto me ha evitado tener que programarme otro editor de tiles con todas las funciones que veias y el codigo de logica de las animaciones se ha reducido a un par de lineas y a interpretar un XML que autogenera el juego a modo de editor en una simple llamada. Sencillez ante todo.

Bueno, claro, pero es que en este caso estamos hablando de modelos 3D que lógicamente es imposible almacenar en tilesets :P

Y ahí mismo has dicho tu el problema, si alguien quiere, en un motor de XNA, usar un tileset con tiles de 32x32, mezclados con 48x48 o incluso 32x48 o 16x64, ahí ya tendría un problema.
Incluso el propio programador (tú) necesitarías hacerte tus propias rutinas para casos específicos, limitandote a la hora de la "libertad de modificación".

Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Si tu consideras que organizarte por paquetes es mas beneficioso para ti que usar tilesets adelante pues, puede serte mas o menos comodo separar tiles por textura que andar definiendo tablas de tiles y una sola textura pero desde luego no es optimo por como funcionan las tarjetas graficas a la hora de acceder a su contenido como ya te hemos explicado y no es cuestion solo de enfocarse en gastar poca memoria o en optimizar hasta el maximo si no de tener un equilibrio entre ambos.

Salu2... ;)

Soy un acérrimo seguidor de la organización jerarquizada.


Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
P.D.: Lo que si seria interesante a medio camino de tu idea de los paquetes y los tilesets seria que al cargar los tiles que necesitas los unieras en memoria bajo una misma textura (respetando el tamaño de potencia de 2) que fuera la que usaras como tileset autogenerado para dibujar en el juego, seguirias manteniendo tu sistema de organizacion por directorios en los paquetes y tendrias optimizado la parte del acceso a las texturas en memoria, lo mejor de ambos mundos aunque con un coste de desarrollo mayor :)

No me parece mala idea. Aunque tampoc la veo tan buena, ya que tendríamos que cargar en memoria todos los gráficos de juego desde el principio.
Para el sistema de índices, podría implementarse un directorio (un fichero de texto) dentro del propio PAK (o incluso fuera de éste) que contenga un listado con el nombre de los carpetas y subcarpetas virtuales del PAK, de manera que crear un sistema de indexación durante el runtime (creo que en español sería "tiempo de ejecución") sólo sería cuestión de interpretar el directorio (el archivo de texto), y nombrar a cada gráfico con el nombre de su carpeta contenedora y un índice que indique su "posición" dentro de la carpeta virtual.
También habría que generar por cada gráfico la posición de su esquina superior derecha, su anchura y altura.

No parece muy complicado, aunque a decir verdad, no sé si dx_lib32 ofrece algun método para obtener esta información de un gráfico, al menos su altura y anchura.

Además, otra ventaja que acabo de darme cuenta: permite una gran libertad a la hora de ser modificado por otros usuarios: éstos solamente tendrían que crear un fichero con un listado de la estructura de directorios y subdirectorios del PAK.
Luego, el editor de mapa, se encargaría de realizar el sistema de indexación y añadir los gráficos a la lista de gráficos.
Y finalmente, el juego haría lo mismo que el editor de mapas, pero pondría las texturas apropiadas según se indique en el mapa.
Es más, podría generarse el archivo de índices una única vez y almacenarlo en cualquier sitio, incluso dentro del propio PAK. Esto evitaría tener que generarlo y perder tiempo más de una vez.

Hechelion

#6
 8o

Podría quotear y contesta a varias cosas, pero no estoy con mucho tiempo así que voy a darte un pequeño resumen.

Si necesitas cargar 25 MB de gráficos para usar 100K en el juego, da igual el método que uses (Tiles o no tiles). Estás haciendo mal uso del recurso, si vas a usar un tile de bosque, 2 tiles de costa y 6 tiles de luces de neon, entonces metes esos 9 tile en una única textura. En ninguna parte dice que debes cargar 3 texturas de 5 MB cada una.
En otras palabras, no andas cargando 3 CD de música para escuchar una canción de cada una. Tomas lo que quieres de cada CD y te quemas tu propio compilado, lo otro es desperdiciar recursos y si lo quieres hacer así, es tu decisión pero no le cargues una mala decisión de diseño a la técnologia (ya decía mi madre que el cojo le hecha la culpa al empedrado  :P).
O sea, los Tiles no son menos eficientes, lo que pasa es que estás buscando la peor solución posible y estás dando un ejemplo, donde cualquier programador o grafista se daría cuenta que hay un problema de diseño (cargar 25 MB para usar 100K), así que no es culpa de que el tileset sea más o menos eficiente, ese ejemplo sería una mala decisión de diseño.


Da igual si usas o no usas Tile, igual necesitas instrucciones para crear un mapa. Además, por lo que entiendo, tu no hablas de tener el mapa entero creado como gráfico (o eso creo) igual hablas de una solución por tile (partes pequeñas que compone un mapa más grande), la única diferencia es que tu hablas de tener un tile por textura, lo cual es menos optimo que meterlos en una única textura.
Todos los juegos hacen eso, mira la textura de un arma en un L2 por ejemplo y veras que todos los gráficos del objeto están metidos en una única textura y que la textura está dividida en varias partes, no tienes un archivo para el mango y otro para el filo, porque tal como te explico Ex3 es menor eficiente.

Volviendo al tema de construir el mapa, tu necesitas o un archivo o código que le diga al juego como debe mostrar las texturas, en tu solución (y fijate que no hablo por PAK ,porque como te dije antes, estás mezclando conceptos) muchos archivos componen una imagen y necesitas ordenarlos para que se vea un mapa. por ejemplo
Agua-Agua-costa-tierra

Si usar una única textura para el mapa, entonces a tu información sólo debes agregarle las coordenadas:
(0,0,32,32)-(0,0,32,32)-(32,0,32,32)-(64,0,32,32)

En una solución usas nombres de archivos, en la otra coordenadas. A nivel de lógica la información que usas para construir el mapa es similar.

Por último, no sé de donde sacas que si usas tiles de 32*32 estás obligado a usar todos los tiles de 32*32, eso depende de como implementes el motor y te lo digo porque yo mismo tengo creado un editor de animaciones para dx_lib32 donde puedes definir todos los tiles que quieras y si te molesta tener que adjuntar un editor con el juego, imagina lo molesto que resulta para otra persona intentar descifrar como funciona una nomenclatura, si no colocas el editor, necesitas por lo menos entregar un manual, así que mucha diferencia no hay. No es intuitivo usar indices, porque un mapa o un conjunto de animaciones no son lineales.


EDIT:
Ahora, si te refieres a que tener unidades más pequeñas que te permitan reutilizar de mejor forma los recursos sin cargar extras, entonces mientras más pequeña sea la textura será mejor (en cada nivel cargas sólo lo que quieres sin repetir nada), si te refieres a eso, pues  si, tener un archivo por textura es mejor, pero eso acarrea otros problemas como ya te explico Ex3, vas a necesitas más ciclos de PC para crear lo mismo. Así que debes sacrificar una en post de la otra y eso ya depende de tu juego, pues cada juego es diferente y tiene necesidades diferentes.

Hoy en día, es más valioso el ciclo de CPU que la cantidad de memoria, si me preguntas que es mejor, cargar 25MB en video o reducir la tasa de FPS a la mitad, pues me quedo con cargar los 25MB, cualquier tarjeta actual (incluso las intel integradas) no suelen partir por debajo de los 128 MB. Pero como te digo, depende de las necesidades de cada juego.

[EX3]

Vamos por partes que me ha quedado una replica bien extensa :P y la aplicacion del iPhone ya le cuesta hasta cargar nuestros eternos posts xD

Al tema:



Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
Creo que ya entiendo cómo has implementado lo de los tiles: si mal no he entendido, básicamente usas dos ficheros: uno con los tiles (uno o los que sean) y otro con los índices de posiciones y demás info.
No exactamente, uno es la textura (PNG o lo que sea), otro el archivo de definicion de tiles que seria la tabla de tiles (clave, dimensiones del tile, puntos de control) y opcionalmente el archivo de animaciones, una tabla de secuencias de animacion, que viene a ser una tabla cuyas secuencias hacen referencia a la tabla de tiles anterior (sus claves) a parte de agregar parametros como si es animacion en bucle, sentido de la animacion (hacia adelante o hacia atras) y el lapso de tiempo entre fotogramas. Esto era por que la clase Sprite de mi motor trabajaba con otra que era un gestor de animaciones, al gestor internamente se le hacia referencia a la textura asociada, otro objeto del motor que era la representacion de la textura con su informacion de tamaño y su lista de tiles. El objeto Sprite gestionaba todo esto de forma transparernte, sencillamente cargando y leyendo sendos archivos a los que no habia que hacer ni referencia alguna ya que al objeto Sprite simplemente le indicabas la textura a cargar y ya buscaba si la textura tenia asociado archivo de tiles y de animaciones, todo en una simple llamada.

Y llegamos a la parte importante :)
Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
Supongamos un juego de plataformas "sidescroll" (osea, tipo mario bros). En el nivel 1, el jugador empieza a la izquierda de todo en un ambiente costero (tiles de arena, de agua, de árboles de costa, etc...). A medida que avanza hacia la derecha, se va transformando en bosque (hierba, árboles de bosque, tierra, etc...) y finalmente se convierte en una ciudad futurista (tiles de edificios, de asfalto, partes metálicas, lices de neon, etc...).
En esta caso, y que es bastante normal, tendrías que cargar tres tilesets diferentes.
Si cada tileset ocupa 5 Mb, pues ya estás consumiendo 25Mb, sólo para buscar 10 o 15 tiles diferentes.

Pero por otro lado, con PAKs sólo consumes la memoria de los gráficos que necesites. Claro que vas a realizar más accesos a disco y demás.

Es decir, lo que uno tiene de ventaja, otro lo tiene de desventaja.
Creo que podría ser cuestión de gustos :-P
No es cuestion solo de gustos si no del equilibrio entre optimizacion y productividad que te hablaba anteriormente. Te vuelvo a ejemplo de los accesos del marine pero ahora con el escenario y buscando en lo posible el maximo ahorro de memoria que propones:

Tienes tu escenario con las 3 tematicas, cada tematica digamos que tenemos unos 25 tiles, cada uno en formato PNG al maximo de compresion y con canal alpha para las transparencias en degradado, 25 x 3 = 75 tiles en total (2.4kb por tile, 75 x 2.4 = 180 Kb). Contando con los elementos del escenario, enemigos, npc's, jugador y cualquier elemento que tenga animaciones, 25 tiles por enemigo, 25 por npc, 25 por jugador (pongamos ahora que cada tile de animacion son 6kb y que cada personaje tiene una media de 40 fotogramas/tile, 3 x 40 = 120 x 6 = 720Kb), tenemos en memoria solo en graficos 900Kb, casi un megabyte.

Digamos que tu escenario lo representas a una resolucion de 1024x768 (la vista que se vera del escenario, no el escenario completo) y tus tiles son de 32x32 por ejemplo (pongamos el caso extremo de que todos los tiles en esta vista son distintos, 32 x 32 = 1024 tiles distintos en pantalla solo con el escenario), tienes ahora en pantalla 8 enemigos, 3 npc's y el jugador, pongamos como el marine del otro ejemplo de estar particionado en 4 piezas (8 * 4 + 3 * 4 + 1 * 4 = 48 tiles en total). En un solo fotograma de tu escena estas realizando 1072 accesos secuenciales a la memoria de la GPU en menos de un segundo. Con una tasa asi quizas solo el renderizado te este bajando la frecuencia de actualizacion a 40/30fps, no esta mal. Ahora sumale lo que tarde en procesar toda la logica de la escena (determinar donde esta la camara, que tiles estan activos, cuales dibujar, cuales animar, comprobar las colisiones de todos los objetos del escenario y que esten en pantalla (sumale ahi otro descarte de elementos), etc...), los enemigos y npc's (su IA, sus estados, coordinar y cuadrar sus partes que lo forman...) , el jugador (sus estados, la coordinacion de las piezas, etc...), etc... etc...  Ahi puede que tu tasa de actualizacion haya bajado a 24fps si no mas. Por debajo de 30fps ya se considera muy poco fluido.


Tilesets. Tenemos varios tilesets, digamos que tengo uno de 1024x256, otro de 512x256 y otro de 512x512, consecutivamente para cada tematica y sin ocupar todo el espacio util de cada textura. Cada tileset, consecutivamente, 400Kb, 250Kb y 380Kb, luego por cada set de cada personaje, el enemigo y el npc, por separado, a 256x128, y el jugador 256x256 por que tiene mas variantes de animacion: enemigo 56Kb, npc 56Kb y jugador 102Kb, en total, tilesets de escenario y tilesets de personajes, 1244Kb -> 1.25Mb de texturas en memoria. No esta nada mal contando con que las texturas no estan ocupadas por completo.

Mismo escenario, 1024 tiles. Seamos puñeteros y pongamos que la vista actual de escenario tiene tiles de los 3 tilesets pero mas o menos desordenados. Esto quiere decir que tendre mas de 3 accesos ya que tendre que ir saltando de un tileset a otro cada x tiles dibujados (cuando dibuje uno que no sea del tileset actual), pongamos 10 accesos, no 20 accesos (tiremos a mas). Los personajes, igual, 8 enemigos, 3 npc's y nuestro jugador, 4 piezas por personaje. Volvamos a ser puñeteros, supongamos que los personajes en la lista de elementos del escenario no estan en orden, tenemos 3 enemigos, 2 npcs, 2 enemigos, el jugador, otro npc y 3 enemigos, al dibujarlos hare 1 acceso comun para los 3 primeros enemigos al mismo tileset, un acceso al tileset del npc para dibujar 3 de ellos, otra vez un acceso al del enemigo para dibujar dos de ellos, un acceso al tileset del jugador para dibujarlo, otro acceso al npc y otro acceso al del enemigo, en total 6 accesos distintos para dibujar los personajes. 20 accesos del escenario + 6 accesos de los personajes = 26 accesos y una burrada de tiles dibujados (mas de 1000 solo en escena), eso quizas no se inmute apenas al renderizar por lo que sobradamente consigo la tasa de 60fps solo al renderizar. Esto esta genial. Sumando la misma logica de juego que antes, solo con lo que pesa el codigo de colisiones, la IA y demas acciones que mencione antes, mi tasa seguramente siga por encima de 40fps si no se mantiene con suerte todavia cerca de 60fps.

Resumen, tu juego ocupa solo en graficos menos de un megabyte pero no sobrepasa una tasa superior a 30 fps que deberia ser el minimo para una fluidez notable. Mi juego ocupa solo en graficos un megabyte y medio y pongamos que se mantiene a una tasa media de 40fps tirando a lo bajo en los momentos criticos (demasiados elementos en pantalla, muchos enemigos pensando con su IA como matarme, etc...) por lo que mantiene una fluidez mas que aceptable. Te ha merecido la pena ahorrar unos escasos bytes de memoria en pro de separar los tiles por texturas y organizarlos en un paquete? Yo diria que no :)

Archivos. Tu usas la vara de medir tiles como si fueran texturas ya que trabajas con archivos sueltos pero no caes en el detalle de que 1000 tiles separados en texturas no ocupan lo mismo que 1000 tiles dentro de una sola textura. Por que? Un archivo de textura no solo contiene los pixeles de la textura, como cualquier otro archivo este define una cabecera con informacion del formato y en caso de formatos como el PNG define tambien un mapa de pixeles mas para definir la mascara de transparencia del canal Alpha. Si separas los tiles por texturas tienes a la larga un numero de datos extra que son la los pixeles de cada textura + su mascara de transparencia. Si cargas un tileset solo cargas un mapa de pixeles y una mascara de transparencia para todo el grupo de tiles.

Equilibrio y productividad, de nada te sirve obsesionarte solo con optimizar la memoria si con ello te olvidas del rendimiento, no sirve de nada que tu juego ocupe un 48Kb si se hace injugable y encima el rendimiento hay que medirlo con lupa en lenguajes tan pesados y lentos como Visual Basic 6.0 que es en lo que esta programada la libreria. En temas de memoria y rendimiento, te va a dar igual en la practica cargar 2 texturas de 1024x1024 que 8 texturas de 256x256 ya que apenas vas tener problemas (que ya no programamos con 48Kb como en los Spectrum :P). En serio, no hay que obsesionarse tanto con el ahorro de memoria, se trata de hacer un uso razonable.

(continua)
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

[EX3]

Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
Cita de: [EX3] en 07 de Marzo de 2011, 07:43:46 PM
Lo primero que con accesos no me refiero a disco (cargar la textura desde el disco duro) si no a la accion que realiza la GPU al dibujar una textura que es cambiar la textura del buffer por otra. Ese acceso tiene un coste de rendimiento a la larga. Un par de ejemplos:

Un tileset (el del marine que te mostre mas arriba), 100 marines en pantalla con distintas configuraciones, contando con que cada marine tiene, digamos, 4 partes (piernas, brazos, torso, cabeza), por cada marine solo accedo una vez a la textura a la hora de dibujarlo aun cambiando el tile de animación o estado (disparo, carrera, etc...) ya que todas las partes estan dentro de la misma textura. 1 x 100 = 100 accesos, si dibujo todos los marines de una tacada no hay cambio de textura al dibujar, entonces solo tendria un solo acceso a la textura para dibujar los 100 marines.

Una textura por tile (texturas de brazos, piernas, cabezas, armas, etc...), 100 marines (igual configuración, 4 piezas) por cada marine tendría que acceder en un solo frame (sin animar) a 4 texturas distintas (4 x 100 = 400 cambios de textura al dibujar los 100 marines) y siendo animado multiplica esos 400 accesos por fotogramas que tenga la animacion. Aunque dibujes todos los marines de una tacada seguirías teniendo 400 accesos a texturas en memoria.

Entonces, que metodo realiza mas accesos por frame? Cual consume mas proceso para hacer lo mismo?

Pero, hablando de PAKs/Dirs, se pueden cargar todos los frames del marine (creo que son 50 o así), al principio del nivel, mientras éste se carga, por lo que ya tendrías en memoria todos los frames de susodicho marine.
Creo que sigues confundiendo los accesos a memoria con la carga de archivos. Con accesos me refiero la accion que realiza la tarjeta grafica internamente de seleccionar en la memoria todos los datos de la textura con la que tiene que trabajar en ese momento, al dibujarla, al leerla, al escribir en su bytes. Aunque tengas los tiles en memoria la tarjeta sigue teniendo que seleccionar el tile a dibujar en cada momento y esa accion a la larga tiene un coste de rendimiento para la tarjeta (piensa que la tarjeta grafica trabaja optimamente con bloques de informacion, ya sean texturas o geometria).

Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
Sí, eso sí, pero si la persona que quiere hacer alguna modificación tendrá que crear también el fichero de índices, además de tener que usar ese programa que has puesto arriba para organizar los tilesets y sus tiles.

Pero con ficheros dentro de PAKs/Dirs, simplemente habría que nombrar a los archivos con un nombre cualquiera más un índice, sin necesidad de usar otras herramientas.
El fichero de indices lo genera el editor, el usuario no tiene que hacer nada salvo darle a guardar en el editor una vez haya hecho lo que tenga que hacer. Mas facil y transparente imposible. Tu sistema de paquetes. Si tuvieras que editar la secuencia de animacion seria mas complicado ya que:
1. Tendrias que descomprimir el fichero.
2. Cambiar y renombrar los archivos pertinentes.
3. Volver a empaquetarlo todo para generar el archivo contenedor.
4. Probar si la animacion esta correctamente definida, en caso contrario vuleta al punto 1.

Con el tileset, desde el editor puedo testear la animacion con el mismo codigo que usa el motor ya que se basa en el, puedo editarlo en el momento y volver a probarlo tantas veces como necesite, guardar los cambios y suplantar el archivo de definicion por el nuevo. Esto en .NET con la serializacion a XML todavia mas rapido y mejor.

Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
No es por desmerecer tu opinión, pero si hablamos de juegos modernos, no sé cuál usa tilesets o algún método análogo para almacenar los gráficos.
Un ejemplo rapido, fijate en las texturas de los modelos 3D, ahi tienes un buen ejemplo de algo similar a un tileset. En una sola textura plasman todos los detalles del modelo, cara, brazos, textura de los ojos y dientes, ropa, accesorios y antiguamente hasta la textura de las armas si la llevaban consigo el modelo. Lo mas que vas a encontrar suelto seran texturas de escenarios pero por que generalmente se reutilizan mucho en gran parte de ellos llegando a ser pocas texturas y tantos accesos a ellas como texturas tenga el escenario (distinto a como funcionaria un mapa de tiles por ejemplo).

Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
De hecho, creo que desde Wolfenstein3D hasta hoy en día, el 90% de los juegos, bién sean 3D ó 2D, usan algún sistema de almacenamiento de gráficos como PAKs, ZIPs, directorios o similares.
Si abres dichos paquetes te encontraras que no solo hay texturas, si no todos los recursos del juego: modelos, sonidos, niveles, scripts, etc... El uso de archivos contenedor como PAK o ZIP lo usan, primero por mantener organizados y fuera del alcance del usuario los recursos del juego (esto con formatos porpios sobre todo) y por el sistema de mantenimiento de versiones que te explique mas arriba. Es mas facil actualizar parte de los recursos con un pequeño archivo que actualizar todo un contenedor de 700Mb como le pasaba al Half-Life.


Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
Bueno, claro, pero es que en este caso estamos hablando de modelos 3D que lógicamente es imposible almacenar en tilesets :P
No del todo. La tarjeta grafica no renderiza los modelos por separado si no que agrupa o intenta agrupar toda la geometria posible en bloques para renderizarla. Eso es un cuello de botella que sufre mi libreria ya que mis sprites en vez de usar un sistema para agrupar todos los sprites en bloques los pinto uno a uno por separado lo cual rinde peor a la larga y si le sumas un numero elevado de accesos a distintas texturas pues peor aun (lo que si optimiza la libreria es el tema de los accesos, aunque se pinten independientemente los sprites el render sabe si ha de cambiar o no de textura).

(continua)
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

[EX3]

Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
Y ahí mismo has dicho tu el problema, si alguien quiere, en un motor de XNA, usar un tileset con tiles de 32x32, mezclados con 48x48 o incluso 32x48 o 16x64, ahí ya tendría un problema.
Incluso el propio programador (tú) necesitarías hacerte tus propias rutinas para casos específicos, limitandote a la hora de la "libertad de modificación".
Falso. Si se puede y yo lo estoy haciendo con mi proyecto. Solo uso un unico codigo para la gestion de animaciones, una clase llamada AnimationManager, y con ella puedo manejar tilesets con distintos tamaños de tiles, la unica restriccion es que cada secuencia de animacion tiene que tener todos los tiles del mismo tamaño pero no quita que tengas varias secuencias cada una con el tamaño de tile que sea. El gestor solo debe conocer tamaño del tile, posicion del primer fotograma y numero de fotogramas, el resto es simple, desplazar la posicion a leer tantas veces como fotogramas tenga la secuencia:

Pseudocodigo de una secuencia de animacion en mi motor:
Rectangle TamañoFotograma
Vector PrimerFotograma // XY del primer fotograma
Int NumeroFotogramas


Pseudocodigo de logica de animacion:
Int FotogramaActual
Rectangle AreaFotograma = PrimerFotograma
AreaFotograma.X = PrimerFotograma.Ancho * FotogramaActual

DibujarFotograma(AreaFotograma)

FotogramaActual + 1
Si FotogramaActual > NumeroFotogramas Entonces FotogramaActual = 0

Como ves no tiene mucha miga ;)

En XNA podria reimplementar el mismo sistema que tenia en Visual Basic 6.0 pero no me merece la pena invertir tiempo en hacerlo asi (no me resulta mucho problema el tema de los fotogramas del mismo tamaño en una secuencia) y tampoco tengo tiempo ni ganas de invertirlo en reprogramar el editor cuando con una simple llamada puedo exportar a XML la estructura de la clase con los datos de la secuencia de animacion y con otra llamada volver a importar ese XML. Facil, rapido y productivo.

Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
No me parece mala idea. Aunque tampoc la veo tan buena, ya que tendríamos que cargar en memoria todos los gráficos de juego desde el principio.
Por que? Solo tendrias que cargar como hasta ahora tus graficos que necesites y armarlos en una textura en memoria.

Cita de: Ubermann en 08 de Marzo de 2011, 06:48:05 PM
Para el sistema de índices, podría implementarse un directorio (un fichero de texto) dentro del propio PAK (o incluso fuera de éste) que contenga un listado con el nombre de los carpetas y subcarpetas virtuales del PAK, de manera que crear un sistema de indexación durante el runtime (creo que en español sería "tiempo de ejecución") sólo sería cuestión de interpretar el directorio (el archivo de texto), y nombrar a cada gráfico con el nombre de su carpeta contenedora y un índice que indique su "posición" dentro de la carpeta virtual.
Un archivo de texto con el listado de carpetas y subcarpetas virtuales? Trabajo innecesario. Mirate el tutorial de archivos PAK que viene con dx_lib32, veras que no es necesario, la libreria ya te da una funcion para listar el contenido del paquete.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Ubermann

La virgen santa madre de dios.

Al igual que Hechelion, quoteraría a todo, pero es que me es imposible hacerlo.

En respuesta general a todo: a parte de los "tilesets" de modelos 3D, ningún otro juego del mercado usa tilesets para los gráficos.
Además ya que comentais que los modelos 3D usan tilesets (lo cual ya sabía), es un uso mínimo, ya que las texturas de los modelos suponen una carga mínima en comparación con el uso de las texturas y demás efectos gráficos, así que no tiene sentido decir que los modelos 3D usan tilesets por que así alijeran el framerate.

Por otro lado, no sé si habeis trasteado con juegos más o menos modernos, pero por si acaso no lo sabéis, éstos cargan en memoria TODO DE UNA SOLA VEZ, es decir, no cargan y descargan cosas a medida que se juega, si no que lo hacen al empezar el nivel, y es por eso que algunos tardan bastante en cargar.
Si no fuera así, sólo tardarían unos segundos en empezar, y el framerate sería ínfimo durante la partida.
De hecho, os puedo poner ejemplos reales: he hecho MODs y mapas para Quake 4 y os digo que por muchas texturas sueltas que use, el framerrate del juego se mantiene estable. Sólo baja cuando hay estructuras complejas o saturación de efectos gráficos, pero nunca por la IA ni cosas similares.

También hablais de que los modelos 3D usan tilesets. Y no se hace por que sea más eficiente o más bonito, si no por que es má fácil de usar un tileset para los skins de armas y monstruos que usar varias texturas diferentes.
Sin embargo, la carga CPU/GPU/lo_que_quieras de las texturas de los modelos es ínfima comparada con la carga de cpu/gpu/... del resto de los contenidos del juego.

También tenemos por otro lado la famosa "llamada para buscar" el tile dentro del tileset.
Está claro que para un jueguecillo simple no representa mucho, pero para algo ya más pesado, el tener que realizar no_se_cuantas llamadas para buscar el tile correspondiente puede ser algo considerable, y quizás más que la sobrecarga de la GPU/CPU para abrir y cerrar ese mismo número de texturas sueltas.

Así que por un lado tenemos ficheros sueltos:
Interpretar Mapa->Abrir textura->Colocar textura

y por el otro, tilesets:
Interpretar Mapa->buscar lugar y posición del tile (fichero de índices)->abrir tileset->buscar tile (buscar=ir a coordenadas)->Colocar tile
Y para accesos a posterior, sólo nos saltamos el paso de "abrir tileset"


No sabría decir cuantos ciclos necesitarán cada uno de ellos, pero yo votaría por que el segundo necesita más.


Eso sí, si hablamos de acceso a disco (que es lento), el método de tilesets es mejor que el de ficheros. Cosa que es indiscutible,


Y aún así, para juegos realizados con dx_lib32, no creo que se note ninguna diferencia de frames por segundo de un método al otro (y en absoluto no estoy desmereciendo dx_lib32), pero de usar tilesets a usar ficheros sueltos, me ahorro el tener que diseñar, implementar, y mantener una rutina y programar un editor que es básicamente imprescindible para el manejo adecuado de los tilesets, mientras que con ficheros sueltos, sólo tengo que seguir unas reglas de nomenclatura sencillas, sin ni siquiera tener que usar más herramientas.

Sea como sea, se agradece vuestra oponión.
Quizás experimente algún método que use tilesets y ficheros sueltos.
Así todos contentos xD

Saludos. :-)

Hechelion

#11
Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM

Por otro lado, no sé si habeis trasteado con juegos más o menos modernos, pero por si acaso no lo sabéis, éstos cargan en memoria TODO DE UNA SOLA VEZ, es decir, no cargan y descargan cosas a medida que se juega, si no que lo hacen al empezar el nivel, y es por eso que algunos tardan bastante en cargar.

Ningún juego moderno grande carga TODO su contenido de una sola vez, ahí tiene el ST2 y otros.

Si no quieres usar tileset porque no te gustan o porque no quieres crearte un sistema de coordenadas, es tu decisión y nadie lo discute, lo que se discute es tu afirmación que es menos eficiente.
Tu hiciste un planteamiento y ese planteamiento es falso, es más eficiente usar menos texturas, en contra posición a lo que tu afirmas. Usar menos o más textura pasara por un tema de diseño. La cantidad optima de texturas depende de varios factores, pero tener menos es más eficiente.

Si para ti es mejor usar muchas texturas porque se te hace más simple programas, esta perfecto, es tu motor, pero no digas que lo hiciste porque es la decisión más eficiente, porque como ya se te mostro Ex3, no lo es.

Sin ir más lejos, no hace ni una semana que leí sobre unas recomendaciones para un prueba de trabajo en un empresa de juegos y la recomendación es que usara la menor cantidad de texturas. Si gente que vive de esto, te recomienda eso, es por algo, no por una apreciación al mirar el contenido de otro juego.

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
También hablais de que los modelos 3D usan tilesets. Y no se hace por que sea más eficiente o más bonito, si no por que es má fácil de usar un tileset para los skins de armas y monstruos que usar varias texturas diferentes.
Sin embargo, la carga CPU/GPU/lo_que_quieras de las texturas de los modelos es ínfima comparada con la carga de cpu/gpu/... del resto de los contenidos del juego.
¿Tú sabes lo que es un mapa UV?
Aunque es un concepto completamente diferente, es un sistema de coordenadas para hacer calzar una textura. Fijate que es el mismo principio, una textura con coordenadas. Todo juego 3D lo usa. Así que no es por ser más fácil. EL uso de coordenadas para obtener el mejor resultado es algo que hacen todos los juegos.

Un tileset común y silvestre, es una textura con coordenadas y tampoco es obligación tener un mapa, el mapa solo te añade versatilidad, al igual que un mapa UV te permite adaptar una textura a una malla 3D, puedes usar coordenadas 2D en un tileset para que una única textura se adapte a tu juego.

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
Así que por un lado tenemos ficheros sueltos:
Interpretar Mapa->Abrir textura->Colocar textura

y por el otro, tilesets:
Interpretar Mapa->buscar lugar y posición del tile (fichero de índices)->abrir tileset->buscar tile (buscar=ir a coordenadas)->Colocar tile
Y para accesos a posterior, sólo nos saltamos el paso de "abrir tileset"

Se te ha olvidado el donde colocar la textura. igual necesitas un mapa o código que defina que es cada fichero. Lo que dices de usar nomenclatura e indice en un archivo (Costa01.png, isla03.png, etc) Eso tiene que estar en algún lado, lo que pasa es que como aún no programas nada complejo con ese sistema no te has dado cuenta de la complejidad que vas a necesitar programar  para poder crear mapas complejos.
Cuando lo tengas terminado, compara todo el código para crear un mapa (hablo de un sistema que te permita crear cualquier mapa) y veras que difícilmente será más simple que un motor para usar tile con coordenadas.

Lo que yo veo, es tu miraste y dijiste. Tile necesitan coordenadas y debe ser un cacho programarlas. y partiste de ahí todo el argumento, no critico tu elección (Más o menos texturas depende mucho más de decisión de diseño), pero no la puedes justificar diciendo que el usar coordenadas es menos eficiente o más complicado, porque en ambos casos estás errado y eso es lo que hemos estado comentando.
Todo juego 3D usa coordenadas en las texturas y todo programados, diseñador de texturas te dirá que los más eficiente es tener menos texturas (dentro de lo posible, porque tampoco sería bueno tener todas los diseños de todos los objetos en una única textura).

[EX3]

Primero puntualizar tu error por que veo que sigues sin aclararte:
Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
Eso sí, si hablamos de acceso a disco (que es lento), el método de tilesets es mejor que el de ficheros. Cosa que es indiscutible,
Yo no estoy hablando de accesos a disco duro, ni de cargar archivos ni de descargarlos. Vuelvo a explicar como funciona la GPU por dentro. Tu tienes una zona de memoria donde estan almacenadas la texturas secuencialmente una tras otra que has cargado previamente desde disco y esa memoria no es la memoria RAM si no la memoria de la GPU. Cuando tu le dices a la tarjeta grafica que quieres dibujar una de esas texturas la GPU ha de leer toda la textura de esa memoria y volcarla en un buffer donde trabaja con ella y realiza todas las operaciones que preciese, ya sea lectura o escritura, volcarla en pantalla, aplicarle transformaciones sobre un poligono, etc... ya que solo trabaja con una textura al mismo tiempo. Esa accion de mover la textura de la memoria al buffer es el denominado acceso que llevo post tras post tratando de explicarte y que tu sigues confundiendo con cargar un archivo y descargarlo. Aclarate por que si no es imposible seguir con el razonamiento.

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
En respuesta general a todo: a parte de los "tilesets" de modelos 3D, ningún otro juego del mercado usa tilesets para los gráficos.
Practicamente la totalidad de los juegos 2D y la mayor parte del contenido de texturas de modelos en los juegos 3D lo hacen junto a los graficos que forman las ventanas y demás interfaces visuales de estos. Incluso aplicaciones que no son juegos usan tilesets para iconos y demas graficos comunes, fuentes de texto, animaciones de ciertos elementos como los iconos de la barra de tareas de Windows, cursores animados...

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
Además ya que comentais que los modelos 3D usan tilesets (lo cual ya sabía), es un uso mínimo, ya que las texturas de los modelos suponen una carga mínima en comparación con el uso de las texturas y demás efectos gráficos, así que no tiene sentido decir que los modelos 3D usan tilesets por que así alijeran el framerate.

(...)

También hablais de que los modelos 3D usan tilesets. Y no se hace por que sea más eficiente o más bonito, si no por que es má fácil de usar un tileset para los skins de armas y monstruos que usar varias texturas diferentes.
Sin embargo, la carga CPU/GPU/lo_que_quieras de las texturas de los modelos es ínfima comparada con la carga de cpu/gpu/... del resto de los contenidos del juego.
No se si te has fijado pero hoy dia practicamente los escenarios se forman a base de modelos 3D a modo de piezas para formar paredes, columnas, cierto tipo de estructuras, no como antiguamente a base de mallas sencillas como ocurria en Half-Life por ejemplo. Creeme, si es una carga considerable de texturas (y geometria), ya que no solo son texturas si no mapas de relieve, de reflexion y demas tecnicas que se aplican sobre la textura base (unas 3 o 4 texturas por modelo). Eso es mucha informacion incluso aun viniendo en formatos comprimidos.

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
Por otro lado, no sé si habeis trasteado con juegos más o menos modernos, pero por si acaso no lo sabéis, éstos cargan en memoria TODO DE UNA SOLA VEZ, es decir, no cargan y descargan cosas a medida que se juega, si no que lo hacen al empezar el nivel, y es por eso que algunos tardan bastante en cargar.
Es que yo no estoy hablando de cargar y descargar de memoria (fijate en lo explicado al principio). Yo no estoy hablando de cargar desde disco nada. Por otro lado, nunca se carga todos los recursos de golpe y de hecho hoy dia muchos juegos cargan por sectores los niveles, llegando a un punto en el que se descarga el sector anterior durante la carga del segundo. Vendria a ser como una especie de streaming puntual que tambien se realiza durante la carga de los mismos, esto lo veras cuando empiezas una partida en muchos juegos actuales y los modelos apenas tiene detalles en sus texturas hasta pasados unos segundos (esto al menos en consolas dada su escasa memoria grafica en comparacion con los PC's).

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
De hecho, os puedo poner ejemplos reales: he hecho MODs y mapas para Quake 4 y os digo que por muchas texturas sueltas que use, el framerrate del juego se mantiene estable. Sólo baja cuando hay estructuras complejas o saturación de efectos gráficos, pero nunca por la IA ni cosas similares.
De verdad estas seguro que esos procesos, la IA y las fisicas por ejemplo, no consumen tiempo de ejecucion? Aqui desde luego no sabes de lo que hablas. Las fisicas y la IA son de los procesos mas costosos en un juego. Si alguna vez has usado algun motor de fisicas o te has programado las tuyas propias, por muy sencillas que esta sean, te habras dado cuenta lo que se resiente la ejecucion. La IA, ponte a calcular rutas con el algorritmo de Dijkstra para 100 enemigos mas la logica de sus maquinas de estado en cada ciclo de tu juego y me dices que tasa de fotogramas obtienes. En IA y fisicas es donde, junto a graficos, se ha de optimizar mucho el rendimiento, son de las areas mas criticas de un juego. Sumale los procesos de descarte de geometria que se realizan para acotar lo que la camara ve para no tener que procesar toda la escena al dibujarla mas los algorritmos para descartar la geometria que tienes delante pero que esta a la vista por ciertos obstaculos (un arbol BSP que es lo que usa tu Quake4 para escenarios de interiores o el Octree para escenarios abiertos), esto tambien se aplica en los motores de fisica para optimizar el numero de elementos a evaluar en las colisiones y respuestas de los objetos, y de forma similar se utiliza en juegos 2D con scroll para descartar elementos que no se tengan que dibujar. Todos estos procesos en conjunto requieren muchos recursos del sistema y los fotogramas por segundo no dependen solo de los graficos si no de todo el ciclo completo del juego: logica + graficos.

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
También tenemos por otro lado la famosa "llamada para buscar" el tile dentro del tileset.
Está claro que para un jueguecillo simple no representa mucho, pero para algo ya más pesado, el tener que realizar no_se_cuantas llamadas para buscar el tile correspondiente puede ser algo considerable, y quizás más que la sobrecarga de la GPU/CPU para abrir y cerrar ese mismo número de texturas sueltas.
Tile1(0, 0, 100, 100)
Tile2(100, 0, 100, 100)
Tile3(200, 0, 100, 100)
...
Tile48(300, 200, 100, 100)

tile = ListaTiles(3) -> Leemos la posicion del tile 3.

Donde realizas ahi una busqueda, que no me he enterado? Eso es un acceso directo a un elemento de la lista. En el buffer de la GPU se traduciria a lo siguiente: en el leer desde el primer pixel del tile (X + Y) hasta el ultimo pixel (Ancho * Alto, numero de pixeles del tile), osea, primer pixel (X + Y) + longitud (Ancho * Alto). Ahi no hay ninguna busqueda, solo lectura directa en memoria. El coste es inifimo (una sola llamada en el codigo).

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
Así que por un lado tenemos ficheros sueltos:
Interpretar Mapa->Abrir textura->Colocar textura

y por el otro, tilesets:
Interpretar Mapa->buscar lugar y posición del tile (fichero de índices)->abrir tileset->buscar tile (buscar=ir a coordenadas)->Colocar tile
Y para accesos a posterior, sólo nos saltamos el paso de "abrir tileset"


No sabría decir cuantos ciclos necesitarán cada uno de ellos, pero yo votaría por que el segundo necesita más.
No entiendo tu accion "Abrir textura" o "Abrir tileset" si entiendo que estan en memoria cargados, ni entiendo "fichero de indices" cuando yo uso listas en memoria.

Si por "Abril textura" o "Abrir tileset" te refieres al acceso de la GPU a la textura en concreto tu metodo realiza un acceso (y por acceso me refiero a lo explicado en el principio del post) por cada tile distinto que leas ya que son texturas independientes:
Dibujar Tile1
    MemoriaGrafica[TexturaTile1]->Buffer // Acceso a la textura.
    Volcar Buffer(0,0, longitudBuffer) // Dibujamos la textura entera.
Dibujar Tile2
    MemoriaGrafica[TexturaTile2]->Buffer // Acceso a la textura.
    Volcar Buffer(0,0, longitudBuffer) // Dibujamos la textura entera.
Dibujar Tile3
    MemoriaGrafica[TexturaTile3]->Buffer // Acceso a la textura.
    Volcar Buffer(0,0, longitudBuffer) // Dibujamos la textura entera.
Dibujar Tile4
    MemoriaGrafica[TexturaTile4]->Buffer // Acceso a la textura.
    Volcar Buffer(0,0, longitudBuffer) // Dibujamos la textura entera.
...

El tileset, solo accedes una vez para todos los tiles que tengan su grafico en el tileset.
Dibujar Tile1
    MemoriaGrafica[TexturaTileSet]->Buffer // Acceso a la textura.
    Volcar Buffer(0,0, 100*100) // Dibujamos la seccion 0,0,100,100.
Dibujar Tile2
    Misma textura, no se realiza cambio
    Volcar Buffer(100,0,100*100) // Dibujamos la seccion 100,0,100,100.
Dibujar Tile3
    Misma textura, no se realiza cambio
    Volcar Buffer(200,0,100*100) // Dibujamos la seccion 200,0,100,100.
Dibujar Tile4
    Misma textura, no se realiza cambio
    Volcar Buffer(300,0,100*100) // Dibujamos la seccion 300,0,100,100.
...

Tu metodo sigue obligando a la GPU a mover mas memoria al cambiar la textura a dibujar entre memoria y buffer de trabajo, por lo tanto penaliza mas en rendimiento.

Cita de: Ubermann en 09 de Marzo de 2011, 07:20:27 PM
Y aún así, para juegos realizados con dx_lib32, no creo que se note ninguna diferencia de frames por segundo de un método al otro (y en absoluto no estoy desmereciendo dx_lib32), pero de usar tilesets a usar ficheros sueltos, me ahorro el tener que diseñar, implementar, y mantener una rutina y programar un editor que es básicamente imprescindible para el manejo adecuado de los tilesets, mientras que con ficheros sueltos, sólo tengo que seguir unas reglas de nomenclatura sencillas, sin ni siquiera tener que usar más herramientas.
Vale, haz la prueba y me dices si pintando texturas sueltas consigues mas tasa de fotogramas que usando una sola textura y pintando varias de sus partes. Te explique mas arriba que dx_lib32 tiene un cuello de botella al no agrupar la geometria de los sprites al dibujarlos (recuerda que estan formados por dos poligonos formando un quad, las mismas rutinas que un motor 3D) y eso, al igual que las texturas, a la GPU le cuesta mas procesar bloques separados de geometria que juntarlos todos en uno y procesarlo del tiron. Si sumas este problema al de pintar con texturas sueltas aumentas ese cuello de botella mas si cabe y desaprovechando que la propia dx_lib32 evita el cambio inncesario de texturas (los accesos) si se van a realizar lecturas a la misma textura. Si tu crees conocer mejor que yo como puede afectar mas o menos el rendimiento de la libreria pues tu mismo. Simplemente vas a usar tu sistema por que consideras que te va a ser mas comodo, cosa que me parece bien, pero no lo elijes por que vaya a ser mas eficiente, que es algo que llevo unos cuantos post demostrandote (y unos cuantos años sufriendolo en mis propios desarrollos).




Se me hace tarde estar dia tras dia con estos post tan largos solo para repetir lo mismo una y otra vez sin mucho sentido cuando debería seguir con otras tareas que me urgen y que no estoy llevando al dia (me tiro 3 horas para redactar y razonar estos "ladrillos").

Finalizando la conversacion: si tu juego va a ser pequeño y no va a usar demasiados graficos todo esto que llevamos hablando durante estos dias te dara igual por que tu juego no tendra una carga excesiva contra la GPU y apenas se note en la tasa de fotogramas, pero si tu juego se asemeja en algo a lo que esta haciendo Hechelion o lo que llevo tiempo intentando hacer (similar a los plataformas que te mostre) a lo poco que tengas una cantidad no excesiva de graficos en pantalla ya notaras que bajas facilmente de los 60 fps a 40, junto con el resto de logica, facil que bajes de 30, si no al tiempo, ya lo veras tu mismo.

Sobre el tema de como crees que funcionan los motores como el del Quake4 que ponias de ejemplo o el del Starcraft2 y como piensas que se gestiona la memoria de la GPU no voy a tocar mas el tema. Tienes informacion para aburrir en internet sobre dichas tecnologias, sobre por que se usan tilesets, sobre los tipicos cuellos de botella al trabajar con la GPU (tienes cantidad de articulos sobre optimizacion en graficos) que viene a ser lo que he estado explicando todo este tiempo (que con tanta replica cualquiera diria que tratamos de engañarte por puro placer cuando es todo lo contrario).

Para cualquier duda sobre la libreria, pregunta en nuevo post, pero yo me descuelgo ya de este hilo.
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.