65.9K
CodeProject 正在变化。 阅读更多。
Home

Managed DirectX 教程:第 7 部分 - 使用高度图

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.40/5 (3投票s)

2006年5月26日

CPOL

3分钟阅读

viewsIcon

63331

这里变得很有趣 - 您将为顶点添加高度值

Sample Image - MDXTut_7.png

什么是高度图以及如何读取它们

在这个(相当短的)教程中,我们将学习高度图,并使用它们为我们的顶点添加不同的高度级别,以创建逼真的地形。

什么是高度图?

高度图是游戏程序员用来读取高度数据的文件。
在形式上,它们是一个图像文件,通常具有与游戏世界中顶点数量一样多的像素。

它们只有灰度颜色。 程序将此高度图加载到内存中,并测试每个像素的颜色值。 如果它是纯白色 (255),那么该像素位置的顶点的高度将是最高的(通常将 255 按比例缩小一个因子),而如果是黑色,则它位于最低位置。

为简单起见,高度图通常以 .RAW 文件格式保存。
这是一种仅存储像素数据,而没有任何压缩或其他任何内容的图像格式。

这些可以在图像编辑器(例如 Adobe Photoshop Elements)中打开,并且工作方式与 bmp 类似。

我们将如何将它应用于我们的地形?

要将高度图应用于我们的地形,我们将简单地修改我们在上一个教程中创建的 SetGrid() 方法,使其接受一个 2D 点数组(我们将应用于 Z 轴),然后创建一个新方法将高度数据加载到其中。

public int[,] heightFromFile(string pFile, int WIDTH, int HEIGHT)
{ 
int[,] HeightData = new int[WIDTH, HEIGHT];
FileStream fs = new FileStream(pFile, FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
int Currheight = new int();for (int i = 0; i < HEIGHT; i++)
for (int y = 0; y < WIDTH; y++)
{
Currheight = (int)(r.ReadByte()/2);
HeightData[WIDTH - 1 - y, HEIGHT - 1 - i] = Currheight;
}
r.Close();
return (HeightData);
}

此方法的前四行只是进行设置。
FileStream 打开程序和特定文件之间的链接(在本例中,是通过参数 pFile 传递的文件),BinaryReader 将自身“附加”到此流,以便它可以真正读取 heightmap 的值。

然后,我们循环遍历文件,读取当前字节值 (ReadByte) 并将其除以 2。这使我们得到一个 255 中的值,然后除法只是为了缩小它(我们不希望我们的地形能够这么高)。
然后,我们将此值分配给相应的 HeightData 元素。
最后,我们关闭文件之间的流并返回 HeightData 数组,现在已完整加载到程序中。

接下来,更改 SetGrid() 方法,使其接受一个名为 heightData 的 2D int 数组,并替换该行

CV[y, x].Z = 0;

CV[y, x].Z = heightData[y, x]; 

最后,我们可以在之前的示例中使用 Form 类的 heightData 成员,并使用我们的新方法加载它。
如果一切顺利,运行示例时,您将拥有高度图地形。 :)
接下来,我们将学习如何在这个地形中移动。

反馈

我总是乐于回答问题,无论是通过 MSN (jamespraveen@aol.com)、电子邮件 (james@magclan.cwhnetworks.com) 还是通过附加到本文的消息板。
如果您对我的任何示例/我的主题有疑问,请随时提问。

历史

  • 26/05/06:发布在 CodeProject 上

之前的文章

© . All rights reserved.