看了OpenGL编3D游戏_CAI,里面的那个A05_开天辟地的例子不大明白,地图的那个部分
void baiscobj::InitTerrain(float h) //初始地形
{ int index = 0;
int Vertex;
for (int z = 0; z < MAP_W; z++)
for (int x = 0; x < MAP_W; x++)
{ Vertex = z * MAP_W + x;
g_terrain [Vertex][0] = float(x)*MAP_SCALE;
g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3);
g_terrain [Vertex][2] = -float(z)*MAP_SCALE;
g_texcoord[Vertex][0] = (float) x;
g_texcoord[Vertex][1] = (float) z;
g_index [index++] = Vertex;
g_index [index++] = Vertex+ MAP_W;
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer (3,GL_FLOAT,0,g_terrain);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer (2,GL_FLOAT,0,g_texcoord);
}
void baiscobj::DrawSand()
{ glBindTexture(GL_TEXTURE_2D, g_cactus[0]);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
for (int z = 0; z < MAP_W-1; z++)
glDrawElements(GL_TRIANGLE_STRIP,MAP_W*2,GL_UNSIGNED_INT,&g_index[z*MAP_W*2]);
}
float baiscobj::GetHeight(float x, float z) //获取高度
{ float CameraX = x/MAP_SCALE;
float CameraZ =-z/MAP_SCALE;
int Col0 = int(CameraX);
int Row0 = int(CameraZ);
int Col1 = Col0 + 1;
int Row1 = Row0 + 1;
if (Col1 > MAP_W) Col1 = 0;
if (Row1 > MAP_W) Row1 = 0;
float h00=g_terrain[Col0 + Row0*MAP_W][1];
float h01=g_terrain[Col1 + Row0*MAP_W][1];
float h11=g_terrain[Col1 + Row1*MAP_W][1];
float h10=g_terrain[Col0 + Row1*MAP_W][1];
float tx =CameraX - int(CameraX);
float ty =CameraZ - int(CameraZ);
float txty = tx * ty;
return h00*(1.0f-ty-tx+txty)
+ h01*(tx-txty)
+ h11*txty
+ h10*(ty-txty);
}
有朋友能详细解释一下吗,看了好久,没看明白,
解决方案 »
- 如何判断一个路径的有效性?
- 郁闷的error LNK2001: unresolved external symbol,请大家帮忙..
- 谁送几本书给我
- 在线请教,创建200个线程后,如何等待和判断线程是否完成?
- Windows下进程间通信有那些比较常用的方法,谁有经验请告诉我?
- 用VC到底怎么编写可共享的类库阿,我烦透了,解答者有高分相送!
- 【求助】TeeChart控件AddArray函数绘图中,横坐标轴显示时间问题
- 怎么读取.ini文件
- MFC ADO写access数据库,代码出错
- 用Matlab的Simulink做的建模仿真,需要做一界面,用什么做最好?
- VC++ Edit控件获得键盘消息的问题
- VC6.0+Office
{
int index = 0;
int Vertex;
for (int z = 0; z < MAP_W; z++)
for (int x = 0; x < MAP_W; x++)
{ Vertex = z * MAP_W + x;
g_terrain [Vertex][0] = float(x)*MAP_SCALE;
g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3);
g_terrain [Vertex][2] = -float(z)*MAP_SCALE;
g_texcoord[Vertex][0] = (float) x;
g_texcoord[Vertex][1] = (float) z;
g_index [index++] = Vertex;
g_index [index++] = Vertex+ MAP_W;
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer (3,GL_FLOAT,0,g_terrain);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer (2,GL_FLOAT,0,g_texcoord);
} void baiscobj::DrawSand()
{ glBindTexture(GL_TEXTURE_2D, g_cactus[0]);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
for (int z = 0; z < MAP_W-1; z++)
glDrawElements(GL_TRIANGLE_STRIP,MAP_W*2,GL_UNSIGNED_INT,&g_index[z*MAP_W*2]);
}
float baiscobj::GetHeight(float x, float z) //获取高度
{ float CameraX = x/MAP_SCALE;
float CameraZ =-z/MAP_SCALE;
int Col0 = int(CameraX);
int Row0 = int(CameraZ);
int Col1 = Col0 + 1;
int Row1 = Row0 + 1;
if (Col1 > MAP_W) Col1 = 0;
if (Row1 > MAP_W) Row1 = 0;
float h00=g_terrain[Col0 + Row0*MAP_W][1];
float h01=g_terrain[Col1 + Row0*MAP_W][1];
float h11=g_terrain[Col1 + Row1*MAP_W][1];
float h10=g_terrain[Col0 + Row1*MAP_W][1];
float tx =CameraX - int(CameraX);
float ty =CameraZ - int(CameraZ);
float txty = tx * ty;
return h00*(1.0f-ty-tx+txty) + h01*(tx-txty) + h11*txty + h10*(ty-txty);
} 把代码调整了一下,衷心向各位请教
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer (3,GL_FLOAT,0,g_terrain);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer (2,GL_FLOAT,0,g_texcoord);
这几句启用了顶点数组,包括坐标和纹理,并指定了顶点数组,分别是g_terrain和g_texcoord
glDrawElements(GL_TRIANGLE_STRIP,MAP_W*2,GL_UNSIGNED_INT,&g_index[z*MAP_W*2])这一句进行渲染,注意它最后一个参数是g_index,表示顶点的索引。g_terrain [Vertex][0] = float(x)*MAP_SCALE;
g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3);
g_terrain [Vertex][2] = -float(z)*MAP_SCALE;
这三句是构造地形,g_terrain [Vertex][1] 表示的是地面的高度。GetHeight(float x, float z)这个函数是获取指定地点的高度,
h00*(1.0f-ty-tx+txty) + h01*(tx-txty) + h11*txty + h10*(ty-txty)是进行双线性插值,这样即便X,Z不是三角形顶点也可以得到高度值。
g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3); //这个高度值是怎么获得的,尤其是这句话(z*MAP_W+x)*3],能解释下么?另外 建立g_index存放顶点索引有什么作用吗?什么是双线性插值?
{V0,V1,V2,V3....,V7},而立方体的六个面可以用顶点的索引号来组成,比如说假设上表面由V0,V1,V2,V3这四个点组成,下表面由V4,V5,V6,V7组成,则上表面可以用数组{0,1,2,3}表示,下表面用(4,5,6,7}表示,索引数组中元素分别表示对应点在顶点数组中的索引号,由于三维坐标数据比较大,用索引数组只需构造指向数据的索引,节省了空间。对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v),其中i、j均为非负整数,u、v为[0,1)区间的浮点数,则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:
f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
其中f(i,j)表示源图像(i,j)处的的像素值,以此类推
这就是双线性内插值法。
这里使用的地图是bmp格式的,所以有三个分量,作者只选择了第一个分量值作为地图高度,也就是g_imageData[(z*MAP_W+x)*3],其实也可以选择另外的分量:g_imageData[(z*MAP_W+x)*3+1]或者g_imageData[(z*MAP_W+x)*3+2]至于为什么要除以3,你可以看看这个函数有个参数float h,所以我认为作者本来是要除以h的,从而通过参数控制地形高度,也就是:g_imageData[(z*MAP_W+x)*3]/h对于获取指定坐标的高度GetHeight函数,我也在研究,希望有高手指教!