我目前正在开发一个涉及使用VertexPositionTextures设置大量顶点数据的项目。这最终占用了大量内存,虽然我可以做一些优化,但我可以做到目前内存中的内容以及可以卸载到硬盘驱动器的内容,我希望尽可能地优化。
我的问题是:有没有办法可以重写VertexPositionTexture结构,以便它使用我的自定义IntVector类来减少占用空间?这还需要修改DrawPrimitives和DrawUserPrimitives吗?
我问这个因为我没有使用纹理图集,所以我的UV坐标总是(0,0),(0,1),(1,0),(1,1)可以表示没有浮点数,我的顶点位置也很容易用整数表示。
答案 0 :(得分:4)
是的,你可以这样做。你只需要定义一个自定义顶点格式,XNA将完成其余的工作。
最重要的是要注意,您只能使用可用VertexElementFormat
s(MSDN)中的元素 - 并注意到HalfVector
格式在Reach
个人资料(info)。
您可能不需要创建自己的矢量类型,因为XNA已经为Microsoft.Xna.Framework.Graphics.PackedVector
(MSDN)或主库中的所有可用格式提供了实现。如果你想创建自己的类型,它需要是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; }
}
}
创建自定义顶点类型时,重要的是确保字段与您在VertexDeclaration
(MSDN)中指定的顺序和布局相匹配。如何创建VertexDeclaration
应该是不言自明的 - 只需查看MSDN page for VertexElement
's constructor即可。每个字段的偏移量以字节为单位指定。
elementUsage
和usageIndex
在HLSL中与vertex shader semantics匹配。因此,在这种自定义格式中,我们有POSITION0
和TEXCOORD0
。
使用IVertexType
是可选的,因为您也可以将VertexDeclaration
直接传递给(例如)VertexBuffer
构造函数。
如果您想要为我提供的顶点格式制作不同的顶点格式,那么这应该是您需要的所有信息。有关详细信息,可以使用blog post by Shawn Hargreaves详细了解API。