import sys, Image from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * viewRotZ = 0 viewRotX = 0 import random seed = 0 if len(sys.argv) > 1: seed = int(sys.argv[1]) def makeHeightField(level): random.seed(seed) size = 2**level + 1 h = [[0]*size for _ in range(0,size)] displacement = 4.0 for l in range(level-1, -1, -1): step = 2**l for i in range(0, size, step*2): for j in range(step, size, step*2): h[i][j] = (h[i][j-step]+h[i][j+step])/2.0 + random.gauss(0,displacement) for i in range(step, size, step*2): for j in range(0, size, step*2): h[i][j] = (h[i-step][j]+h[i+step][j])/2.0 + random.gauss(0,displacement) for i in range(step, size, step*2): for j in range(step, size, step*2): h[i][j] = (h[i-step][j]+h[i+step][j]+h[i][j-step]+h[i][j+step])/4.0 + random.gauss(0,displacement) displacement /= 1.8 return h def makeTerrain(level): hf = makeHeightField(level) size = len(hf) dl = glGenLists(1) glNewList(dl, GL_COMPILE) glTranslatef(-16, -16, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) scale = 32 / (size-1.0) for i in range(0,size): for j in range(0,size): if hf[i][j] < 0: hf[i][j] = -0.01 for i in range(0,size-1): glBegin(GL_TRIANGLE_STRIP) for j in range(0,size): if hf[i][j] >= 0: glColor3f(0.3, 1, 0.2) else: glColor3f(0, 0, 0.8) glVertex3f(i*scale,j*scale,hf[i][j]) if hf[i+1][j] >= 0: glColor3f(0.3, 1, 0.2) else: glColor3f(0, 0, 0.8) glVertex3f((i+1)*scale,j*scale,hf[i+1][j]) glEnd() glEndList() return dl def draw(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(50.0, 1.0, 1.0, 100.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glTranslatef(0.0, 0.0, -30.0) glRotatef(viewRotX, 1.0, 0.0, 0.0) glRotatef(viewRotZ, 0.0, 0.0, 1.0) glCallList(terrain) glutSwapBuffers() level = 0 def keyboard(key, x, y): global level, terrain if key == chr(27): sys.exit(0) elif key == '+': level += 1 terrain = makeTerrain(level) elif key == '-' and level>0: level -= 1 terrain = makeTerrain(level) glutPostRedisplay() def specialkey(key,x,y): global viewRotX, viewRotZ if key == GLUT_KEY_LEFT: viewRotZ = viewRotZ + 3 elif key == GLUT_KEY_RIGHT: viewRotZ = viewRotZ - 3 elif key == GLUT_KEY_UP: viewRotX = viewRotX + 3 elif key == GLUT_KEY_DOWN: viewRotX = viewRotX - 3 glutPostRedisplay() glutInit([]) glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH) glutInitWindowSize(400,400) glutCreateWindow(sys.argv[0]) glutDisplayFunc(draw) glutKeyboardFunc(keyboard) glutSpecialFunc(specialkey) glEnable(GL_DEPTH_TEST) terrain = makeTerrain(level) glutMainLoop()