Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Buffers De Vértices E Índices

Iniciado por Helius, 12 de Febrero de 2004, 04:11:47 PM

« anterior - próximo »

Helius

 Hola,

Estoy con un motor que importa los polígonos del max y los ordena en un octree. Ahora bien, para minimizar las llamadas a DrawPrimitive tengo ordenados los triángulos por textura dentro de cada nodo del octree.
La pregunta es: ¿cómo contruyo los búfers de vértices o de índices?

Es decir, ¿creo un sólo búfer y lo relleno cada frame con los vértices que se van a pintar? (podría crear un sólo búfer con todos los triángulos que se van a pintar (de todos los nodos que se ven) y ordenado linealmente por textura, así a la hora de pintar recorrería el bufer textura por textura pintando todos los tris desde el comienzo del búfer hasta el final)

¿o por el contraio me creo un búfer para cada nodo (en tiempo de carga, no mientras renderizas) para almacenar los triangulos ordenados por textura?? (en este caso si el octree tiene muchos nodos llegaría a tener tantos búfers como nodos, pero no habría que estar generando búfers ni ordenarlos en cada frame...)

ein?
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

AgeR

 Yo también estoy pensando en la mejor forma de almacenar los vértices de un octree, y bueno, no me he puesto aún, pero allá va lo que se me ocurre así de primeras.

Yo guardaría en un mismo vertex buffer todos vértices/triángulos del modelo, ordenándolos por nodos del octree. No sé si me explico... la idea es usar un sólo vertex buffer estático para el modelo. En cada nodo del octree, además de ir añadiendo polys al vertex buffer, se guarda un índice y la cantidad de polys del nodo. El índice indica la posicion donde empiezan los polys del nodo dentro del VB... Para dibujar el nodo símplemente habría que llamar a la función DrawPrimitive, indicándole la posición desde la cual quieres dibujar y la cantidad de polys.

De todas formas no sé cómo está el tema de la rapidez, sobre todo por el cambio de texturas. Igual combiene generrar un VB Dinámico y rellenarlo cada vez ordenado por texturas.

Otra opción que se me ocurre es crear otro índice y ordenar las partes a dibujar por textura  e ir haciendo DrawPrimitives, cambiando lo menos posible de textura.

:huh: Acabo de ver que lo que pretendes es precisamente minimizar las llamadas a DrawPrimitive XDDDD
En ese caso, lo obvio sería hacer el VB Dinámico.

Por otra parte yo actualmente uso un VB estático para cada modelo en mi motor, y no va nada mal, incluso con más de 50k polys en pantalla me rula perfectamente.

En fín, seguro que te he liado más de lo que estabas, así que a ver si se pasan haddd, berserker y compañía por aquí, que son los expertos  :rolleyes:

Saludos!

Miki

Bien Helius, es el cuento de nunca acabar.
Yo solo te voy a dar un par de consejos y un par de pistas:
- A DX no le mola k uses vertex buffers dinámicos
- A DX no le mola k hagas muchas DrawPrimitives()
- A DX no le mola k hagas muchas SetStreamResource()  --->para asociar un vertex buffer
- A DX no le mola k hagas muchas SetTexture()

¿joder, entonces k coño le mola a DX?

Hay algo k no le fastidia mucho a DX, y esas son las llamadas a SetIndices()

Ya para terminar, puedes alojar un index buffer en GPU o en CPU xq la diferencia de rendimiento tan solo
puede suponer unas 2-3 fps.

Bien, con esto ya te lo he dixo todo. Espero haberte iluminado :-P

En serio, no pienses cosas raras xq esas restricciones son lo único k te ayudarán en tu viaje por D3D XD

Salu2

Helius

 Esas restricciones las conocía, de ahí mi quebradero de cabeza para intentar minimizarlas.
Otra cosa: me estoy refiriendo a un octree para terreno, en este caso es bastante grande (medio millon de polis)

Es cierto que a DX no le gustan los buffers dinamicos pero siempre será mejor un buffer dinamico creado de una pasada que tener que estar cambiando entre muchos buffers de vertices y a su vez cambiar de texturas otro mogollon de veces no??

bueno, lo que realmente me interesa es la manera óptima de organizar el octree para manejarse con los buffer de vertices/indices, a ver si alguien tiene más sugerencias  :D  
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Zaelsius

 Yo creo que deberías hacer cuentas y usar la opción que minimizase el uso del bus AGP. Si utilizas VB dinámicos, estarás constantemente enviando datos por el bus, lo que requiere tiempo.

Si utilizas un VB para cada nodo y sólamente lo utilizas una vez por frame, hay bastantes posibilidades de que no aguanten todos mucho tiempo en memoria de GPU, pero seguramente sea más óptimo que la otra manera ya que las tarjetas actuales van bien servidas de memoria.

El cambio de textura es algo parecido, antes cuando habia muy poca memoria de video el cambiar de textura podia implicar borrar texturas anteriores de la GPU para subir una nueva por el bus. Si habia poca memoria y este cambio era constante, el rendimiento decaía rápidamente.

Bueno este es mi punto de vista, aunque realmente no he experimentado demasiado con estas cosas.  ;)  

Helius

 Otra idea es crear un único búfer de vértices, y crear un array de índices por cada nodo (que indica los triangulos en cada nodo).
Al pintar la escena veo los nodos visibles y hago lo siguiente: voy añadiendo en un único index búfer dinámico los índices de los triángulos de los nodos que se vean, previamente ordenados por textura. Después de esto me quedará un index buffer relleno con los tris que se ven y ordenado por textura. Sólo queda pintar ese index buffer zona a zona (textura a textura). De esta manera minimizo las llamadas a DrawPrimitve (y el cambio de texturas) que serían tantas como texturas diferentes se vean en la escena actual

Aunque no creo que sea bueno tener un único bufer de vértices tan grande verdad? (grande me refiero a cientos de miles de vértices)


El problema de crear varios búfers de vértices por nodo (aunque esten ordenados por textura) es que habría demasiados DrawPrimitive's, que sería igual a: texturas_en_cada_nodo * número_de_nodos_visibles  no??

uff me voy a volver loco  :blink:  
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Zaelsius

 El problema de un VB gigante es que si toca mandarlo por el bus muchas veces.. :-/. Siempre puedes utilizar una solución intermedia, usando un VB para cada p.ej. 4 nodos. En fin, todo es probar y depende de muchos factores.

Miki

Como bien decía mi colega, todo depende, depende de muchos factores.
En primer lugar ya te aviso de que no vas a poder meter más de 65.535 vertices en un VB en GPU (las tarjetas CARAS soportan más). Así k en tu caso lo mejor es, usando un octree, tirar de 8 VB, uno para cada nodo maestro del octree (se crean 8 nodos en la primera subdivisión del nodo madre). Y la otra cosa k tienes k hacer es lo k´tú ya has dixo, un array de punteros a IB en cada nodo del octree, donde el array es tan grande como número de materiales (texturas) tienes en el escenario. Luego con dos FOR's es fácil abarcar el problema:

Citar
PARA CADA material(x) HACER
      SetMaterial(x)
      SetTexture(x)
      PARA CADA nodo_visto_en_X_material(x, y) HACER
           // Donde 'y' es el nodo en cuestión y 'x' es el indexbuffer del array de buffers del nodo
           SetIndices(x)
   DrawPrimitive()
      ACABA
ACABA

De esta forma no tienes k ir modificando un IB dinámico (cosa k tardaría más k hacer muchos SetIndices() ). Nosotros lo hacemos así en RET FX y da un resultado muy bueno.
Salu2






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.