【DX11地形篇】4-地形网格纹理

参考教程

Tutorial 3: Terrain Texturing

学习记录

  本篇介绍地形网格的纹理贴图,基于上一篇代码,我们简单的使用 TextureShaderClass 来渲染网格,使用一个 TextureManagerClass 类管理项目中的纹理数据。框架如图:

1

  这次我们将以 TextureShaderClass 来代替 ColorShaderClass 渲染网格,所以在 ShaderManagerClass 中新增 TextureShaderClass 的对象,同时添加它的 Render 接口。修改后的类声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
////////////////////////////////////////////////////////////////////////////////
// Class name: ShaderManagerClass
////////////////////////////////////////////////////////////////////////////////
class ShaderManagerClass
{
public:
ShaderManagerClass();
ShaderManagerClass(const ShaderManagerClass&);
~ShaderManagerClass();

bool Initialize(ID3D11Device*, HWND);
void Shutdown();

bool RenderColorShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX);
bool RenderFontShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4);
bool RenderTextureShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*);

private:
ColorShaderClass* m_ColorShader;
FontShaderClass* m_FontShader;
TextureShaderClass* m_TextureShader;
};

  其次,我们修改 TerrainClass ,为顶点增加 uv 属性,并且在初始化顶点数据的时候初始化:

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
struct VertexType
{
XMFLOAT3 position;
XMFLOAT2 texcoord;
};

struct HeightMapType {
float x, y, z;
};

struct ModelType {
float x, y, z;
float tu, tv;
};

// Load the 3D terrain model with the height map terrain data.
// We will be creating 2 triangles for each of the four points in a quad.
for(j=0; j<(m_terrainHeight-1); j++)
{
for(i=0; i<(m_terrainWidth-1); i++)
{
// Get the indexes to the four points of the quad.
index1 = (m_terrainWidth * j) + i; // Upper left.
index2 = (m_terrainWidth * j) + (i+1); // Upper right.
index3 = (m_terrainWidth * (j+1)) + i; // Bottom left.
index4 = (m_terrainWidth * (j+1)) + (i+1); // Bottom right.

// Now create two triangles for that quad.
// Triangle 1 - Upper left.
m_terrainModel[index].x = m_heightMap[index1].x;
m_terrainModel[index].y = m_heightMap[index1].y;
m_terrainModel[index].z = m_heightMap[index1].z;
m_terrainModel[index].tu = 0.0f;
m_terrainModel[index].tv = 0.0f;
index++;

// Triangle 1 - Upper right.
m_terrainModel[index].x = m_heightMap[index2].x;
m_terrainModel[index].y = m_heightMap[index2].y;
m_terrainModel[index].z = m_heightMap[index2].z;
m_terrainModel[index].tu = 1.0f;
m_terrainModel[index].tv = 0.0f;
index++;

// Triangle 1 - Bottom left.
m_terrainModel[index].x = m_heightMap[index3].x;
m_terrainModel[index].y = m_heightMap[index3].y;
m_terrainModel[index].z = m_heightMap[index3].z;
m_terrainModel[index].tu = 0.0f;
m_terrainModel[index].tv = 1.0f;
index++;

// Triangle 2 - Bottom left.
m_terrainModel[index].x = m_heightMap[index3].x;
m_terrainModel[index].y = m_heightMap[index3].y;
m_terrainModel[index].z = m_heightMap[index3].z;
m_terrainModel[index].tu = 0.0f;
m_terrainModel[index].tv = 1.0f;
index++;

// Triangle 2 - Upper right.
m_terrainModel[index].x = m_heightMap[index2].x;
m_terrainModel[index].y = m_heightMap[index2].y;
m_terrainModel[index].z = m_heightMap[index2].z;
m_terrainModel[index].tu = 1.0f;
m_terrainModel[index].tv = 0.0f;
index++;

// Triangle 2 - Bottom right.
m_terrainModel[index].x = m_heightMap[index4].x;
m_terrainModel[index].y = m_heightMap[index4].y;
m_terrainModel[index].z = m_heightMap[index4].z;
m_terrainModel[index].tu = 1.0f;
m_terrainModel[index].tv = 1.0f;
index++;
}
}

  之后,我们需要一个 TextureManagerClass 类来管理我们的纹理,其声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
////////////////////////////////////////////////////////////////////////////////
// Class name: TextureManagerClass
////////////////////////////////////////////////////////////////////////////////
class TextureManagerClass
{
public:
TextureManagerClass();
TextureManagerClass(const TextureManagerClass&);
~TextureManagerClass();

bool Initialize(int);
void Shutdown();

bool LoadTexture(ID3D11Device*, ID3D11DeviceContext*, char*, int);

ID3D11ShaderResourceView* GetTexture(int);

private:
TextureClass* m_TextureArray;
int m_textureCount;
};

  最后,我们替换 ZoneClass 中的渲染方法为纹理渲染:

1
2
3
// Render the terrain grid using the texture shader.
m_Terrain->Render(Direct3D->GetDeviceContext());
result = ShaderManager->RenderTextureShader(Direct3D->GetDeviceContext(), m_Terrain->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix , TextureManager->GetTexture(0));

  最终效果如下:

2

  源代码:DX11TerrainTutorial-TerrainTexturing

0%