您的位置:首页 > 大数据 > 人工智能

Terrain maps

2015-09-12 21:08 288 查看
《introduce to 3D Game Programming》 Chapter 13 Terrain reading nodes

-----------------------------------------------------------------------------------------------------------------------------------------------

灰度图: 用来表示地形高度

heightmap is an array where each element specifies the height of a particular vertex in the terrain grid

allocate a byte of memory for each element in heightmap.

loading a RAW File

定义vector<byte>,这样值就在[0,255]灰度范围之内

bool Terrain::readRawFile(std::string fileName)
{
// Restriction: RAW file dimensions must be >= to the
// dimensions of the terrain.  That is a 128x128 RAW file
// can only be used with a terrain constructed with at most
// 128x128 vertices.
// A height for each vertex
std::vector<BYTE> in( _numVertices );
std::ifstream inFile(fileName.c_str(), std::ios_base::binary);
if( inFile == 0 )
return false;
inFile.read(
(char*)&in[0], // buffer
in.size());// number of bytes to read into buffer
inFile.close();
// copy BYTE vector to int vector
_heightmap.resize( _numVertices );
for(int i = 0; i < in.size(); i++)
_heightmap[i] = in[i];
return true;
}


Accessing and modifying the heightmap

Terrain::getHeightmapEntry

Terrain:: setHeightmapEntry

Generating the terrain geometry

地形大小的定义,通过行,列, 以及行列中单元格子的大小 3个元素来确定

define the size of our terrain by specifying the number of vertices per row, the number of vertices per column,

and the cell spacing.

_width = _numCellsPerRow * _cellSPacing;

_depth = _numCellsPerCol * _cellSPacing;



Computing the Vertices

begin generating vertices at start and then to row by row generating vertices until we reach end.

the y-coordinate is easily obtained by finding the corresponding entry in the loaded heightmap data structure

(u,v) texture coordinate that corresponds to the terrain vertex at (i,j) is given by:

根据i,j 乘以 cellSpacing,可以获取顶点在UV坐标系中的坐标

u = j . uCoordIncrementSize

v = i. vCoordIncrementSize

Terrain::Terrain(IDirect3DDevice9* device,
std::string heightmapFileName,
int numVertsPerRow,
int numVertsPerCol,
int cellSpacing,
float heightScale)
{
_device         = device;
_numVertsPerRow = numVertsPerRow;
_numVertsPerCol = numVertsPerCol;
_cellSpacing    = cellSpacing;

_numCellsPerRow = _numVertsPerRow - 1;
_numCellsPerCol = _numVertsPerCol - 1;

_width = _numCellsPerRow * _cellSpacing;
_depth = _numCellsPerCol * _cellSpacing;

_numVertices  = _numVertsPerRow * _numVertsPerCol;
_numTriangles = _numCellsPerRow * _numCellsPerCol * 2;

_heightScale = heightScale;


Computing the Indices-Defining the Triangles

to compute the indices of the triangle grid, we simply iterate through each quad, starting in the upper left and ending

in the lower right of Figure 13.4, and compute the two triangles that make up that quad.

从左上到右下方向使用迭代的方法,计算三角形面片的顶点。



Texturing

the Terrain class provides two ways to texture the terrain. The obvious way is to simply load a previously made textrue

file and use that. The following method implemented by the Terrain class loads a texture form the file into the _tex

data member, which is a pointer to an IDirect3DTexture9 interface. internally, the Terrain:: draw method sets _tex before

rendering the terrain.

load 已有的纹理

bool Terrain::loadTexture(std::string fileName)
{
HRESULT hr = 0;

hr = D3DXCreateTextureFromFile(
_device,
fileName.c_str(),
&_tex);

if(FAILED(hr))
return false;

return true;
}

Lighting

Terrain::genTexture method makes a calll to Rerrain:: lightTerrain that, as the name implies, lights the terrain to enhance

the realism. Since we already computed the colors of the terrain texture, we only need to compute a shade factor that brightens

or darkens areas of the rerrain with respect to a defined light source.

as angles get larger, the quad faces more and more away from the light source, thus receiving less light. notice that once

the angle between the light vector and the normal is greater then 90 degrees, the surface receives no light.

使用Rerrain:: lightTerrain, 因为纹理已经给地形加的颜色,我们只需通过计算光线和法线的夹角来确定地形的亮度。

Computing the shade of a Quad

the direction to the light source is given as a normalized vector that we call L in this discussion. in order to calculate the

angle between L and the quad’s normal vector N, we first need to find N,

计算法线:即是计算两个向量的叉乘



Shading the Terrain

simply iterate through each quad, compute the shade value of that quad, and then scale the quad’s corresponding

texel color by that shade.

Walking on the Terain

move the camera so that it simulates us walking on the terrain. That is ,we need to adjust the camera’s height(y-coordinate)

depending on the part of the terrain that we are standing on.In order to do this we first need to find the cell we are in given

the x- and z-coordinates of the camera’s position. The Terrain:: gerHeight function does this; it takes the camera’s x- and z-corrdinates

as parameters and returns the height the camera needs to be set to in order for it to be on the terrain.

通过移动相机来模拟行走在地图上面。即通过调整相机的高度来随地形起伏变化。首先找到摄像机的位置,然后即可获取高度Terrain:: gerHeight



if we are in the “upper” triangle,. otherwise, we are in the “lower” triangle

to find the height if we are in the “upper” triangle, we construct 2 vectors, u = (cellSpacing, B-A,0) andv = (0,C-A,-cellSpacing)

q = (qx ,A, qz) , 沿向量u方向做线性插值得到dx,同理得到dz,这样高度 y 向量为(q+dxu+dzv
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: