什么是API的独立的顶点处理一个很好的代码结构? [英] What is a good code structure for api-independant vertex processing?

查看:346
本文介绍了什么是API的独立的顶点处理一个很好的代码结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前在3D媒体引擎工作使用C#和我所遇到的一个小难题。我有我的人丁循环想通了,我有一个伟大的插件架构和内容管理系统,甚至物料管道都计划好了。然后引擎计划使用DirectX和OpenGL(通过渲染插件),随着这两个API可编程管线。

Currently working on a 3D media engine using C# and I have come across a little conundrum. I have my rending loop figured out, I got a great plug-in architecture and content management system and even a material pipeline all planned out. Then engine is planned to use DirectX and OpenGL (via 'renderer' plug-ins), along with both APIs' programmable pipe-line.

不管怎么说,在本周初,我开始对发动机工作顶点处理(我一直在害怕这几个星期)的抽象层。正如你们当中有些人知道,顶点图形API之间处理是不是在所有相关或相同的。井有点相关),但并不相同。在OpenGL处理​​顶点是非常直接的,您可以创建自定义的顶点结构,将其发送到GPU,然后让你的着色器处理其余部分。这是完美的灵活的图形管线时,OpenGL是不需要知道包含与每个顶点哪些元素。 DirectX的另一手需要我们每个顶点结构创建声明,然后将它们发送给GPU。

Anyways, at the beginning of this week I started on working on the engines abstract layer for processing vertices (I have been dreading this for weeks now). And as some of you know, vertex handling between graphic APIs' is not at all related or the same. Well kinda related ;), but not the same. In OpenGL handling vertices is very straight-forward, you create the custom vertex structure, send it to the GPU and then let your shaders handle the rest. This is perfect for a flexible graphics pipe-line, OpenGL is not required to know what elements are contained with each vertex. DirectX on the other-hand requires us to create declarations for each vertex structure and then send them to the GPU.

的问题是,我不知道是什么类型的顶点结构被通过​​,我肯定想避免创建涉及声明枚举,通过一个顶点和一些抽象的VertexDeclaration类中的每个元素的抽象层;这会导致一些问题:

The issue is that I will not know what type of vertex structure is being passed and I would definitely like to avoid creating the abstraction layer that involves declaring each element of a vertex through enumerations and some abstract 'VertexDeclaration' class; this would cause some issues:

1)获得顶点元素将是一个痛苦,至少可以说。我可以用一些VertexSemantic,并要求顶点的位置。A - Z,但处理大量的顶点为类似骨骼动画时,可以有很多的开销

1) Getting vertex elements will be a pain to say the least. I could use some 'VertexSemantic' and ask for the positions of vertex 'a - z', but when processing a lot of vertices for something like skeletal animation, it can have a lot of overhead.

2)不是很人性化的考虑引擎的主要焦点是新手。我想为用户能够创建定制的顶点和网格缓冲器,无需声明一吨的物体,消耗宝贵的开发时间。

2) Not very user-friendly considering the engines' main focus is 'newbies'. I would like for users to be able to create custom vertices and mesh buffers, without having to declare a ton of objects, consuming valuable development time.

3)多吗?

现在我可以做属性的东西,然后创造了DirectX渲染器内的顶点结构的声明。例如,继续前进,创造一些枚举:

Now I could do something with attributes and then create declarations for vertex structures inside the DirectX renderer. For instance, go ahead and create some enums:

// 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
}

现在我可以创建用户可以应用到自己的顶点结构中的各元素的'场'的属性:

Now I can create an attribute that users can apply to the 'fields' of each element in their vertex structure:

    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
    }



一个什么样的一个例子自定义顶点结构可以是这样的:

An example of what a custom vertex structure could look like:

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
}

这将是很好。在DirectX插件(渲染)我可以创建一个实用工具类,它可以为每个结构类型的语义,然后缓存数据,因此没有申报必须重新创建为每个顶点做。

This would be nice. In the DirectX plug-in (renderer) I could just create a utility class that can create the semantics for each structure type and then cache the data so the declarations don't have to be recreated for each vertex.

我连一个NONE枚举值ELementUsage增加,使自定义值可用于什么都意味着...但话又说回来,他们将在OpenGL中只有工作,因为的DirectX 。需要你来标记每一个顶点......除非有我丢失的东西。

I could even add a NONE enumeration value to ELementUsage so that custom values may be used for what ever means... but then again they would only work in OpenGL because DirectX requires you to mark each vertex... unless there is something I am missing.

我的问题(S):

有没有更好的办法去了解这个(除了使用attirbutes)?
是没有办法避免在DirectX使用VertexDeclarations? ?
是否有您可能不知道关于我的'问题的任何东西。

Is there a better way to go about this (besides using the attirbutes)? Is there a way to avoid using VertexDeclarations in DirectX? Is there any thing you may not understand about 'my' question?

编辑:

使用属性的问题将是从每个顶点获取单元数据。说我希望得到网状缓冲每个顶点的位置。自从我与属性去了,我不能只是做'vertex.Position',我会创造一个实用的方法,可以提取一个顶点结构的字段引用,比如'Utility.GetElement(顶点,ElementUsage.POSITION) 。这种方法需要使用反射来先找到属性,然后返回参考字段值。设置甚至不会(我认为)的价值可能呢?

An issue with using attributes would be getting element data from each vertex. Say I wanted to get the positions of each vertex in a mesh buffer. Since I went with attributes, I can't just do 'vertex.Position', I would have to create a utility method that could extract a field reference from a vertex structure, like 'Utility.GetElement(vertex, ElementUsage.POSITION)' . This method would need to use reflection to first find the attribute, then return the reference to the field value. Setting the value would not even (i think) be possible?

另一种方法是创建一个IElement接口,并实现每一个元素(现在的位置,正常等)。该接口可以有名称属性,我可以直接返回继承的元素结构里面,像PositionElements'Name属性将只返回当前位置。

Another way would be to create an IElement interface and implement each element (Positon, Normal, etc). The interface could have Name property that I can return directly inside the inherited element structure, like the PositionElements' Name property would just return "Positon".

接下来,我把持不住IElement数组indside包含类似的addElement(IElement),GetElement(字符串名称),GetElement(INT指数),插入方法顶点结构,更换等,我将实施众所周知的DirectX的所有元素,这样渲染器插件可以解析一个顶点结构创建顶点声明数组。

Next I could hold the array of IElement indside a Vertex struct that contains methods like AddElement(IElement), GetElement(string name), GetElement(int index), Insert, Replace, etc. I would implement all elements known to DirectX so that the renderer plug-in could parse a vertex structure to create an array of vertex declarations.

这样做的问题是,我不知道如果一个数组'[]'可以用作顶点元素的数据。就像,不数组包含什么其它字节(如果有的话)会妨碍我从传递顶点结构(包含IElement数组)直接到DirectX,然后到GPU?

The issue with this is that I am not sure if an array '[]' can be used as vertex element data. Like, what other bytes does an array contain (if any) that would hinder me from passing the Vertex struct (contains the IElement array) directly to DirectX, then to the GPU?

实现这种方式会是什么,我需要它绝对完美的。另一个问题是可以继承的类型IElement的(元素)是一个类,或做元素的值必须是值类型?

Implementing it this way would be absolutely perfect for what I need it for. Another question is could the inheriting types of IElement (the elements) be a class, or do element values have to be value-types?

推荐答案

这是一个很长的时间,因为我做任何的DirectX或OpenGL,所以把我的意见与一粒盐,但我记得做的的东西的这样一个前一阵子。

It has been a long time since I've done any directx or opengl, so take my advice with a grain of salt, but I remember doing something like this a while ago.

我觉得我做了这样的事情:

I think I did something like this:

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);

您不得不这是应用了使用一组类型化数据集的图形流。从这个可以产生适当的顶点格式。该API将让你改变单个元素或上传并一气呵成更换整个顶点缓冲区。

You'd have a graphics stream which was a set of typed data sets with a usage applied. From this you can generate an appropriate vertex format. The API would let you change individual elements or upload and replace the entire vertex buffer in one go.

最大的缺点是,你不会有一个结构,它代表一个列在你的顶点结构。

The biggest downside is that you don't have one structure that represents a "column" in your vertex structure.

我不知道这是东西你要找的那种。为什么会这样的设计不适合?

I don't know if this is the kind of thing you're looking for. Why would a design like this not be appropriate?

这篇关于什么是API的独立的顶点处理一个很好的代码结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆