【DX11地形篇】2-地形网格

参考教程

Tutorial 1: Grid and Camera Movement

学习记录

  本篇主要介绍对地形网格的绘制,代码基于上一篇内容。

  既然说是地形网格,那么自然是以网格为主。我们之前在 ModelClass 中读取模型文件来创建模型数据,在 TerrainClass 中则是使用代码生成网格。首先来看我们 TerrainClass 的声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
////////////////////////////////////////////////////////////////////////////////
// Class name: TerrainClass
////////////////////////////////////////////////////////////////////////////////
class TerrainClass
{
private:
struct VertexType
{
XMFLOAT3 position;
XMFLOAT4 color;
};

public:
TerrainClass();
TerrainClass(const TerrainClass&);
~TerrainClass();

bool Initialize(ID3D11Device*);
void Shutdown();
bool Render(ID3D11DeviceContext*);

int GetIndexCount();

private:
bool InitializeBuffers(ID3D11Device*);
void ShutdownBuffers();
void RenderBuffers(ID3D11DeviceContext*);

private:
ID3D11Buffer *m_vertexBuffer, *m_indexBuffer;
int m_vertexCount, m_indexCount;
};

  和 ModelClass 几乎相同。在它的 InitializeBuffers 方法中,我们使用代码生成顶点和索引数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
bool TerrainClass::InitializeBuffers(ID3D11Device* device)
{
VertexType* vertices;
unsigned long* indices;
D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
D3D11_SUBRESOURCE_DATA vertexData, indexData;
HRESULT result;
int i, j, terrainWidth, terrainHeight, index;
XMFLOAT4 color;
float positionX, positionZ;


// Set the height and width of the terrain grid.
terrainHeight = 256;
terrainWidth = 256;

// Set the color of the terrain grid.
color = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);

// Calculate the number of vertices in the terrain.
m_vertexCount = (terrainWidth - 1) * (terrainHeight - 1) * 8;

// Set the index count to the same as the vertex count.
m_indexCount = m_vertexCount;

// Create the vertex array.
vertices = new VertexType[m_vertexCount];
if(!vertices)
{
return false;
}

// Create the index array.
indices = new unsigned long[m_indexCount];
if(!indices)
{
return false;
}

// Initialize the index into the vertex and index arrays.
index = 0;

// Load the vertex array and index array with data.
for(j=0; j<(terrainHeight-1); j++)
{
for(i=0; i<(terrainWidth-1); i++)
{
// Line 1 - Upper left.
positionX = (float)i;
positionZ = (float)(j + 1);

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;

// Line 1 - Upper right.
positionX = (float)(i + 1);
positionZ = (float)(j + 1);

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;

// Line 2 - Upper right
positionX = (float)(i + 1);
positionZ = (float)(j + 1);

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;

// Line 2 - Bottom right.
positionX = (float)(i + 1);
positionZ = (float)j;

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;

// Line 3 - Bottom right.
positionX = (float)(i + 1);
positionZ = (float)j;

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;

// Line 3 - Bottom left.
positionX = (float)i;
positionZ = (float)j;

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;

// Line 4 - Bottom left.
positionX = (float)i;
positionZ = (float)j;

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;

// Line 4 - Upper left.
positionX = (float)i;
positionZ = (float)(j + 1);

vertices[index].position = XMFLOAT3(positionX, 0.0f, positionZ);
vertices[index].color = color;
indices[index] = index;
index++;
}
}

// Set up the description of the static vertex buffer.
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;

// Give the subresource structure a pointer to the vertex data.
vertexData.pSysMem = vertices;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;

// Now create the vertex buffer.
result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);
if(FAILED(result))
{
return false;
}

// Set up the description of the static index buffer.
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
indexBufferDesc.StructureByteStride = 0;

// Give the subresource structure a pointer to the index data.
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;

// Create the index buffer.
result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);
if(FAILED(result))
{
return false;
}

// Release the arrays now that the buffers have been created and loaded.
delete [] vertices;
vertices = 0;

delete [] indices;
indices = 0;

return true;
}

  可以看到我们是以四条线的方式来确定每一个四边形,所以在绘制图元类型的时候我们选用线绘制:

1
2
// Set the type of primitive that should be rendered from this vertex buffer, in this case lines.
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);

  最终效果(高处往下看):

2

  源代码:DX11TerrainTutorial-GridAndCameraMovement

0%