【发布时间】:2013-06-08 16:25:00
【问题描述】:
最近我决定压缩我的顶点数据以提高渲染效率,我遇到了一个解决方案 - 使用 half(特别是 half4 和 half2)而不是 float用于存储我的顶点数据。我的顶点结构如下:
[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 对我的网格的评价:
这是指定布局后缓冲区查看器中的相同部分(我将只显示一列,因为它们很宽,希望你能明白):
正如你所看到的,我的一半被错误地威胁为漂浮物。在着色器中将 float4 更改为 half4 也无济于事,似乎问题出在其他地方。是否有另一种方法告诉我的 GPU 使用我的顶点缓冲区作为半缓冲区而不是作为浮点缓冲区?
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();
我正在通过 SlimDX 和 C# 使用 D3D9。
【问题讨论】:
-
你能显示你的代码 sn-p 来填充缓冲区吗?
-
@Gnietschow 当然,这里是 - pastebin.com/YzcnUc8r
-
嗯,没有看到任何错误。你的绘图代码呢?愚蠢的问题:你记得在draw call之前设置顶点声明吗?
-
@Gnietschow 听起来我当时在某个地方犯了一个愚蠢的错误。我已经用部分绘图代码更新了我的帖子。感谢您的帮助!
-
那很好:),但不幸的是我不知道为什么它不起作用。最后一个猜测:在你的填充代码中你使用
data.indices.Count(),不应该是顶点的计数吗?你会解锁缓冲区吗?
标签: c# directx slimdx vertex-buffer