游戏设计之基于高程图的三维地形绘制

2015年完成的游戏设计课程大型实验论文(基础应用) —— 引用请联系博主

一、概述

地形绘制是室外三维游戏中必须面对的问题。三维真实感地形是虚拟场景中的基础部分,利用Visual C++,以通用的标准三维图形函数库OpenGL为工具,通过在位图的灰度值地形高程数据之间建立相应的映射关系,建立标准的地形高程数据组,并依托OpenGL平台快速建立生成三维网格地形,然后经过纹理贴图形成真实感较强的三维可视化地形图

二、如何实现高程图转化为三维地形模型

地理科学中使用等高线的方式描述山地,如果按照一定横切面将山体切成若干份,每份投影集中起来就形成了等高线图。

在计算机科学中,则以位图方式(高度图通常保存为RAW格式,它简单地将8位灰度按照先先“X”再“Y”的顺序记录下来,不需要任何头文件)展现山体,黑白色的深浅(灰度)即代表了山势的高低,白色为最高,黑色为最低[1]。

地形模型是整个地形实时显示的核心内容,地形模型主要是基于数字高程模型(DEM)建立起来。目前的DEM的表达形式中最主要的两种:不规则三角形(TIN)和规则格网(GRID)[2]。而三角形是最为最小图形单元,所以三维地形的建模就是将DEM数据进行网格化处理,每一个网格用三角形面片绘制出来,就可以构成高低起伏的曲面图形。

地形的基础三角网格(此处设置的三角形面片边长较大,面片越小,纹理越细腻)

 

1. 将P2.raw的高程图以只读方式存入数组。

pFile = fopen( strName, "rb" );// 以只读/二进制模式打开文件
fread( pHeightMap, 1, nSize, pFile );// 将数据读出到数据队列中
LoadRawFile("p2.raw", MAP_SIZE * MAP_SIZE, g_HeightMap);

2. 初始化地形大小以及网格间距,计算第一步位图的高度与宽度,以及地形水平垂直网格数。如果位图图像的宽或高有冗余(位图高度、宽度不是给定网格的整数倍[3]),剪裁掉并重新计算实际的位图图像宽和高。建立位图的灰度值与地形高程的先行映射关系。根据点坐标找出高度值存入数组。完成高程图到三维模型的转化。

#define MAP_SIZE		512		// p2.raw高程映射文件的大小
#define STEP_SIZE		16		// 每个三角形网格的宽度和高度
#define HEIGHT_RATIO	1.5f		
---------------------------------------------------------------
int Height(BYTE *pHeightMap, int X, int Y)
{
    // 确保x,y没有超过数组大小
	int x = X % MAP_SIZE;
	int y = Y % MAP_SIZE;

	if(!pHeightMap) return 0;	// 确保高程数据存在

	// 获取高程值
	return pHeightMap[x + (y * MAP_SIZE)];	
}

三、三维地形的绘制与纹理映射(Draw & Mapping)

通过高程图建立三维模型之后根据高程图得到的坐标数据,通过循环绘制对应坐标的三角形面片完成每一个坐标的对应三维线状图像。

同时在绘制三角形面片的同时绑定纹理,即在绘制网格线的同时,纹理也已经完成了坐标定位,在Init.cpp函数中实现纹理图像的处理以及纹理的绘制方式。

应用高度图后的地形网格

关键代码段

=================三角面片绘制,高程图转三维模型图的代码段=================

glBegin( GL_TRIANGLE_STRIP );			
    for ( X = 0; X <= MAP_SIZE; X += STEP_SIZE )// 遍历高程数据中所有行
    {
        for ( Y = MAP_SIZE; Y >= 0; Y -= STEP_SIZE )//  遍历所有列
        {	// 获得高程值		
            x = X;							
            y = Height(pHeightMap, X, Y );	
            z = Y;							
            // 设置当前的纹理坐标
            SetTextureCoord( (float)x, (float)z );
            glVertex3i(x, y, z);		
            // 获得高程值		
            x = X + STEP_SIZE; 
            y = Height(pHeightMap, X + STEP_SIZE, Y ); 
            z = Y;
            // 设置当前的纹理坐标
            SetTextureCoord( (float)x, (float)z );
            glVertex3i(x, y, z);			
        }
    }
// 绘制完成
glEnd();
====================纹理映射绑定代码=========================
CreateTexture(g_Texture[0],"p2.bmp");
glBindTexture(GL_TEXTURE_2D, g_Texture[0]);

绘制原理:

通过循环绘制,每一次循环绘制出两个三角形面片构成一组正方形(如图3),通过判断渲染面的方法实现地形的顺序绘制,其顺序如图4所示,每次循环bSwitchSides的数值即会改变。

图三 地形绘制主要过程(一)
图四 地形绘制主要过程(二)

纹理绑定有一个优点就是可以实现三维地形图的纹理映射之后的纹理映射线框图(图五)与纹理映射图(图六),使用函数通过鼠标控制可以实现两图的转换。

// 纹理模式

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

 // 线框模式

glPolygonMode(GL_FRONT_AND_BACK,  GL_LINE);

 

 

图5  纹理映射线框图

                     

图6  纹理映射图

 

四、总结

在做地形图的开始阶段,出现很多问题。由于平时的作业只是涉及简单的平面图形、绘制简单的立方体,再加上简单的灯光、纹理映射、旋转移动等等,同时对使用OpenGL的函数也是一知半解,因此基于高程图绘制地形图是一次很大的挑战。所以在实现之前查找了许多文献资料,慢慢的理解地形图的基本原理,也收获了一些编程方面的信息。在这个过程有很多的收获,不但了解了OpenGL在三维绘制方面的强大,也对图形处理有了更深的理解和兴趣,很幸运选了这门课,发现了一个不同的编程世界,同时也谢谢老师的指导和帮助,在程序员的路上又有了一个小进步。

参考文献

[1]  李大雨,刘新文,汪新兵,谢方明.三维可视化地形图的设计与实现[M]. 四川:兵工自动化编辑部,2009:11.

[2]  高武俊,张继贤,沈涛.OpenGL环境下地形三维景观模型的实现及应用[M]. 北京:中国测绘科学研究所,2002.

[3]  宋  利,何明一,基于位图的三维地形速绘算法及其OpenGL编程[M]. 计算机仿真,2009(2).

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值