地形仅在下面呈现

时间:2014-04-17 18:56:31

标签: c++ directx rendering terrain

我正在尝试渲染地图,但不幸的是,只渲染了底面。

我想在设置顶点和索引缓冲区时我做错了。

这是我初始化顶点和索引缓冲区的部分:

// Initialize vertices and indices
SimpleVertex* vertices = new SimpleVertex[(dimension + 1) * (dimension + 1)];
WORD* indices = new WORD[dimension * dimension * 6];

for (WORD i = 0; i < dimension + 1; ++i)
{
    for (WORD j = 0; j < dimension + 1; ++j)
    {
        vertices[i * (dimension + 1) + j].Pos = XMFLOAT3(i, rand() % 2, j);
        vertices[i * (dimension + 1) + j].Color = XMFLOAT4(rand() % 2, rand() % 2, rand() % 2, 1.0f);
    }
}

for (WORD i = 0; i < dimension; i++)
{
    for (WORD j = 0; j < dimension; j++)
    {
        indices[(i * dimension + j) * 6] = (WORD)(i * (dimension + 1) + j);
        indices[(i * dimension + j) * 6 + 2] = (WORD)(i * (dimension + 1) + j + 1);
        indices[(i * dimension + j) * 6 + 1] = (WORD)((i + 1) * (dimension + 1) + j + 1);
        indices[(i * dimension + j) * 6 + 3] = (WORD)(i * (dimension + 1) + j);
        indices[(i * dimension + j) * 6 + 5] = (WORD)((i + 1) * (dimension + 1) + j + 1);
        indices[(i * dimension + j) * 6 + 4] = (WORD)((i + 1) * (dimension + 1) + j);
    }
}

// Create vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(SimpleVertex)* (dimension + 1) * (dimension + 1);
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer(&bd, &InitData, &g_pVertexBuffer);
delete vertices;
if (FAILED(hr))
    return hr;

// Set vertex buffer
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);

// Create indices buffer
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(WORD)* dimension * dimension * 6;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = indices;
hr = g_pd3dDevice->CreateBuffer(&bd, &InitData, &g_pIndexBuffer);
delete indices;
if (FAILED(hr))
    return hr;

我的英语不好的借口:(。谢谢你的阅读!

2 个答案:

答案 0 :(得分:1)

我遇到的第一件事是你可能会以错误的顺序声明你的顶点。如果您的Direct3D上下文期望顶点是逆时针,并且您的顺序是按顺时针顺序定义的,则“背面剔除”将导致您的多边形不可见,除非从另一侧查看。

具体来说,D3D11_RASTERIZER_DESC :: FrontCounterClockwise设置方向。 (见http://msdn.microsoft.com/en-us/library/windows/desktop/ff476198%28v=vs.85%29.aspx

在设置光栅化器描述的代码中,尝试设置CullMode = D3D11_CULL_NONE,如果出现地形,那么这就是你的问题。

答案 1 :(得分:1)

最有可能的是,面部剔除没有正确设置。

理论上(感谢Google提供链接;)):

在实践中

  1. 您决定将顶点放在三角形中的顺序(实际上,您使用索引进行操作,因为缓冲区已编入索引) - 顺时针或逆时针。
  2. 做出决定#1,您现在决定哪些面孔必须被视为&#34;前面&#34;:

    D3D11_RASTERIZER_DESC rd = {};
    rd.FrontCounterClockwise = true; // counterclockwise are front
    
  3. 你决定rasterizer必须剔除哪些面:后面的,前面的,或者没有:

    rd.CullMode = D3D11_CULL_BACK; // back faced primitives will be stripped out 
                                   // during rasterization
                                   // (clockwise ones in our example)
    
  4. 因此,您可以更改几何绕组和/或DirectX绕组选项和/或DirectX剔除选项。

    注意:默认情况下,DirectX 11使用falseD3D11_CULL_BACK作为上述参数。因此,它将顺时针原始图像视为正面,并将逆时针图像视为背面。

    注意:为了更好地理解剔除,请在纸张的两面画一个三角形,就好像从不同的侧面看同一个三角形一样。将指数放在每个顶点附近(纸张两侧相同)。画一个显示上弦顺序的圆形箭头。将它与您的网格进行比较。然后很明显你必须使用哪种缠绕顺序和剔除。

    <强>来源:

    MSDN DirectX参考页: