¿Qué es una buena estructura de código para el procesamiento de vértices api-independiente? [cerrado]

StackOverflow https://stackoverflow.com/questions/2189494

Pregunta

En la actualidad trabaja en un motor de medios 3D usando C # y me he encontrado con un pequeño acertijo. He mi bucle desgarrador descubierto, me dieron una gran arquitectura plug-in y el sistema de gestión de contenidos e incluso de una tubería de material todo planeado. Entonces motor está previsto utilizar DirectX y OpenGL (vía 'renderer' plug-ins), junto con programable La tubería de ambas API.

De todas formas, a principios de esta semana que comenzó el trabajo sobre la capa abstracta motores para el procesamiento de vértices (he estado temiendo esto hace semanas). Y como algunos de ustedes saben, la manipulación vértice entre las API gráficas no es en absoluto relacionado o el mismo. Bien poco relacionados;), pero no es lo mismo. En OpenGL manipulación de vértices es muy sencillo, se crea la estructura del vértice a medida, lo envía a la GPU y luego deje que sus shaders se encargue del resto. Esto es perfecto para una tubería de gráficos de línea flexibles, OpenGL no es necesario saber qué elementos están contenidos en cada vértice. DirectX en la otra mano nos obliga a crear declaraciones para cada estructura vértice y luego enviarlos a la GPU.

El problema es que no voy a saber lo que se está pasando tipo de estructura vértice y sin duda como para evitar la creación de la capa de abstracción que implica declarar cada elemento de un vértice a través de las enumeraciones y algunos clase abstracta 'VertexDeclaration'; esto podría causar algunos problemas:

1) Obtención de elementos de vértice será un dolor para decir lo menos. Podría utilizar una cierta 'VertexSemantic' y pedir las posiciones de vértice. 'A - z', pero cuando se procesa una gran cantidad de vértices para algo así como animación del esqueleto, que puede tener un montón de gastos generales

2) No es muy fácil de usar teniendo en cuenta los motores foco principal es 'novatos'. Me gustaría que los usuarios sean capaces de crear vértices personalizados y malla tampones, sin tener que declarar una tonelada de objetos, consumiendo valioso tiempo de desarrollo.

3) más?

Ahora que podía hacer algo con los atributos y luego crear declaraciones de estructuras de vértices dentro del procesador de DirectX. Por ejemplo, seguir adelante y crear algunas enumeraciones:

// for getting the format layout of the element
public enum ElementFormat
{
    Float, Float2, Float3, Byte, etc, etc
}
// for determining the 'usage' 
// (here is 'another' where DirectX limits vertex structures ><)
public enum ElementUsage
{
    Position, Normal, Color, TextureCoord, etc, etc
}

Ahora puede crear un atributo que los usuarios pueden aplicar a los 'campos' de cada elemento en su estructura vértice:

    public class VertexElementAttribute : Attribute
    {
        #region Properties
        /// <summary>
        /// Gets the total size (in bytes) of the element.
        /// </summary>
        public int Size
        {
            get;
            set;
        }
        /// <summary>
        /// Gets the number of values contained with-in the element.
        /// </summary>
        public int Count
        {
            get;
            set;
        }
        /// <summary>
        /// Gets the type semantic of the element.
        /// </summary>
        public ElementType Type
        {
            get;
            set;
        }
        /// <summary>
        /// Gets the usage semantic of the element.
        /// </summary>
        public ElementUsage Usage
        {
            get;
            set;
        }
        #endregion

        #region Init
        /// <summary>
        /// Creates a new vertex element attribute.
        /// </summary>
        /// <param name="count">The number of values contained within the element.</param>
        /// <param name="size">The total size (in bytes) of the element.</param>
        /// <param name="type">The type semantic of the element.</param>
        /// <param name="usage">The usage semantic of the element.</param>
        public VertexElementAttribute(int count, int size, ElementType type, ElementUsage usage)
        {
            Count = count;
            Size = size;
            Type = type;
            Usage = usage;
        }
        #endregion
    }

Un ejemplo de lo que es una estructura de vértice a medida podría ser:

public struct VertexPositionColor
{
    [VertexElement(3, sizeof(Vector3), ElementType.FLOAT3, ElementUsage.POSITION)]
    public Vector3 Xyz;
    [VertexElement(4, sizeof(Color), ElementType.FLOAT4, ElementUsage.COLOR)]
    public Color Rgba; 

    ... etc
}

Esto estaría bien. En el DirectX plug-in (render) tan sólo pudiera crear una clase de utilidad que puede crear la semántica para cada tipo de estructura y luego almacenar en caché los datos para las declaraciones no tienen que ser recreado para cada vértice.

Incluso podría añadir un valor NINGUNO enumeración de ELementUsage modo que los valores personalizados se pueden utilizar para lo que cada vez los medios ... pero por otra parte que lo harían sólo funcionan en OpenGL porque DirectX se requiere para marcar cada vértice ... a menos que haya algo que me falta.

Mi pregunta (s):

¿Hay una mejor manera de hacer esto (además de usar los attirbutes)? ¿Hay una manera de evitar el uso de VertexDeclarations en DirectX? ¿Hay alguna cosa que no puede entender acerca de 'mi' pregunta?

EDIT:

Un problema con el uso de atributos sería conseguir datos de los elementos de cada vértice. Decir que quería obtener las posiciones de cada vértice en un buffer de malla. Desde que fui con atributos, no puedo hacerlo 'vertex.Position', que tendría que crear un método de utilidad que podría extraer una referencia de campo de una estructura de vértice, como 'Utility.GetElement (vértice, ElementUsage.POSITION)' . Este método tendría que utilizar la reflexión para encontrar primero el atributo, y luego volver la referencia al valor del campo. Establecer el valor ni siquiera (creo) ser posible?

Otra forma sería la creación de una interfaz IElement e implementar cada elemento (Positon, normal, etc). La interfaz podría tener propiedad Name que puedo volver directamente dentro de la estructura del elemento heredado, al igual que los PositionElements' Nombre de la propiedad que acaba de regresar 'Positon'.

A continuación me podía sostener el conjunto de IElement indside una estructura de vértices que contiene métodos como addElement (IElement), GetElement (nombre de la cadena), GetElement (int index), Insertar, Reemplazar, etc. Me volvería a poner en práctica todos los elementos conocidos para DirectX de modo que el procesador de plug-in podría analizar una estructura de vértice para crear una matriz de las declaraciones de vértices.

El problema con esto es que no estoy seguro de si '[]' se puede utilizar una matriz como datos de elementos de vértice. Como, ¿qué otra bytes contiene una matriz (si los hay) que eso me obstaculizar el paso de la estructura Vertex (contiene la matriz IElement) directamente a DirectX, a continuación, a la GPU?

Ejecución de esta manera sería perfecto absolutamente lo que lo necesita. Otra pregunta es ¿podrían los tipos que heredan de IElement (los elementos) ser una clase, o hacer valores de los elementos tienen que ser de valor tipos?

¿Fue útil?

Solución

Ha sido un largo tiempo desde que he hecho cualquier DirectX u OpenGL, así que tome mi consejo con un grano de sal, pero recuerdo que hace algo como esto hace un tiempo.

Creo que hice algo como esto:

var graphicsStream = new GraphicsStream();

var elements = graphicsStream.Create<Vector3>(Usage.Position);
graphicsStream.Create<Color>(Usage.Color);
graphicsStream.Create<Quaternion>(Usage.Fribble);

elements.SetData(new[] { new Vector3(), new Vector3() });

var vertexFormat = graphicsStream.GetFormat();
graphicsStream.Validate();  // ensure all the streams have the same length

// get a particular element by type
var p = graphicsStream.GetData(Usage.Position, 1);

tendría una corriente de gráficos que era un conjunto de conjuntos de datos de tipo con un uso aplicado. De esto se puede generar un formato de vértice apropiado. La API sería permitirá cambiar elementos individuales o de carga y reemplazar todo el búfer de vértices de una sola vez.

El mayor inconveniente es que no tiene una estructura que representa una "columna" en la estructura de su vértice.

No sé si este es el tipo de cosa que usted está buscando. ¿Por qué un diseño como este no sea apropiado?

Otros consejos

Se puede echar un vistazo a cómo OGRE maneja esto. En particular El render documentación del sistema sobre VertexElement y también el vértice buffer de clases . OGRE es C ++, pero estoy seguro de que será capaz de obtener los patrones de diseño fácilmente convertidos a C #.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top