Windows 8 Directx 开发学习笔记(五)山峰河谷模型的简单实现
来源:互联网 发布:安卓神级系统优化脚本 编辑:程序博客网 时间:2024/05/03 08:47
通过之前对DirectX示例程序代码的研究,基本了解DirectX最简单的工作过程,为了更好的理解整个过程,基于示例程序做一个山峰河谷的简单模型。首先还是根据模板创建正方体的示例程序,Visual C++ -〉Windows应用商店 -〉DirectX3D应用程序,如图1。设置好名称后完成创建。
程序显示一个类似山峰河谷的模型,只要将正方体的数据替换成模型数据即可。在不改变示例程序其他部分的前提下,要提供的模型数据只需包括顶点坐标和颜色,索引数组两部分,其中最重要的部分就是顶点坐标的生成。
在DirectX的右手坐标系中,y方向为垂直方向,表示高度,x和z方向定义水平面。DirectX只绘制三角形,如果将山峰河谷模型投影在xz平面,那么xz平面就是由许多三角形组成的网格。假设相邻的两个三角形能构成一个正方形,如图2,顶点的x和z坐标就很容易生成。获得xz坐标之后,将其代入高度计算公式即可算出y。为表现出山峰河谷的效果,不同的高度范围应该有不同的颜色,可以使用条件判断进行设置。
首先找到CubeRenderer.cpp中的CreateDeviceResources方法,删除里面定义正方体顶点的代码。设x和z的变化范围为0-127,间隔均为1,定义常量和颜色如下:
const int xRange = 128;const int zRange = 128;const float dx = 1.0f;const XMFLOAT3 WHITE(1.0f,1.0f, 1.0f);const XMFLOAT3BEACH_SAND(1.0f, 0.96f, 0.62f);const XMFLOAT3LIGHT_YELLOW_GREEN(0.48f, 0.77f, 0.46f);const XMFLOAT3DARK_YELLOW_GREEN(0.1f, 0.48f, 0.19f);const XMFLOAT3DARKBROWN(0.45f, 0.39f, 0.34f);
接着创建一个xRange*zRange大小的数组存储顶点信息。生成顶点坐标时,从原点开始按行扫描,获得xz坐标后代入上面的公式计算出y坐标。然后根据y坐标进行判断,不同的高度值对应的不同颜色,模拟山峰效果。
VertexPositionColorVertices[xRange*zRange]; for(int row=0;row<zRange; ++row){ float zPos = row*dx; for(int col=0;col<xRange; ++col) { float xPos = col*dx; float yPos = 0.3f *(zPos*sinf(0.1f*xPos) + xPos*cosf(0.1*zPos)); Vertices[xRange*row + col].pos = XMFLOAT3(xPos, yPos,zPos); if(yPos <-10.0f) Vertices[xRange*row + col].color =BEACH_SAND; else if (yPos <5.0f) Vertices[xRange*row + col].color =LIGHT_YELLOW_GREEN; else if (yPos <10.0f) Vertices[xRange*row + col].color =DARK_YELLOW_GREEN; else if (yPos <12.0f) Vertices[xRange*row+ col].color = DARKBROWN; else Vertices[xRange*row + col].color =WHITE; }}
然后就是创建索引数组。每个正方形由两个三角形组成,所以索引数组的大小为3*2*(xRange-1)*(zRange-1)。与上面生成顶点相同,生成索引时也从原点开始,不过每次存储的是两个三角形的顶点序号。
unsigned shortIndices[3*2*(xRange-1)*(zRange-1)]; int tempIndice = 0;for(int row=0;row<(zRange-1); ++row){ for(int col=0;col<(xRange-1); ++col) { Indices[tempIndice] = xRange*row + col; Indices[tempIndice+1] = xRange*row +col + 1; Indices[tempIndice+2] = xRange*(row+1)+ col; Indices[tempIndice+3] = xRange*(row+1)+ col; Indices[tempIndice+4] = xRange*row +col + 1; Indices[tempIndice+5] = xRange*(row+1)+ col + 1; tempIndice += 6; }}
模型生成后还有工作要做,因为生成的模型比正方体大很多,为了显示模型全貌,需要调整可视距离。将CreateWindowSizeDependentResources中XMMatrixPerspectiveFovRH方法的参数由100.0f改成1000.0f。
另外,在Update方法中,摄像机的位置和焦点也要调整,而且这次不需要模型随时间旋转,所以固定旋转角度为0度,代码如下。
XMVECTOR eye =XMVectorSet(0, 30.0f, 0, 0.0f);XMVECTOR at =XMVectorSet(50.0f, -0.1f, 50.0f, 0.0f);XMVECTOR up =XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); XMStoreFloat4x4(&m_constantBufferData.view,XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));XMStoreFloat4x4(&m_constantBufferData.model,XMMatrixTranspose(XMMatrixRotationY(0.0f)));
按F5运行查看效果,如图3。
静态的模型看上去没什么感觉,可以通过移动摄像机的位置,简单模拟飞过整个区域的效果,这样感觉好些。只需要添加一个随时间变化的变量flyPos来更新摄像机的位置,焦点坐标同时改变是为了保持视线方向不变。
float flyPos = timeTotal * 5;XMVECTOR eye =XMVectorSet(flyPos, 30.0f, flyPos, 0.0f);XMVECTOR at =XMVectorSet(50.0f + flyPos, -0.1f, 50.0f + flyPos, 0.0f);
虽然只是一个简单粗糙的山峰河谷模型实现,在编写过程中还是遇到点问题,尤其是寻找一个合适的摄像机位置和焦点。不过通过实现这个模型,对DirectX的三维空间和工作原理有了更深的体会。
- Windows 8 Directx 开发学习笔记(五)山峰河谷模型的简单实现
- Windows 8 Directx 开发学习笔记(七)水波纹的实现
- Windows 8 Directx 开发学习笔记(十)纹理贴图实现旋转的木箱
- Windows 8 Directx 开发学习笔记(十二)利用混合实现浮在水面的木箱
- Windows 8 Directx 开发学习笔记(二)建立模型及初始化设备
- Windows 8 Directx 开发学习笔记(六)添加水模型
- Windows 8 Directx 开发学习笔记(九)材质定义及混合光照效果实现
- Windows 8 Directx 开发学习笔记(十三)利用模板实现木箱镜像
- Windows 8 Directx 开发学习笔记(十四)使用几何着色器实现三角形细分
- Windows 8 DirectX 开发学习笔记(十五)使用Billboard实现树木贴图
- Windows 8 Directx 开发学习笔记(八)要有光
- Windows 8 Directx开发学习笔记(一)应用基本框架
- Windows 8 Directx 开发学习笔记(三)摄像机设置及控制正方体旋转
- Windows 8 Directx 开发学习笔记(四)示例程序小结
- Windows 8 Directx 开发学习笔记(十一)地形纹理贴图
- Windows 8 DirectX 开发学习笔记(十六)使用Terragen生成自然环境贴图
- [DirectX游戏开发笔记之二] 最简单的DirectX
- DirectX学习笔记(十四):三维地形系统的实现
- frameset和div常规布局的优缺点比较
- SQL Server创建数据库
- JavaScript Date(日期)对象
- Yii 的登录流程
- seo是搜索引擎的漏洞吗?
- Windows 8 Directx 开发学习笔记(五)山峰河谷模型的简单实现
- JavaScript语言核心04
- 这女的装B要么装处女,装可爱;要么就是走妖娆路线的。
- 详解Objective-C中委托和协议
- 简单调试 Python 程序
- 端口重用 C++ (地址重用)
- Xcode 4.1/4.2/4.2.1 免证书(iDP)开发+真机调试+生成IPA全攻略
- DES加密算法
- web site relate to H.265