bool TerrainDemo::ReadRawFile(std::string filePath)
{
std::ifstream inFile;
inFile.open(filePath.c_str(), std::ios::binary);
inFile.seekg(0, std::ios::end);
std::vector<BYTE> inData(inFile.tellg());
inFile.seekg(std::ios::beg);
inFile.read((char*)&inData[0], inData.size());
inFile.close();
m_heightInfos.resize(inData.size());
for (unsigned int i = 0; i < inData.size(); ++i)
{
m_heightInfos[i] = inData[i];
}
return true;
}
bool TerrainDemo::InitTerrain(float width, float height, UINT m, UINT n, float scale)
{
m_cellsPerRow = m;
m_cellsPerCol = n;
m_verticesPerRow = m + 1;
m_verticesPerCol = n + 1;
m_numsVertices = m_verticesPerRow*m_verticesPerCol;
m_width = width;
m_height = height;
m_heightScale = scale;
for (auto& item : m_heightInfos)
{
item *= m_heightScale;
}
float oX = -width * 0.5f;
float oZ = height * 0.5f;
//每一格坐标变化
float dx = width / m;
float dz = height / n;
m_vertices.resize(m_numsVertices);
for (UINT i = 0; i < m_verticesPerCol; ++i)
{
float tempZ = oZ - dz * i;
for (UINT j = 0; j < m_verticesPerRow; ++j)
{
UINT index = m_verticesPerRow * i + j;
m_vertices[index].Pos.x = oX + dx * j;
m_vertices[index].Pos.y = m_heightInfos[index];
m_vertices[index].Pos.z = tempZ;
m_vertices[index].TexC = XMFLOAT2(dx*i, dx*j);
}
}
UINT nIndices = m * n * 6;
m_indices.resize(nIndices);
UINT tmp = 0;
for (UINT i = 0; i < n; ++i)
{
for (UINT j = 0; j < m; ++j)
{
m_indices[tmp] = i * m_verticesPerRow + j;
m_indices[tmp + 1] = i * m_verticesPerRow + j + 1;
m_indices[tmp + 2] = (i + 1) * m_verticesPerRow + j;
XMFLOAT3 temp;
ComputeNomal(m_vertices[m_indices[tmp]], m_vertices[m_indices[tmp + 1]],
m_vertices[m_indices[tmp + 2]], temp);
m_vertices[m_indices[tmp]].Normal = temp;
m_vertices[m_indices[tmp + 1]].Normal = temp;
m_vertices[m_indices[tmp + 2]].Normal = temp;
m_indices[tmp + 3] = i * m_verticesPerRow + j + 1;
m_indices[tmp + 4] = (i + 1) * m_verticesPerRow + j + 1;
m_indices[tmp + 5] = (i + 1) * m_verticesPerRow + j;
ComputeNomal(m_vertices[m_indices[tmp + 3]], m_vertices[m_indices[tmp + 4]],
m_vertices[m_indices[tmp + 5]], temp);
m_vertices[m_indices[tmp + 3]].Normal = temp;
m_vertices[m_indices[tmp + 4]].Normal = temp;
m_vertices[m_indices[tmp + 5]].Normal = temp;
tmp += 6;
}
}
return true;
}
void TerrainDemo::ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal)
{
XMFLOAT3 f1(v2.Pos.x - v1.Pos.x, v2.Pos.y - v1.Pos.y, v2.Pos.z - v1.Pos.z);
XMFLOAT3 f2(v3.Pos.x - v1.Pos.x, v3.Pos.y - v1.Pos.y, v3.Pos.z - v1.Pos.z);
XMVECTOR vec1 = XMLoadFloat3(&f1);
XMVECTOR vec2 = XMLoadFloat3(&f2);
XMVECTOR temp = XMVector3Normalize(XMVector3Cross(vec1, vec2));
XMStoreFloat3(&normal, temp);
}
作为图片,我通过分析高度图来渲染地形,但只使用一个纹理。图中不同的高度代表不同的地形,如道路,草地,水等。如何使用不同的纹理来渲染不同的地形?我必须计算地形不同部分的顶点和索引吗? 有些部分是不规则的,如何计算它们的索引?在着色器中执行此操作是否可以,以及如何操作?