OpenGL游戏引擎开发[7]-生成南京地形图

获取南京地形高度图数据

上节我们自己生成另一个平面地形,这节我们生成一个带有真实地形高度的【南京玄武区】的地形图。

如果大家玩过《城市天际线》的画,都知道游戏里面可以导入现实世界真实的地图的。其官网提供了一个工具:

http://terrain.party/

这是一个使用openlayers地图库制作的一个在线生成真实世界地形高度图的工具,我们在上面找到想要生成高度图的区域,就可以使用右侧的工具栏下载按钮进行下载。

下载下来一个压缩包:

里面有文件的说明信息,请自行查看。这里我们使用融合过的高度图【nanjing Height Map (Merged).png】

接着,将之前生成平面网格时赋予每个顶点高度为0的代码,改成从高度图中读取高度数据。

因为高度图是一个灰度图,里面的像素值的范围是(0,255)。这里需要根据自己的需求来使用这个高度值。比如:有的区域比较平坦,一张高度图中的像素值可能都集中在125左右,那么你绘制出来地形的高度起伏并不是很明显,特别是地形图很大的时候(也就是上节说的生成地形时SIZE设置很大时)。如果有的区域,地形的起伏刚好较为均匀,地形图的像素值在(0,255)分布较为均匀,直接使用像素值作为OpenGL中顶点的y值,那么效果可能也会不错。

总之,数据是死的, 人是活的。怎么使用数据,取决于你最终想要的效果。

"计算机图形学中,只要你看起来是对的,那就是对的。" --忘了哪本书上讲的。

处理高度数据

首先,我们先直接使用像素值来作为要绘制的高度来看看效果怎么样。

我们这里使用的是PNG图片,有RGBA四个通道组成。

因为是灰度图,所以 R=G=B (常识),这里我们没有使用到透明度通道,因为这里没有物体的混合嘛。

我们随便取R通道作为来代表该点实际的高度值。

Java中使用 BufferedImage.getRGB() 返回一个int

Java中int占4个字节,刚好每个字节(占8bit)存储一个像素值,看下图:

那么如果要获取R的像素值,就需要对返回的int进行右移16位,再使用0xFF(1个字节=8bit)进行与运算,这样就能得到R的像素值。 这个不难理解吧。

A通道、G通道和B通道的值获取以此类推,只不过这里没用到。

那么我们直接将R的值返回,看看绘制的地形图是什么样的。

好像还不错, 我们使用归一化的方法来看看效果。

BufferedImage.getRGB()返回的int的范围是[-256*256*256,+256*256*256],也就是我们这里定义的 MAX_PIXCEL_COLOR

因为int我们只用到了后面3个字节(RGB),第一个字节(表达A通道),这里我们没用到。后3个字节全为1时(也就是 MAX_PIXCEL_COLOR )该int绝对值值最大。

那么任取 h 属于 [-MAX_PIXCEL_COLOR,MAX_PIXCEL_COLOR]

h += MAX_PIXCEL_COLOR

h的范围变成 [ 0, 2 * MAX_PIXCEL_COLOR]

然后, h /= 2 * MAX_PIXCEL_COLOR

那么,h的范围编程 [ 0, 1],这样h就归一化为 [0,1]范围内了。

最后,乘以 我们定义的地形的最大高度 MAX_HEIGHT 来进行绘制。

好像也差不多,大家可以根据实际情况,不一定要将高度值归一化到[0,1]之间,归一化到 [1/4, 3/4]范围内也是可以的嘛。

OK,本节结束。

欢迎大家关注我的公众号【OpenGL编程】。

每天进步一点点,探索3D编程背后的技术细节,不再做只会“调包”的傻小白。以幽默风趣的行文风格,近乎白话文的专业知识讲解,分享3D编程的心得、教程、算法,带你走进3D编程的世界。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值