Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





VertexBuffer DirectX

Iniciado por Manu343726, 28 de Mayo de 2012, 11:24:10 AM

« anterior - próximo »

Manu343726

Buenas.
Estoy desarrollando un pequeño motor grafico con directx en c++, y tengo una dudilla sobre el uso de los vertexbuffer
La idea es hacer el motor totalmente orientado a objetos, así que había pensado gestionar la escena como un conjunto de poliedros, cada uno con sus propios vertices, de manera que cada poliedro es dibujado mediante su propio vertexuffer.

Por los ejemplos que he visto en el sdk de 2010, la mecanica siempre es crear el vertexbuffer, seleccionarlo, y dibujarlo.
Lo que no se es si el pipeline de DirectX está diseñada para andar cambiando de vertexbuufer todo el rato.
Es ésta la manera de hacerlo?

Gracias


XÑA

Todo lo que sea modificar un VertexBuffer significa bloqueo, así que malo. A no ser que le digas que es un VertexBuffer Dynamic, que entonces lo que hace es crear otro y luego liberar el viejo. Pero como copias de la CPU a la GPU, al final siempre hay una gran ralentización.
Si te fijas, por eso, TODO lo que se puede se hace en la GPU.

Pero eso pronto va a cambiar...¿Habéis visto el raytracing de NVidia?  :o

http://www.geeks3d.com/20120517/nvidia-kepler-realtime-raytracing-demo-gtc-2012/

Manu343726


TrOnTxU

En mi opinión deberias utilizar un vertex buffer por una malla completa o incluso varias mallas o submallas.

En cuanto lo de "orientar a objetos" totalmente el motor. Si esto implica crear clases a nivel de poligono, etc. y comenzar a utilizar polimorfismo, etc a "bajo nivel", yo lo veo un GRAN ERROR. Lo intenté en el pasado (y se puede decir que lo logré, porque funcionar, funciona, claro, ... pero como funciona es otra cosa).

En mi opinión, clases para managers, y otras cosas de "alto nivel".

Struct y PODs, para todo aquello que vaya a bajo nivel. Es mejor diseñar Orientado a Datos que Orientado a Objetos. En otras cosas porque como dice Mike Acton (Insomiac Games): "donde hay uno hay más de uno".


Se que es una opinión, y que muchos estarán en contra, pero como dice un amigo (que aparte de amigo, es un crack): "C+" mola, ... el "C++" no tanto (demasiado "+" XD).


Bueno, recuerda que es solo mi opinión.

Un salduo.

Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

Manu343726

#4
sobre lo de no fragmentar los datos demasiado,  guardando éstos en muchos tipos de objetos, estoy totalmente de acuerdo. muy bonito a la hora de implementarlo (un poliedro está formado por caras, y éstas por vertices...etc etc), pero no a la hora de la eficiencia. Como comentabas, si que estoy usando un modelo de objetos para hacer diferentes managers, y así hacer las cosas más fáciles. Pero ademas de ésto, estoy procurando que siempre se tenga acceso directo a DirectX nativo, una especie de backdoor por si se necesita operar a bajo nivel, o personalizar más el programa.

He estado echando una ojeada y he tenido mucho en mente lo que decíais sobre cargar una y otra vez los vertexbuffers, por aquello de que cuanto menos cpu haya de por medio mejor. Que os parece un vertex buffer general para toda la escena, y que cada poliedro utilice su propio index buffer. Claro que ésto solo funcionará para escenas pequeñas, no puedo guardar un vertexbuffer para una malla de terreno compleja en la gpu no??? o si?

que os parece?

TrOnTxU

Cita de: VBManu en 31 de Mayo de 2012, 06:23:15 PM
He estado echando una ojeada y he tenido mucho en mente lo que decíais sobre cargar una y otra vez los vertexbuffers, por aquello de que cuanto menos cpu haya de por medio mejor. Que os parece un vertex buffer general para toda la escena, y que cada poliedro utilice su propio index buffer. Claro que ésto solo funcionará para escenas pequeñas, no puedo guardar un vertexbuffer para una malla de terreno compleja en la gpu no??? o si?

En un prinicipio, tampoco pasa nada por tener unos cuantos vertex buffers.

Hay juegos (aunque más antiguos) que tenian toda le geometria del escenario en una malla, aunque solo se dibujará parte de la misma. Pero tambien tienes que tener en cuenta si quieres que haya "instancias" de una misma geometria.
Al final la geometria de la escena la deberias tener en memoria de gpu (aunque hay API y plataformas que te permiten tener buffers en memoria principal, y hay algunos dispositivos que tienen la memoria compartida CPU/GPU).

Otra cosa es que sea un "mundo" muy grande, con lo que tienes que tirar de "streamming", pero lo que visualizas lo tienes que "tener cargado", de eso nadie te salva.

Lo que tienes que tener en cuenta son los "draw-calls". Para dibujar con "un material diferente", debes de lanzar un draw-call por cada objeto, y entre ellos, cambiar el estado del renderer (o encolar un display list, dependiendo de la API).

No hay solución mágica, ni un camino fácil ... las APIs son tan "flexibles" a la vez que "complejas" para permitir hacer las "guarrerias" que hagan falta con tal de rascar 1ms más en cada frame.

Tienes más de un camino válido y eficiente, pero por desgracia, hay más de 100 "malos" e ineficientes. Mi consejo es que busques el equilibrio, y no te obsesiones con "generalizarlo" todo. Para mi las mejores soluciones son las soluciones especificas, si estuviera inventada ya la solución mágica para todo, sobrariamos los ingenieros.

Un saludo y suerte :)

Vicent: Linked-In  ***  ¡¡Ya tengo blog!!






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.