Windows 8 Directx 开发学习笔记(五)山峰河谷模型的简单实现
2012-11-06 14:07
841 查看
通过之前对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,定义常量和颜色如下:
接着创建一个xRange*zRange大小的数组存储顶点信息。生成顶点坐标时,从原点开始按行扫描,获得xz坐标后代入上面的公式计算出y坐标。然后根据y坐标进行判断,不同的高度值对应的不同颜色,模拟山峰效果。
然后就是创建索引数组。每个正方形由两个三角形组成,所以索引数组的大小为3*2*(xRange-1)*(zRange-1)。与上面生成顶点相同,生成索引时也从原点开始,不过每次存储的是两个三角形的顶点序号。
模型生成后还有工作要做,因为生成的模型比正方体大很多,为了显示模型全貌,需要调整可视距离。将CreateWindowSizeDependentResources中XMMatrixPerspectiveFovRH方法的参数由100.0f改成1000.0f。
另外,在Update方法中,摄像机的位置和焦点也要调整,而且这次不需要模型随时间旋转,所以固定旋转角度为0度,代码如下。
按F5运行查看效果,如图3。
静态的模型看上去没什么感觉,可以通过移动摄像机的位置,简单模拟飞过整个区域的效果,这样感觉好些。只需要添加一个随时间变化的变量flyPos来更新摄像机的位置,焦点坐标同时改变是为了保持视线方向不变。
虽然只是一个简单粗糙的山峰河谷模型实现,在编写过程中还是遇到点问题,尤其是寻找一个合适的摄像机位置和焦点。不过通过实现这个模型,对DirectX的三维空间和工作原理有了更深的体会。
程序显示一个类似山峰河谷的模型,只要将正方体的数据替换成模型数据即可。在不改变示例程序其他部分的前提下,要提供的模型数据只需包括顶点坐标和颜色,索引数组两部分,其中最重要的部分就是顶点坐标的生成。
在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 开发学习笔记(十五)使用Billboard实现树木贴图
- 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 开发学习笔记(三)摄像机设置及控制正方体旋转
- Android开发学习笔记一:Android启动界面的简单实现
- Flask-RESTful接口开发学习笔记一:实现简单的GET请求
- Windows 8 Directx 开发学习笔记(四)示例程序小结
- 学习笔记——基本光照模型简单实现
- Android(java)学习笔记218:开发一个多界面的应用程序之人品计算器的简单实现
- Windows 8 Directx 开发学习笔记(十一)地形纹理贴图
- Flask-RESTful接口开发学习笔记一:实现简单的GET请求
- Android开发学习笔记(六):最简单的办法实现APP欢迎界面
- 【Unity3D游戏开发学习笔记】(七)上帝之眼—第三人称摄像机的简单实现(跟随视角,自由视角)