我目前正在关注Frank D. Luna的Directx 10书。我刚刚遇到了他用于渲染山脉的一种方法,我不确定我理解他为什么使用它。对于他使用的顶点缓冲区:(n和m是行,列,dx为1.0f)(Getheight将X和Z放入类似于山的功能)
)float dx = 1.0f;
float halfWidth = (n - 1)*dx*0.5f;
float halfDepth = (m - 1)*dx*0.5f;
for (DWORD i = 0; i < m; ++i)
{
float z = halfDepth - i*dx;
for (DWORD j = 0; j < n; ++j)
{
float x = -halfWidth + j*dx;
// Graph of this function looks like a mountain range.
float y = getHeight(x, z);
vertices[i*n + j].pos = D3DXVECTOR3(x, y, z);
// Color the vertex based on its height.
if (y < -10.0f)
vertices[i*n + j].color = BEACH_SAND;
else if (y < 5.0f)
vertices[i*n + j].color = LIGHT_YELLOW_GREEN;
else if (y < 12.0f)
vertices[i*n + j].color = DARK_YELLOW_GREEN;
else if (y < 20.0f)
vertices[i*n + j].color = DARKBROWN;
else
vertices[i*n + j].color = WHITE;
}
}
然后,他使用的索引缓冲区:
int k = 0;
for (DWORD i = 0; i < m - 1; ++i)
{
for (DWORD j = 0; j < n - 1; ++j)
{
indexlist[k] = i*n + j;
indexlist[k + 1] = i*n + j + 1;
indexlist[k + 2] = (i + 1)*n + j;
indexlist[k + 3] = (i + 1)*n + j;
indexlist[k + 4] = i*n + j + 1;
indexlist[k + 5] = (i + 1)*n + j + 1;
k += 6; // next quad
}
}
如果有人可以向我解释这两个缓冲区的用途,那将是很棒的。我只是不太确定他为什么使用这些方程以及这些方程式做什么。
创建VertexBuffer时,术语i * n + j
用于计算当前顶点的索引。j
用于X轴上的位置。因此,如果您增加j
并保持i
,则可以在同一行的右侧到达顶点。索引也增加了1。如果您增加i
并保持j
,则将到达当前一个以下的顶点。该索引增加了n
(场的宽度)。这很自然,因为两者之间的顶点必须存在。
使用n = 4
的宽度,您将获得以下编号
j| 0 | 1 | 2 | 3 |
i | | | | |
---+----+----+----+----+
0 | 0 | 1 | 2 | 3 |
1 | 4 | 5 | 6 | 7 |
2 | 8 | 9 | 10 | 11 |
...
您会看到,从行i
到行i+1
移动导致索引被字段宽度增加,而从j
列到j+1
导致索引增加了1。这在公式j + i * n
中增加了。
使用相同的公式用于计算索引缓冲区。
第一个三角形是:
col j , row i -> j + i * n
col j + 1, row i -> j + 1 + i * n
col j , row i + 1 -> j + (i + 1) * n