Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Me Va A Volver Loco El Id3dxsprite

Iniciado por KACHORRO, 23 de Octubre de 2005, 12:39:33 PM

« anterior - próximo »

Ray

 pequeño (gran) error que cometí en el ejemplo de DrawPrimitive, asumí que el ultimo parámetro indicaba el número de vertices pero en realidad lo que hay que poner es el número de primitivas y como son 2 triangulos necesarios para dibujar el QUAD el valor es 2, no 4.

lpDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, n*4, 2);

El 1º párametro indica la forma en que se dibujan los triángulos, y el 2º la posición del primer vertice del sprite en la lista que hemos establecido en SetStreamSource.

QUOTE (Lord Trancos 2)

Creo q si ordena él ganaria rendimiento, pero si desactiva el z-buffer eso podria provocar que aumentará el overdraw, ¿no?
[/quote]
Cierto, no siempre interesa desactivar el z-buffer. Si se dibujan cientos de objetos pequeños va a ser más rápido y sencillo usar z-buffer que clasificarlos uno mismo.

Si se dibujan muchos objetos unos detras de otros como los arboles de una carretera o una serie de muros mejor ordenarlos de atras hacia delante y dibujar usando z-buffer, todo lo que tapen los primeros objetos no lo tendra que dibujar la tarjeta en los pixels de los dibujos restantes que pueden ser millones de calculos entre texturas, luces, efectos, niebla, etc.

Tambien se puede comprobar el test pero desactivar la escritura, para dibujar cristales, humo, luces, y otros efectos traslúcidos, siendo esto lo último que se dibuje.

lpDevice->SetRenderState( D3DRS_ZWRITEENABLE,  FALSE);

a veces puede interesar hacer que el test siempre pase y que tape a dibujos posteriores, por ejemplo para un simulador de avión mejor dibujar primero la cabina y luego la escena, ahorrando a la tarjeta el trabajo de tener comprobar el test de la cabina y de calcular el color de todos los pixels que esten ocultos por ella.

lpDevice->SetRenderState( D3DRS_ZFUNC,  D3DCMP_ALWAYS); // dibuja siempre
DibujarCabina();
lpDevice->SetRenderState( D3DRS_ZFUNC,  D3DCMP_LESS); // dibuja si está mas cerca
DibujarEscenario();

yo creo que lo mejor en el caso de cachorro es desactivar el z-buffer para el fondo (dibujandolo primero) si la pantalla tiene 800x600 se va a ahorrar 480000 comprobaciones, y lo dejaría activado para el resto y así evitar el coñazo de tener que ordenar constantemente, con darles una coordenada z es suficiente, además lo que pierdes al realizar la comprobación luego lo ganas al ahorrar el cálculo de los pixels de los objetos que queden ocultos, de hecho ganaría en velocidad si ordenase los sprites de atras a adelante con el z-buffer activado.

KACHORRO

 He estado mirando lo del zbuffer...

Y es cierto, estando desactivado me va mas rapido.

El orden de dibujado lo hago yo a mano. Pero me es irrelevante ahora mismo, porque me sobra CPU de lejos para lo que hago, asi que hacerlo por el zbuffer no me va a acelerar nada, o quizá me lo reduzca.

Lo que he comprobado es que con direct3d da igual el ordenador que tengas ya que todo (o casi) depende de la tarjeta gráfica.

Así que ahora mismo, que me sobra CPU para el programa en si, da igual que optimice mi codigo de juego... tengo que optmizar, por kinders, el codigo de renderizado de d3d si quiero mejorar la velocidad.


[EX3]

 
Cita de: "KACHORRO"El orden de dibujado lo hago yo a mano. Pero me es irrelevante ahora mismo, porque me sobra CPU de lejos para lo que hago, asi que hacerlo por el zbuffer no me va a acelerar nada, o quizá me lo reduzca.
...
Lo que he comprobado es que con direct3d da igual el ordenador que tengas ya que todo (o casi) depende de la tarjeta gráfica.
Quizas en tu maquina si, pero has pensado en la de los usuarios finales, gente que trabaje con cacharros un poco bajos en rendimiento por tener una grafica baja, etc... y si estas ordenando a mano si que tendras que optimizar, por que eso si que depende de la CPU y no de la grafica.

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

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

KACHORRO

 Tienes razón. Pero ahora mismo mi problema es... en un ordenador potente (en el que sobra CPU para calculo de juego) da igual lo potente que sea, porque con una tarjeta grafica mala, el juego irá lento.

Es decir, hay que optimizar para que en las tarjetas malas, vaya rapido.

Después ya veré si mi codigo es necesario optimizarlo para ordenadores malos.

no sé si me explico  :P  

zupervaca

 hola si vas a ordenarlos tu a mano lo mejor es que uses la funcion qsort de c estandard, esta muy optimizada a parte que es de los mejores sistemas de ordenacion

KACHORRO

 Pues anda que si te digo que ahora mismo estoy utilizando... BURBUJA !!!!

jajajajaja

y me sobra tiempo de CPU

por eso me fastidia que ahora sea la GPU la que me limite la velocidad del engine, y es por eso que tengo que optimizar Direct3D hasta que reviente.

:-)

TheAzazel

 Kachorro, no estaras "desobedeciendo" la primera ley universal en programacion eh?

Veras, se trata de terminar TODO antes de ponerse a optimizar NADA. Es algo que mas o menos hemos aprendido todos a base de perder tiempo y tiempo y volver a deshacer lo ya hecho y vuelta a empezar.

A mi me parece que si utilizas D3D para pintar sprites 2D...eso te deberia de ir suficientemente bien como para perder tiempo optimizando nada...yo terminaria el juego y despues, lo vas probando en distintos equipos/tarjetas... que cumple con los minimos pues ni tocarlo mas(a no ser que te gusta la optimizacion) que no cumple? pues probar con opengl o ya te rompes la sesera intentando buscar un ruta mejor...

Por un benchmark que hicimos hace un tiempo donde comparabamos SDL,directdraw,opengl y direct3d...me cuesta creer que d3d te vaya a ser un cuello de botella.... a no ser que quieras que funcione en una Voodoo1 jeje que seguro hasta va bien y todo :P

Ray

 Tienes razón de optimizar al final, pero yo hay dos cosas que intentaría fijarlas al principio, que son el tamaño de los buffers de vertices y de las texturas.

intenta meter los sprites agrupados en texturas grandes, crear una textura independiente para cada uno es una locura. Al menos todos los objetos pequeños como botellas, velas, libros, etc. los metería en una única textura.

¿Que tamaño de sprite estás usando para las pruebas? porque para muchos sprites pequeños tienes que optimizar los vertices y para sprites grandes los pixels.

saludos.



KACHORRO

 
CitarVeras, se trata de terminar TODO antes de ponerse a optimizar NADA.

Veamos... yo tenia mi engine funcionando a las mil maravillas en DirectDraw, me daba potencia de sobra en un Pentium 2. Pero la necesidad de tener alpha blending y algunas cosas más via hardware me forzaron a migrar. Y he migrado a direct3d, con la promesa de que "tu tarjeta acelera todo como si fuera 3d" y me encuentro que rinde menos que el directdraw... entonces , no se trata de terminar o no, se trata de seguir trabajando con direct3d a sabiendas de que va a rendir como yo quiero. No tiene sentido terminar todo para luego tener que quitar direct3d y poner otra cosa. Es por eso que necesito saber qué me puede dar ahora, para cambiar si es necesario.

Citar¿Que tamaño de sprite estás usando para las pruebas? porque para muchos sprites pequeños tienes que optimizar los vertices y para sprites grandes los pixels.

Un ejemplo simple... un bitmap de 1024x768, sólo eso, me da un resultado de 170 frames/segundo en un pentium 4 1.700 con una geforce4 mx 440

A mi se me antoja poco...  

TheAzazel

 Mira esto:

http://www.stratos-ad.com/forums/index.php...=ST&f=43&t=5237

para que vas pruebas de rendimiento con muchos sprites....

asi te dara una idea del rendimiento que deberias obtener tu con D3D.

[EX3]

 
Cita de: "KACHORRO"Un ejemplo simple... un bitmap de 1024x768
Un consejo, para evitar problemas de escalas en los diferentes sprites que se almacenan en la textura, esto a la hora de decirle a D3D que sector de la textura en memoria quieres renderizar, que si la textura tiene un tamaño no potencia 2 te lo convierte a potencia 2 modificando su tamaño en memoria. Utiliza mejor texturas de tamaño de potencia 2, en este caso, 1024x1024, que de por si te recomiendo que sea el tamaño maximo que utilices, ya que algunas graficas no soportan mas de esto, incluso algunas no pasan de 512x512 pero ya es raro (y las vodoo no pasan de 256x256, pero esto si que no merece atencion a dia de hoy :P)

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

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

KACHORRO

 Lo hago tal como dices.
Lo de la textura a 1024 solo lo he usado como referencia de rendimiento.

Por cierto... el comando GetMemTeture o algo asi (no recuerdo ahora la nomenclatura exacta) que devuelve la memoria para texturas disponible en que unidad lo hace ? en bytes ?

Ray

 
Cita de: "KACHORRO"Un ejemplo simple... un bitmap de 1024x768, sólo eso, me da un resultado de 170 frames/segundo en un pentium 4 1.700 con una geforce4 mx 440

A mi se me antoja poco...
Un bitmap de 1024x768 parece pero no es tan simple, son casi 80000 pixels que la tarjeta tiene que procesar y pintar uno a uno.

Si lo que quieres es trasladar a la pantalla cantidades grandes de pixels como el caso del fondo del juego quizás deberías probar a crear surfaces igual que hacías en DDraw, solo que el método ahora se llama CreateOffscreenPlainSurface. Después usas UpdateSurface, que es parecido al Blt de DDraw para copiar todo o parte de la surface al backbuffer. Debes crearla con D3DPOOL_SYSTEMMEM.

Para obtener el backbuffer debes usar GetBackBuffer y para obtener la información de la surface si te hace falta hay que usar GetDesc. Todos son métodos de IDirect3ddevice9 incluidos el UpdateSurface, excepto el GetDesc que es un método de la surface para obtener su información.

Por otro lado... Según dijiste anteriormente usabas la librería D3DX, y para cargar las texturas 3DXCreateTextureFromFile. Puedes también usar D3DXLoadSurfaceFromFile y copiarlas a la pantalla con D3DXLoadSurfaceFromSurface, tiene opción para añadir color key, por lo que puedes usarlo incluso para los sprites que no usen otros efectos, aunque desconozco su rendimiento y sus posibles problemas.

Y del resto no te preocupes por usar texturas, si dibujas sprites grandes (que son las más lentos) tendrás que dibujar pocos porque no caben tantos en pantalla y si dibujas muchos tendrán que ser pequeños por lo que irán rápidos y tampoco tendrás problema.

Y si sigue sin funcionar les decimos a microchof, que inventen el DirectK, (la K de kachorro) pero eso tiene que irte rápido por cojones.

(GetAvailableTextureMem(), en bytes me parece).

KACHORRO

 
CitarY si sigue sin funcionar les decimos a microchof, que inventen el DirectK, (la K de kachorro) pero eso tiene que irte rápido por cojones.

:P

Vale... lo de las surfaces ya lo pensé, pero no habia tenido tiempo de probarlo. Creo que tenian la restriccion  de que la surface origen fuera igual a la destino... no sé, lo miraré.

Gracias por el resto de consejos. :)

[EX3]

 
Cita de: "Ray"Si lo que quieres es trasladar a la pantalla cantidades grandes de pixels como el caso del fondo del juego quizás deberías probar a crear surfaces igual que hacías en DDraw, solo que el método ahora se llama CreateOffscreenPlainSurface. Después usas UpdateSurface, que es parecido al Blt de DDraw para copiar todo o parte de la surface al backbuffer. Debes crearla con D3DPOOL_SYSTEMMEM.
Ya quisiera yo poder hacer esto en D3D8 :( No es nada optimo renderizar surfaces en D3D8 por que tienes que hacer muchos locks/unlocks y eso es pesadisimo para la tarjeta, parece que en D3D9 se han puesto las pilas con el tema (buen futuro me veo cuando porte la dx_lib32 a VB.NET :D)

Cita de: "Ray"Por otro lado... Según dijiste anteriormente usabas la librería D3DX, y para cargar las texturas 3DXCreateTextureFromFile. Puedes también usar D3DXLoadSurfaceFromFile y copiarlas a la pantalla con D3DXLoadSurfaceFromSurface, tiene opción para añadir color key, por lo que puedes usarlo incluso para los sprites que no usen otros efectos, aunque desconozco su rendimiento y sus posibles problemas.
Esto no se como sera en D3D9 pero en D3D8 D3DXLoadSurfaceFromSurface() no es muy rapida que digamos y al menos en D3D8 el parametro ColorKey se lo pasa por el forro :-/ Yo ultilizo esta funcion en mi libreria solo para operaciones puntuales de pasar surfaces a texturas y viceversa, pero para poco mas.

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.