DirectX - 在顶点缓冲区中的一半而不是浮点数

时间:2013-06-08 16:25:01

标签: c# directx slimdx vertex-buffer

最近我决定压缩我的顶点数据以提高渲染效率,我遇到了一个解决方案 - 使用一半(特别是 half4 half2 )而不是浮点数用于存储我的顶点数据。我的顶点结构如下:

[StructLayout(LayoutKind.Sequential)]  
public struct MyVertex  
{  
    public Half4 Position; //8 bytes
    public Half4 Normal; //8 bytes
    public Half2 UVW; //4 bytes
    public Half4 TextureID; //8 bytes  
    public Half4 BlendFactor; //8 bytes
    public const int SizeInBytes = (2 * 4) * 4 + (2 * 2);  
}  

这是我的顶点声明:

MyVertexDecl = new VertexDeclaration(device,
            new VertexElement[6]
        {
            new VertexElement(0, 0, DeclarationType.HalfFour, DeclarationMethod.Default, DeclarationUsage.Position, 0),
            new VertexElement(0, 8, DeclarationType.HalfFour, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
            new VertexElement(0, 16, DeclarationType.HalfTwo, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
            new VertexElement(0, 20, DeclarationType.HalfFour, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 1),
            new VertexElement(0, 28, DeclarationType.HalfFour, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 2),
            VertexElement.VertexDeclarationEnd

        });

当我将我的数据作为MyVertex数组直接发送到DrawUserPrimitives时,一切正常。
但是当我决定将所有数据放入VBO以避免过多的复制操作时,我的所有网格变成了像素混乱。我将我的值写成ushorts(SlimDX halfs为每个组件都有RawValue字段) 以下是PIX对我网格的看法: crazy numbers

在指定我的布局后,这里是缓冲区查看器中的相同部分(我只显示一列,因为它们很宽,希望你能得到这个想法):
there is a nice numbers you have there
正如你所看到的,我的半身被错误地威胁为花车。在着色器中将float4更改为half4也没有用,似乎问题出在其他地方。是否有另一种方法可以告诉我的GPU使用我的顶点缓冲区作为halfs的缓冲区而不是浮点缓冲区?

UPD:
这是我的绘图代码(缩短):

public void Render(GraphicsDevice device, ICamera camera, MyModel model)
    {
        //there are some SetValue calls
        model.Effect.CommitChanges();
        foreach (D3D9.VertexBuffer buf in model.Meshes)
        {
            device.SetStreamSource(0, buf, 0, MyVertex.SizeInBytes);
            device.DrawPrimitives(D3D9.PrimitiveType.TriangleList, 0, mesh.VertexCount);
        }
    }

以下是调用此方法的方法(主要部分):

_eff.BeginPass(0);
GraphicsDevice.VertexDeclaration = vDecl;
renderer.Render(GraphicsDevice, camera, world);
_eff.EndPass();

我正在使用D3D9到SlimDX和C#。

2 个答案:

答案 0 :(得分:1)

我明白了。我忘了锁定缓冲区并调用我的VertexDeclaration初始化方法。对于有5年经验的程序员来说,这是一种耻辱......谢谢,它现在有效:)

答案 1 :(得分:0)

通常的显卡管道经过优化,可以计算浮动的高带宽内容。

我认为directx不能在低级别处理顶点缓冲区中的一半。

我正在用Device :: CreateVertexBuffer和D3DFVF的文档备份我的猜测:

CreateVertexBuffer:格式与参数FVF一起传递。也许当将其设置为非fvf缓冲区时,可以使用自定义着色器渲染缓冲区(但我不知道您的框架是否会尝试这样做,因为它可能会更慢)。如果它不为零:

D3DFVF:所有可用的顶点格式都只是浮点数。