3

我是 DirectX 的新手,我正在尝试在一个场景中使用D3DPT_TRIANGLESTRIP. 一个矩形没问题,但两个矩形是完全不同的球类游戏。D3DPT_TRIANGLELIST是的,我可以使用原始类型绘制的四个三角形来绘制它们。我的好奇心在于使用D3DPT_TRIANGLESTRIP. 我用于一个 Rectangle 的部分代码D3DPT_TRIANGLESTRIP如下:

CUSTOMVERTEX recVertex[] = {
    {  10.0f,  10.0f, 0.10f, 1.0f, 0xffffffff, }, // x, y, z, rhw, color
    { 220.0f,  10.0f, 0.10f, 1.0f, 0xffffffff, },   
    {  10.0f, 440.0f, 0.10f, 1.0f, 0xffffffff, },   
    { 220.0f, 440.0f, 0.10f, 1.0f, 0xffffffff, },
}; 

if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4 * sizeof( CUSTOMVERTEX ),
               0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
{
    return E_FAIL;
}

更重要的代码...

VOID* precVertex;    
if( FAILED( g_pVB->Lock( 0, sizeof( recVertex ), ( void** )&pGameField, 0 ) ) ) 
{
return E_FAIL; 
}
 memcpy( precVertex, recVertex, sizeof( recVertex ) );

然后像这样渲染...

g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

基于这个模型,我可以轻松地复制代码更改自定义顶点上的 x 和 y 值并创建另一个顶点缓冲区,它会工作。

就我个人而言,我觉得这不是最好的方法,特别是考虑到我必须绘制 100 个矩形或类似的东西的情况。问题是,我没有其他想法。所以我的问题是,用 绘制两个矩形的最有效方法是什么D3DPT_TRIANGLESTRIP?还有一种复制和转换当前矩形的可能方法吗?

4

4 回答 4

3

最有效的方法是使用索引绘制,然后在 2 个矩形之间重复索引。

即索引 0, 1, 2, 3, 3, 4, 4, 5, 6, 7 从三角形剥离中产生以下三角形

0, 1, 2 - 1, 2, 3 - 2, 3, 3 - 3, 3, 4 - 3, 4, 4 - 4, 4, 5 - 4, 5, 6 - 5, 6, 7

三角形 2, 3, 3 - 3, 3, 4 - 3, 4, 4 和 4, 4, 5 的面积都是零,在显卡上很早就会被丢弃。这样,您可以在一次调用 DrawIndexedPrimitive 时渲染 4 个三角形。

当然,这意味着您要发送 10 个索引。您也可以只发送 12 个索引并将两个矩形绘制为 tri 列表中的 4 个三角形。使用索引绘图时,您会发现硬件会跟踪它已经转换的顶点,因此它不必再费心了。

即,如果您将索引缓冲区定义为

0, 1, 2, 3, 0, 2, 4, 5, 6, 7, 4, 6

并且你有一个至少有 4 个顶点的后期变换缓存(几乎每个显卡都有一个大得多的后期变换缓存,GeForce 3 肯定做到了!)然后你可以看到两个三角形都将被渲染,但每个顶点只会变身一次。与直觉相反,在任何 DX8 后硬件(即任何 DX9 或 10 硬件)上,您会发现使用此后变换缓存和三角形列表的额外简单性意味着您实际上会从三角形列表中获得比三角形更好的性能条。

所以总而言之,回答“所以我的问题是,用 D3DPT_TRIANGLESTRIP 绘制两个矩形的最有效方法是什么?” 答案是绘制一个 D3DPT_TRIANGLELIST 并停止担心它:)

于 2009-08-28T06:47:58.780 回答
2

将第二个矩形的四个顶点添加到顶点缓冲区,然后调用DrawPrimitive两次。

g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 4, 2 );
于 2009-08-28T05:40:43.890 回答
1

您可以扩展recVertex到 8 点。这是一种常见的技术。专为在这种模式下工作而设计的 3D 硬件。例如查看教程。

如果你想绘制 100 个(我认为这意味着在问题的上下文中“一个巨大的数字”)矩形,你应该考虑使用meshes

于 2009-08-28T05:56:26.653 回答
0

通常最好将几何图形批处理到更大的索引顶点缓冲区中,并为每个 3D 对象调用具有正确偏移的适当绘图函数到缓冲区中。请记住,硬件不会将您的对象视为单独的实体,它只关心顶点/索引缓冲区、纹理、着色器程序和各种状态。您的工作是以最佳方式将其全部提供给硬件,并在每帧中批量处理合理数量的绘图任务。

对于像这样的微小几何图形和固定功能,您绝对应该将全部拍打到单个缓冲区中。

于 2009-09-03T11:52:44.240 回答