import sys, Image from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * viewRotZ = 0 viewRotX = 0 import random def makeHeightField(level): 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(): hf = makeHeightField(6) size = len(hf) dl = glGenLists(1) glNewList(dl, GL_COMPILE) glTranslatef(-size/2.0, -size/2.0, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) for i in range(0,size-1): glBegin(GL_TRIANGLE_STRIP) for j in range(0,size): glVertex3f(i,j,hf[i][j]) glVertex3f(i+1,j,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() def keyboard(key, x, y): if key == chr(27): sys.exit(0) 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() glutMainLoop()