1

我遇到了一些问题。

我需要类或结构来表示不同类型的顶点(TextureVertex,ColorVertex等)。我还需要一个超类 ( Vertex),因为我需要能够VertexBuffer为任何顶点类型制作。顶点必须是值类型,为什么我似乎需要一个结构。

这种冲突在 C# 中通常是如何解决的?

编辑:我需要值类型数据的原因是该方法(http://sharpdx.org/documentation/api/m-sharpdx-direct3d11-buffer-create--1-1)似乎需要这种方式。它调用非托管代码,顶点数据进入数据参数。

编辑2:抛出一些代码

public interface Vertex
{ }

[StructLayout(LayoutKind.Sequential)]
public struct TextureVertex : Vertex
{
    private Vector3 _position;
    public Vector3 Position { get { return _position; } set { _position = value; } }

    private Vector2 _texture;
    public Vector2 Texture { get { return _texture; } set { _texture = value; } }

    private Vector3 _normal;
    public Vector3 Normal { get { return _normal; } set { _normal = value; } }

    public TextureVertex(float x, float y, float z, float u, float v)
    {
        _position = new Vector3(x, y, z);
        _texture = new Vector2(u, v);
        _normal = new Vector3();
    }
}

...

TextureVertex[] vertices = new []
{
    new TextureVertex(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f),
    new TextureVertex(-1.0f, +1.0f, 0.0f, 0.0f, 0.0f),
    new TextureVertex(+1.0f, +1.0f, 0.0f, 1.0f, 0.0f),
    new TextureVertex(+1.0f, -1.0f, 0.0f, 1.0f, 1.0f)
};

...

VertexBuffer = Buffer.Create<Vertex>(Graphics.Device, BindFlags.VertexBuffer, vertices);
4

2 回答 2

7

这种要求的组合是不可能的。您可以创建Vertex一个界面 ( IVertex),但请注意,struct随后键入的任何内容IVertex都将被“装箱”。也许你最好的选择是使用泛型,即Buffer<T> where T : IVertex. 只要您以T(而不是IVertex)的形式键入任何变量/字段/等,那么它将受到约束,也就是说:没有装箱。你在代码中使用的那一刻IVertex(除了在约束中)你会得到拳击 - 所以尽量避免这种情况。

具体来说:

T[] someBuffer = ...

T item0 = someBuffer[0]; // no box required here
item0.SomeMethodOnIVertex(); // this is a "constrained" call; no boxing

IVertex item1 = someBuffer[1]; // BOX HERE!!!
item1.SomeMethodOnIVertex(); // this is a virtual call via the box
于 2013-05-23T08:40:37.503 回答
1

不,在这种情况下你不能使用继承。

顶点是值类型的原因是为了确保一个顶点数组(本质上是一个缓冲区)将被布置为一块连续的内存。

这样,底层框架在将其发送到图形驱动程序时将能够仅使用 1 个操作来复制它。

但是值类型的这种行为确实有一个很大的限制:Vertex 的所有实例在内存中必须具有相同的大小,以便运行时可以根据其索引在数组中定位一个值。

但是允许对结构进行继承会打破这种期望,因为您可以将 ColorVertex(带有颜色数据)放在顶点值数组中,因此在同一个数组中具有不同大小的对象。

这种行为对于 ref 类型(想想“类”)是可能的,因为在这种情况下,数组将只存储对真实内容的固定大小的引用。

But it also means that copying only the array would not include the actual data, and copying the actual data would require reading the array, then copying each instance individually which would not yield acceptable performance for a 3D engine.

于 2013-05-23T09:00:58.713 回答