在上文中,讲述了PyOpenGL的基本配置,以及网格,球形的生成,以及基本的漫游。现在利用上一篇的内容,来利用高程图实现一个基本的地形,并且,利用上文中的第三人称漫游,以小球为视角,来在地形上前后左右漫游,能实时检测高度。下面先看下效果图:
二张图,球分别在不同的地方,不同的显示模型,一个是全填充的,一个是线连,可以从中看到一些基本的思路。大致过程分别如下,首先拿到一张高度图,检索其中的高度对应的通道的值,然后用来改变网格的高度。这个过程只需要在初始化时生成就行了,所以我们可以简单的用CPU来完成这个。然后是球体的漫游,这部分在上文中已经讲了第一与第三人称漫游,用的就是其中的第三人称作漫游,在这里,我们主要是要检索球下面的地形的高度,因为需要实时计算,这部分用GPU来完成。
我们先看下,根据高度图来改变网格高度的相关代码(请对照前文中的网格类Plane来看,下面的setHeight为其中的一个方法):
1 def setHeight(this,image): 2 ix = image.size[0] 3 iy = image.size[1] 4 this.heightImage = image 5 print ix,iy 6 #print "xr,yr",this.xr,this.yr 7 lerp = lambda a,b,d:a * d + b * (1.0 - d) 8 fade = lambda t : t*t*(3.0-2.0*t) #t*t*t*(t*(t*6.0-15.0)+10.0) 9 for y in range(this.yr): 10 for x in range(this.xr): 11 index = 5 * (this.xr * y + x) + 3 12 #print index 13 fx = float(x) / float(this.xr - 1) * float(ix - 1) 14 fy = float(y) / float(this.yr - 1) * float(iy - 1) 15 #print float(x) / float(this.xr - 1),fx,float(y) / float(this.yr - 1),fy 16 xl,xr,yu,yd = int(math.floor(fx)),int(math.ceil(fx)),int(math.floor(fy)),int(math.ceil(fy)) 17 dx,dy = fade(fx - xl),fade(fy - yu) 18 #print "loc:",xl,xr,yu,yd,dx,dy 19 #left up,right up,left down,right down 20 lu,ru,ld,rd = image.im[ix * yu + xl],image.im[ix * yu + xr],image.im[ix * yd + xl],image.im[ix * yd + xr] 21 #print ix * yu + xl,lu,ru,ld,rd 22 hight = lerp(lerp(lu,ru,dx),lerp(ld,rd,dx),dy) 23 this.data[index] = hight / 255.0 24 #print "setHeight:",hight / 255.0