重写VertexPositionTexture以使用整数向量

时间:2012-08-29 20:10:37

标签: c# xna-4.0

我目前正在开发一个涉及使用VertexPositionTextures设置大量顶点数据的项目。这最终占用了大量内存,虽然我可以做一些优化,但我可以做到目前内存中的内容以及可以卸载到硬盘驱动器的内容,我希望尽可能地优化。

我的问题是:有没有办法可以重写VertexPositionTexture结构,以便它使用我的自定义IntVector类来减少占用空间?这还需要修改DrawPrimitives和DrawUserPrimitives吗?

我问这个因为我没有使用纹理图集,所以我的UV坐标总是(0,0),(0,1),(1,0),(1,1)可以表示没有浮点数,我的顶点位置也很容易用整数表示。

1 个答案:

答案 0 :(得分:4)

是的,你可以这样做。你只需要定义一个自定义顶点格式,XNA将完成其余的工作。

最重要的是要注意,您只能使用可用VertexElementFormat s(MSDN)中的元素 - 并注意到HalfVector格式在Reach个人资料(info)。

您可能不需要创建自己的矢量类型,因为XNA已经为Microsoft.Xna.Framework.Graphics.PackedVectorMSDN)或主库中的所有可用格式提供了实现。如果你想创建自己的类型,它需要是struct(或顶点中的松散字段),它们以相同的方式打包。

最后,值得指出的是,没有32位int数据类型。并且也没有任何好处,因为float(a Single)在32位时的大小相同。 (并且一些GPU以单精度运行,因此无论如何都无法保持额外的精度。)


因此,我们从包含VertexPositionTexture位置(96位)和Vector3纹理坐标(64位)的Vector2开始,总共160位。

让我们将其转换为自定义IntVertexPositionTexture,其中包含Short4位置(64位)和NormalizedShort2纹理坐标(32位),总共96位(40%大小)减少)。

(如果您使用的是2D,则可以使用Short2代替Short4并保存另外32位。没有Short3。)

这是顶点类型的代码,实际上只是知道API期望的情况:

struct IntVertexPositionTexture : IVertexType
{
    public Short4 Position;
    public NormalizedShort2 TextureCoordinate;

    public IntVertexPositionTexture(Short4 position, NormalizedShort2 textureCoordinate)
    {
        this.Position = position;
        this.TextureCoordinate = textureCoordinate;
    }

    public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration(new VertexElement[]
    {
        new VertexElement(0, VertexElementFormat.Short4, VertexElementUsage.Position, 0),
        new VertexElement(8, VertexElementFormat.NormalizedShort2, VertexElementUsage.TextureCoordinate, 0),
    });

    VertexDeclaration IVertexType.VertexDeclaration
    {
        get { return IntVertexPositionTexture.VertexDeclaration; }
    }
}

创建自定义顶点类型时,重要的是确保字段与您在VertexDeclarationMSDN)中指定的顺序和布局相匹配。如何创建VertexDeclaration应该是不言自明的 - 只需查看MSDN page for VertexElement's constructor即可。每个字段的偏移量以字节为单位指定。

elementUsageusageIndex在HLSL中与vertex shader semantics匹配。因此,在这种自定义格式中,我们有POSITION0TEXCOORD0

使用IVertexType是可选的,因为您也可以将VertexDeclaration直接传递给(例如)VertexBuffer构造函数。


如果您想要为我提供的顶点格式制作不同的顶点格式,那么这应该是您需要的所有信息。有关详细信息,可以使用blog post by Shawn Hargreaves详细了解API。