Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Dudas sobre VertexBuffers en Direct3D

Iniciado por [EX3], 30 de Marzo de 2008, 09:06:44 PM

« anterior - próximo »

[EX3]

Continuando este topic en el foro del proyecto de Loover y para no seguir secuestrandolo :) he preferido continuarlo por aqui.

Retomando el hilo a partir de este post.
Cita de: "zupervaca"Si quieres un codigo de ejemplo pasate por aqui: http://www.codeplex.com/dibplus/Release/ProjectReleases.aspx?ReleaseId=610
No digo que sea el mejor codigo del mundo, pero como guia te valdra.
La clase que te interesa esta en System/Drawing/sprite.h
Si le pegas un ojo veras que se crea un vertexbuffer e indexbuffer, este ultimo se inicializa una vez (cuando se crea) y el vertexbuffer se le ponen valores mas o menos coherentes (aunque no haria falta).
Para comenzar el render se llama a la funcion Begin y cuando quieres terminarlo a la End, despues entra la llamada a estas dos funciones tienes funciones que te permiten cambiar el estado de los sprites, estas propias funciones se encarga de pintar todo si es necesario, es decir, si cambia algun estado del render.

Saludos y espero que esto te ayude a mejorar la dx_lib32
Acabo de bajar los fuentes para echarle un vistazo. Gracias por el aporte, Zupervaca :) Seguro que a Loover tambien le vendra de lujo si decide implementar los vb. Aun asi tengo dudas sobre la ordenacion por listas como tengo implementado, imagino que Loover le pasara igual. Separando por jerarquias de Textura, RenderStates y TexturesStates, todo ello entiendo en vb separados. Esto alteraria la ordenacion de cada sprite en cada nivel de Z? Me explico. Suponiendo que tuviera que aplicar las jerarquias o configuraciones mencionadas por cada nivel de Z tendria n vb's segun configuracion. Si yo realizo las siguientes llamadas:

Sprite|Textura|RenderState
------+-------+-----------
A     |Tex1   |Alpha
B     |Tex2   |Color
C     |Tex1   |Color
D     |Tex2   |Inverso
E     |Tex1   |Color

Obtendria los siguientes VertexBuffers en un nivel de Z:
VertexBuffer |Sprites
----------------+-------
Tex1, Color  |C, E
Tex1, Alpha  |A
Tex2, Color  |B
Tex2, Inverso |D

Y tendria de resultado el siguiente orden de dibujo respecto del orden de llamada:
Sprites ordenados por llamada (el deseado): ABCDE
Sprites ordenados por orden de dibujo mediante VertexBuffers: CEABD

Vosotros como arreglais este asunto. Tirais de DephBuffer para aplicar ordenacion por Z o lo solucionais por listas? En caso de hacerlo por listas, como lograis la coherencia de orden de dibujo con la de llamada?

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

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

Loover

O bien eso, o bien activar el zbuffer. Pero... ¿qué sería más rápido? :P

Por cierto [EX3], solo por curiosidad, ¿qué haces para evitar dibujar los objetos fuera de la región de vista?
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

[EX3]

Cita de: "Loover"O bien eso, o bien activar el zbuffer. Pero... ¿qué sería más rápido? :P
Con el zBuffer seria mas rapido pero ya tuve problemas en su dia ya que fue la primera opcion que iba a implementar. Me trastocaba los pixeles de los bordes de las texturas generando un efecto un tanto fastidioso:

Con el zBuffer activado:


Con el zBuffer desactivado:


Por eso me decidi por implementar la lista de llamadas ordenadas.

Cita de: "Loover"Por cierto [EX3], solo por curiosidad, ¿qué haces para evitar dibujar los objetos fuera de la región de vista?
Nada del otro mundo. En verdad solo descarto cuando todos los vertices del sprite estan fuera de pantalla ya que si roto o deformo perspectiva no podria hacer un recorte efectivo de textura (solo podria en dibujados normales sin transformaciones) y dibujar el sprite recortado. Esto es valido si trabajas con sprites pequeños, que suele ser lo normal.

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

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

Loover

En cuanto a los artifacts... ¿activaste el clipping de la textura?
SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

CitarCon el zBuffer seria mas rapido
¿Por qué? Tener el zbuffer activado y hacer ztesting consume bastante más que ordenar una lista de sprites por un valor z (fijo que incluso aunque la ordenaras con un aberrante Bubble Sort :)).

Pero está claro que si tenemos que mandar a la tarjeta todos los vértices en un mismo vertex buffer / array o lo que sea, habrá que activarlo por narices.

Me pregunto si al final, con tanta cosa (transformar vértices, rellenar buffers/arrays pertinentes, activar zbuffer) no irá el asunto igual de velocidad.

Por cierto, el título de este post debería ser más bien "Optimizando render agrupando por material". Por que esto se puede hacer tanto con vertexbuffer como con arrays, depende si luego dibujas con DrawPrimitiveUp o con DrawPrimitive.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

[EX3]

Cita de: "Loover"En cuanto a los artifacts... ¿activaste el clipping de la textura?
SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
Sip, justo antes de setear la textura y llamar a DrawPrimitiveUp(). Lo que no recuerdo exactamente que hacia esto xDDDD Lo que si recuerdo que por entonces, cuando la prueba de zBuffer por hard, no lo tenia implementado (esto creo que lo implemente a raiz de un topic de no hace mas de un año que se abrio)

Cita de: "Loover"Con el zBuffer seria mas rapido
¿Por qué? Tener el zbuffer activado y hacer ztesting consume bastante más que ordenar una lista de sprites por un valor z (fijo que incluso aunque la ordenaras con un aberrante Bubble Sort :)).[/quote]
Siempre sera mas rapido, supongo, a traves de hardware que hacerlo a pelo por software. Quizas me equivoque, no lo se con seguridad :)

Cita de: "Loover"Pero está claro que si tenemos que mandar a la tarjeta todos los vértices en un mismo vertex buffer / array o lo que sea, habrá que activarlo por narices.
En mi caso me temo que no. O existe forma de respetar el orden de dibujo tal y como lo tengo implementado actualmente en dx_lib32 o no hay VertexBuffer que valga, aunque eso me cueste una severa penalizacion en rendimiento :)

Cita de: "Loover"Me pregunto si al final, con tanta cosa (transformar vértices, rellenar buffers/arrays pertinentes, activar zbuffer) no irá el asunto igual de velocidad.
Yo pienso que si. Siempre sera mas rapido enviar 16 llamadas de VertexBuffers a la tarjeta que enviar 1070 llamadas a DrawPrimitiveUp().

Referente a lo que decia en el otro hilo:
Cita de: "[EX3"]Este tema me esta interesando cada vez mas, me temo. Acabo de hacer una prueba de estres con mi libreria dibujando una textura 128x128 cubriendo toda la pantalla (1024x768) y dibujando en todos los niveles de Z (17 en total, de -8 a 8, un total de 1070 sprites) y no pasa de 28fps en la GeForce 3 :(
Vale, 1070 sprites. Lo pienso friamente y yo al menos en el juego que intento desarrollar, a una resolucion de 800x600, la mayoria de los sprites que tendira que dibujar serian de 64x64 y mayores dimensiones (para escenario y demas), y los pocos items que hubiera a 32x32 o 16x16 quizas, pero no han llegado a superar los 200 sprites en pantalla segun recuerdo. Esto me ha llevado hacer unas cuentas pruebas en el PC con la GeForce 3 y estos resultado he obtenido:

800x600
130 sprites de 64x64 - 186 fps
494 sprites de 32x32 - 62 fps

1024x768
221 sprites de 64x64 - 130 fps
825 sprites de 32x32 - 36 fps

Realmente la optimizacion no trata solo de lograr dibujar infinidad de sprites en pantalla (30.000 he leido por ahi) si no de representar en escena lo deseado utilizando los recursos minimos, en este caso cuantos menos sprites mejor. Vosotros considerariais muy deficientes los resultados mostrados o los veriais aceptables? A lo mejor en cifras de cantidad de sprites podria parecer poco, quizas una imagen lo muestre desde otro punto de vista. Esta fue una antigua prueba que hice cuando implemente la ordenacion de dibujo por listas en dx_lib32:



Contabilizando a dedo creo que hay 54 sprites mas o menos en pantalla, transformados y sin transofrmar, y una media de 212fps a pantalla completa a 640x480 (a 800x600 con el mismo numero de sprites, pongamos unos 200 fps quizas?)

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

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

Loover

CitarSiempre sera mas rapido, supongo, a traves de hardware que hacerlo a pelo por software. Quizas me equivoque, no lo se con seguridad.

Pero es que el depth testing es una operación que se hace a nivel de texel, no de sprite, ni siquiera de polígono. Se hace texel a texel, comparando el valor del texel que se va a blitear con el valor almacenado en el zbuffer. Esta es una operación, aún hecha por hardware, infinitamente más costosa que ordenar una lista con 5000, 1 milllón, o lo que tengas de sprites :D. Con el depth buffer activado, irá más lento.

CitarEn mi caso me temo que no. O existe forma de respetar el orden de dibujo tal y como lo tengo implementado actualmente en dx_lib32 o no hay VertexBuffer que valga, aunque eso me cueste una severa penalizacion en rendimiento

Creo que vas a tener que activar el zbuffer por narices, por imagina que tienes 300 sprites que comparte la textura "conejito". Imagina que cada uno de esos 300 sprites tiene un valor z diferente, y que es importante que lo mantengan. Si ahora agrupas por valor z y mandas a dibujar, harías exactamente 300 lamadas a DrawPrimitive/DrawPrimitiveUp, con lo que no ganarías nada. La gracias es que actives el zbuffer, y los renderices TODOS con una sola llamada a DrawPrimitiveUp (está claro que en el buffer deben estar los sprites transformados ya). La pregunta es: ¿iría esto más rápido?

CitarYo pienso que si. Siempre sera mas rapido enviar 16 llamadas de VertexBuffers a la tarjeta que enviar 1070 llamadas a DrawPrimitiveUp().

Creo que aquí estás mezclando conceptos. Lo que nos proponen Ak47 y prompt es indiferente de si usas DrawPrimitive (vertex buffers) o DrawPrimitiveUp (arrays). Con ambos puedes agrupar por material / estado de blending  y mandar a dibujar. Y por las pruebas que he hecho en el test de los tropecientos mil ovnis no hay diferencia entre hacer 5000 llamadas seguidas a DrawPrimitive que 5000 seguidas a DrawPrimitiveUp si la cantidad de polígonos a dibujar en cada llamada es pequeña. Así que mejor usar DrawPrimitive, ya que te permite actualizar los vértices directamente, sin lockear (aunque locke internamente la api).

Quiero hablar un rato sobre la posible implementación del tinglado este, a ver si prompt y ak47 exclarecen un poco las cosas

A mi lo que preocupa de agrupar y mandar a renderizar, aparte del hecho de tener que activar el zbuffer, es el hecho de tener que crear los arrays / buffers. Los factores de agrupación (textura compartida, estado de blending) son valores que pueden cambiar en cualquier momento de la aplicación (en cualquier momento puedo querer que un sprite tenga un tipo de blending diferente, o simplemente se active como "no visible", etc). Así que dichos arrays, deberían crearse a cada frame y rellenarse. Está claro que no podemos crearlos haciendo un new y luego eliminarlos haciendo un delete a cada frame, pues esto es costosísimo... por lo que tendríamos que tener creados unos cuantos arrays (tantos como estados diferentes queramos permitir) y los tamaños de dichos arrays también tendrían que ser dinámicos. Por ejemplo:

Array1 [1024] => Contiene sprites con la textura "conejito", el estado de blending "a".
Array2 [1024] => Contiene sprites con la textura "perro", el estado de blending "b".
Array3 [1024] => Contiene sprites con la textura "corazon", el estado de blending "b".

¿Cúal es la forma de hacer esto? Debo tener un recuento de las texturas que existen en la aplicación en todo momento y asegurarme de que hay un buffer preparado para cada una. ¿Qué pasa si sobrepaso de 1023 sprites en un buffer en concreto? Habría que hacer un nuevo realloc de dicho array, por ejemplo doblar su tamaño, para asegurarnos de no hacer demasiados news... ¿cierto?

Otro problema asociado es: si un sprite cambia de estado de blending, debe cambiar de buffer, por lo que los buffer hay que rellenarlos a cada frame, y esto de por sí, debe ser algo costoso.

¿Es esta la forma correcta de hacerlo? Vaya tinglado :D, tengo que mirar ese código fuente que habeis citado.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Loover

En cuanto a lo que está "bien" o "mal" de fps [EX3], es algo que depende del juego. Te animo a que pruebes el juego "Harvest Massive Encounter". En este juego está claro que lo que le permite renderizar esa brutalidad de sprites a la vez es el hecho de que agrupan por materiales como nos animan a hacer prompt y ak47.

Pero para la mayoría de juegos, en los que no habrá tantos sprites, nuestros engines irían perfectamente sin problemas.

Yo de momento creo que voy a ver exactamente como se tendría que implementar esto, y ya decidiré si lo hago o no, pues con el frustum culling y tal, va bastante bien (a ver si la subo y la probais).
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

zupervaca

Hola,

creo que os estais liando con cosas sin importancia:
- Si quereis probar si el zbuffer consume mucho lo teneis facil, simplemente activarlo con los renders que teneis ahora, vereis que no se nota.
- El tamaño del vertexbuffer optimo ronda los 4000 vertices, aunque depende de la declaracion del vertice que se use, lo optimo es quedarse por los 96KB de tamaño, mas de esto puede generar una perdida de velocidad.
- Cuando el numero de sprites a renderizar supere el vertexbuffer lo que teneis que hacer es forzar el render y volver a comenzar.
- No teneis por que usar esta tecnica siempre, es mas, debe depender del programador el agrupar los sprites, es decir, el programador tiene que pintar todos los ovnis, despues todos los misiles, etc. ya que si vais a pintar un sprite unico en pantalla usar esta tecnica es peor que usar directamente un solo DrawPrimitive ya que gastais cpu para nada.
- Se deben de cachear todos los calculos posibles como matrices de transformacion de proyeccion, etc.
- Tener vuestras propias clases de matrices ya que sera mas rapido llamar al codigo de vuestro juego que al api de direct3dx.
- Las animaciones de un mismo sprite deben estar en una unica textura, si es posible meter incluso varias en la misma
- Con los shaders se puede hacer una tecnica un pelin mas avanzada y es pintar hasta 8 texturas diferentes con un solo vertexbuffer, por desgracia esta idea que tuve hace tiempo no he podido probarla aun, ademas tenemos el problema de que no todas las tarjetas graficas soportan shaders 1_1 ni 8 texturas simultaneas.
- Se me olvidaba: Usar DrawPrimitive ya que bloquear y desbloquear un vertexbuffer es mas rapido que crearlo, bloquearlo y desbloquearlo que es como lo hace DrawPrimitiveUP.
- Usar indexbuffer para calcular menos vertices y solo usar 4 por cada sprite.
- El indexbuffer solo se debe de inicializar una vez ya que no variara nunca.
- Dejar el blending activado no baja la velocidad, ademas la mayoria de las veces usaremos el source y dest mismo para pintar con transparencia. (mientras menos pixels se pinten mas rapido va el render)

Despues de dos años no me acuerdo de muchas mas cosas con las que optimizar, ademas ya no estoy en el mundillo de los juegos asi que puede que todo lo que digo este obsoleto, aunque claramente el test de los conejos sigue tirando de una forma brutal :P

Saludos

Loover

CitarTener vuestras propias clases de matrices ya que sera mas rapido llamar al codigo de vuestro juego que al api de direct3dx.

No estoy de acuerdo. Las funciones de DX de multiplicación de matrices, produtos vectoriales, etc, están muy optimizadas y la gracia que tienen es que aprovechan internamente instrucciones especiales según el procesador, etc.

http://www.toymaker.info/Games/html/direct3d_faq.html#D3D7
Citar
Should I use the D3DX Vectors / Matrix or write my own?

The vector and matrix types that come with Direct3D are highly optimized. There are many functions that can be performed using them, like dot product, cross product etc. which are optimized to run best on the processor. i.e. if your game runs on a Pentium machine these functions will use code optimized by Intel for top speed but if your game runs on an AMD it uses code optimized for that platform. So it would be hard for you to write a vector structure/class and functions that can outperform the D3DX ones. For true black box code you will require your own vectors for calculations outside of the visualization component. A conversion will then need to take place when passing these into the visualization component.

Otra cosa es que si quieres que tu motor corra tanto en ogl como direct3d, lo más normal es que las implementes tu mismo, para usar una única metodología.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

[EX3]

Cita de: "Loover"Creo que vas a tener que activar el zbuffer por narices, por imagina que tienes 300 sprites que comparte la textura "conejito". Imagina que cada uno de esos 300 sprites tiene un valor z diferente, y que es importante que lo mantengan. Si ahora agrupas por valor z y mandas a dibujar, harías exactamente 300 lamadas a DrawPrimitive/DrawPrimitiveUp, con lo que no ganarías nada. La gracias es que actives el zbuffer, y los renderices TODOS con una sola llamada a DrawPrimitiveUp (está claro que en el buffer deben estar los sprites transformados ya). La pregunta es: ¿iría esto más rápido?
Mas rapido no lo se con seguridad, yo desde mi punto de vista sigo pensando que sera mas rapido el zbuffer que el codigo de Visual Basic 6.0  en que esta programado dx_lib32 :P Y sobre lo de activar el zBuffer, en su momento no logre solucionar el asunto de que no respeta las transparencias, a ningun nivel de alpha que tenga la textura, por lo que no me sirve (no encuentro el post en el foro, pero recuerdo que me dieron varias soluciones y ninguna funciono correctamente o no supe implementarla bien, que tambien es posible)

Cita de: "Loover"Creo que aquí estás mezclando conceptos. Lo que nos proponen Ak47 y prompt es indiferente de si usas DrawPrimitive (vertex buffers) o DrawPrimitiveUp (arrays). Con ambos puedes agrupar por material / estado de blending  y mandar a dibujar.
Vale, entonces llamemoslo "buffer", un buffer donde meter toda la geometria de un grupo de sprites con estados y texturas comunes :)

Cita de: "Loover"En cuanto a lo que está "bien" o "mal" de fps [EX3], es algo que depende del juego. Te animo a que pruebes el juego "Harvest Massive Encounter". En este juego está claro que lo que le permite renderizar esa brutalidad de sprites a la vez es el hecho de que agrupan por materiales como nos animan a hacer prompt y ak47.

Pero para la mayoría de juegos, en los que no habrá tantos sprites, nuestros engines irían perfectamente sin problemas.
Para mi juego al menos esta dando la talla sin problemas (un plataformas a lo flashback), quizas para un Age of Empire o similar... pues no meteria la mano en el fuego :P

Cita de: "zupervaca"- Las animaciones de un mismo sprite deben estar en una unica textura, si es posible meter incluso varias en la misma
Esto lo estoy poniendo en practica en la implementacion sobre .NET que utiliza mi libreria, digamos que obligo a la clase de animacion a usar una sola textura para almacenar la animacion y como mucho, si se diese el caso, tener la opcion de cambiar la textura por si se tuviesen las animaciones separadas en un par de texturas. Esto ya comprobe que era mas rapido que usar una textura individual por frame.

Cita de: "zupervaca"- Se deben de cachear todos los calculos posibles como matrices de transformacion de proyeccion, etc.
Esto no me ha quedado claro del todo. Cachear los calculos. Te refieres a calcular operaciones comunes y almacenarlas para evitar recalcularlas en cada pasada?

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

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

zupervaca

EX3 a lo que me refiero es con cachear calculos es a mas que nada las matrices de transformacion y proyeccion, cada vez que quieras pintar un sprite tendras que indicar las coordenadas de los vertices ya transformadas.

Loover lo de las matrices no lo digo por decir, me baso en pruebas que realice con un sobremesa y dos portatiles diferentes, nunca se debe de dar por sentado algo que leas en una pagina web, lo mejor es comprobarlo por uno mismo.

Loover

CitarLoover lo de las matrices no lo digo por decir, me baso en pruebas que realice con un sobremesa y dos portatiles diferentes, nunca se debe de dar por sentado algo que leas en una pagina web, lo mejor es comprobarlo por uno mismo.

Siempre es lo mejor probarlo uno mismo, yo también lo hice. Tengo un set de funciones matriciales propio que hice para un render por software para una práctica de la uni (hay es donde aprendí también a como implementar un depth buffer por software, con lo que estoy convencidísimo que ordenar con un Quick Sort tu lista de sprites por z va a ser a la fuerza más rápido que utilizar z-testing). Y durante un tiempo estuve utilizando dicho set. También probé diferentes implemetanciones de matrices, vectores, etc que encontré en Krugle. Aparte de que ya se habló de esto anteriormente en un post en el que pregunté especificamente esto. Te he puesto ese link, por ponerte uno, pero es algo de lo que podrás encontrar información en muchos lados. Finalmente volví a las de DX.

Reitero lo dicho, las funciones de producto vectorial, escalar, transformaciones, multiplicaciones, etc, están implementadas en dx aprovechando las posibilidades de instrucciones de cada procesador, por lo que es muy dificil que las tuyas vayan a ir más rápido (tendrías que hacerlo como ellos, aprovechando dichas instrucciones, ensamblador, etc). Hay ciertas cosas que irán a la misma velocidad, como crear una matriz de traslación, rotación o escalado, pues es simplemente introducir unos valores en la matriz, pero muchas otras operaciones no.

Otro link:
http://www.devmaster.net/forums/showthread.php?t=6611
These math libraries can be faster, because D3DX is hardly optimized. In particular by using the SSE instrution set one can do vector math a whole lot faster on modern CPUs. Just to illustrate this: Optimizing the Rendering Pipeline of Animated Models Using the Intel Streaming SIMD Extensions.

No pongo en duda para nada que fuera más rápido en las pruebas que tu hiciste, pero estoy convencido de que se debió a otros factores y no al hecho de implementar tu mismo un set de funciones matemáticas en vez de usar las de DX. De todos modos, si las tienes a mano, me gustaría echarles un vistazo.

Por cierto, no sé si te lo comenté ya, pero no me funciona el ejemplo "rabbits" en Direct3d, el log me pone "No se pudo crear el render". En OGL, a 800x600 y desactivando el vsync (edité el fichero xml) me da 20 fsp con unos 2000 sprites. El test del engine HGE, que es de donde creo que has sacado el sprite, me da unos 40fps, y eso que escalan sus conejos a mayor tamaño, pero vamos, para probarlo bien, habría que hacerlo exactamente con los mismos tamaños, etc. ¿Has usado lo de una única llamada para dibujar todo? Tengo que hacer yo también un test parecido a ver cuántos fps me da.

Citar- Se me olvidaba: Usar DrawPrimitive ya que bloquear y desbloquear un vertexbuffer es mas rapido que crearlo, bloquearlo y desbloquearlo que es como lo hace DrawPrimitiveUP.

Esta, como he comentado, también la probé en el test de los ovnis, y daba   lo mismo en dicho test. Esto se debe a que para menos de x (no recuerdo cuanto) vértices da exactamente igual, por lo que como mandaba solo de 4 en 4 vértices daba igual. He leído mucho estos días sobre la eterna discusión entre usar DrawPrimitive versus DrawPrimitveUp y las cosas no están blancas o negras, lo cierto es que dependiendo de para que vayas usarlos, es perfectamente válido usar DrawPrimitiveUp, todo es tener claro como funcionan internamente. Un DrawPrimitiveUp solo tiene memcopy adicional por lo que si son pocos vértices, ni se nota. Como también comenté los del Harvest usan DrawPrimitiveUp para TODO, y nunca he visto un juego a tanta resolución con tantos sprites en pantalla a la vez.

Lo que no entiendo es porque me iba 1 o 2 fps más rápido el DrawPrimitiveUp en el test de los ovnis. Debería ser al revés :S

Citar- Con los shaders se puede hacer una tecnica un pelin mas avanzada y es pintar hasta 8 texturas diferentes con un solo vertexbuffer, por desgracia esta idea que tuve hace tiempo no he podido probarla aun, ademas tenemos el problema de que no todas las tarjetas graficas soportan shaders 1_1 ni 8 texturas simultaneas.
- Dejar el blending activado no baja la velocidad [...]

No tenía ni idea de estas dos, gracias por el aporte. Yo creía que desactivar el alpha blending ayudaba. De hecho en LooverLib doy la posibilidad de usar LOV_OPAQUE o LOV_ALPHA (aparte de LOV_SPRITE que es el más rápido pues usa descarte de texel) justo para eso. Luego haré una prueba por gusto. [Edit] Ya lo he probado y es cierto, me ha sorprendido bastante. Pero aún hay más, usando descarte de texel tampoco va más rápido, si acaso solo 2 o 3 fps más. Por lo que creo que voy a dejar de diferenciar entre modos. Vaya sorpresa.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Loover

Lo que comentais de que se gana mucho teniendo las animaciones en una única textura, está claro que es cierto. De hecho, un motor hiperoptimizado, podría hacerse creando texturas de un tamaño óptimo (¿quizás el máximo permitido por la tarjeta?) e ir empaquetando todos los recursos gráficos en ellas (a la manera de los lightmaps).

Para sprites mayores que el máximo de textura permitido por la tarjeta, habría que cortar en bloques (es lo que hago yo actualmente).

Pero eso sería bastante tela de implementar :), aparte de que habría que tener en cuenta factores como que al eleminar cierto sprite, quedaría huecos y habría que reaprovecharlos si luego creamos otro, etc. Aparte que los tiempos de carga serían mayores, pues habría que copiar las texturas, etc.

Pero vamos, eso, junto con el instancing y un buen culling... peazo de optimización :D
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

[EX3]

Cita de: "zupervaca"EX3 a lo que me refiero es con cachear calculos es a mas que nada las matrices de transformacion y proyeccion, cada vez que quieras pintar un sprite tendras que indicar las coordenadas de los vertices ya transformadas
Disculpamente, no se si sera el sueño o que es Lunes pero no lo entiendo bien :D Malentiendo que te refieres a que mantenga matrices ya calculadas si no se ha de modificar la transformacion del sprite, por ejemplo un sprite estatico que no varia sus caracteristicas ni posicion. Es esto o voy mal encaminado? :)

Cita de: "Loover"Lo que comentais de que se gana mucho teniendo las animaciones en una única textura, está claro que es cierto. De hecho, un motor hiperoptimizado, podría hacerse creando texturas de un tamaño óptimo (¿quizás el máximo permitido por la tarjeta?) e ir empaquetando todos los recursos gráficos en ellas (a la manera de los lightmaps).

Para sprites mayores que el máximo de textura permitido por la tarjeta, habría que cortar en bloques (es lo que hago yo actualmente).

Pero eso sería bastante tela de implementar :), aparte de que habría que tener en cuenta factores como que al eleminar cierto sprite, quedaría huecos y habría que reaprovecharlos si luego creamos otro, etc. Aparte que los tiempos de carga serían mayores, pues habría que copiar las texturas, etc.

Pero vamos, eso, junto con el instancing y un buen culling... peazo de optimización :D
Recordar que "semos" amateurs, señores, al menos la mayoria, no pretendamos optimizar como el Unreal Engine 3 :D Yo sinceramente me conformo con poder hacer mi juego un dia de estos, pero no pretendo que corra en un Pentium II ni similar ;) (y si necesitase hacer autenticas burradas y tirar de shaders meteria mano directamente a XNA o alguna libreria ya hecha en vez de implementarmelo yo mismo).

Si el asunto del zBuffer hay forma de solucionar ese problema de transparencias que muestro en mi captura no tendria problema alguno en reescribir el render usando "buffers" para agrupar por textura y estados (de hecho seria una implementacion mas facil y sencilla que la actual) pero si he de hacerlo sin zBuffer y no puedo mantener el orden Z de dibujado de forma coherente (y esto incluiria el texto, que no lo podria englobar con la geometria... cosa que ahora si hago) seguire como estoy. Voy a buscar de nuevo info sobre el asunto de usar zBuffer en 2D pero si alguno conoce algun tuto o articulo de antemano bienvenido sea :)

Salu2...
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.