import math import random import xml.dom.minidom from pyglet.gl import * from pyglet import image from pyglet.window import key from pyglet import font from util import fetchTextFromFirstElementByTagName as fetchText from util import dataFile spin = 0.0 rotate = 0.0 auto = True class GalacticMap(object): def __init__(self): self.lineColor = (0, 1, 0, 0) self.lineStroke = 1.0 self.resolution = 400 self.rotation = 0 self.spin = 0 self.position = (-13.8, -44.2, 1.0) self.quad = gluNewQuadric() self.starSystems = parseConfigFile('Drahew.xml') self.lines = [] self.starSprites = [] for star in self.starSystems: #name, x, y, z = star #self.starSprites.append(Star(x, y, z)) self.starSprites.append(Star(*star)) for deg in range(0, 180, 30): rad = math.pi * deg / 180 sinVal = math.sin(rad) cosVal = math.cos(rad) dest_x = sinVal * 10 dest_y = cosVal * 10 target_x = sinVal * -10 target_y = cosVal * -10 self.lines.append(((target_x, target_y, 0), (dest_x, dest_y, 0))) def draw(self): glColor4f(1.0, 1.0, 1.0, 1.0) radius = 10 inner = radius - 0.1 glLoadIdentity() glTranslatef(0.0, 0.0, -6.0) glRotatef(self.rotation, 1.0, 0.0, 0.0) glRotatef(self.spin, 0.0, 0.0, 1.0) gluQuadricDrawStyle(self.quad, GLU_FILL) glScalef(0.2, 0.2, 0.2) for depth in range(0, 10, 2): gluDisk(self.quad, inner-depth, radius-depth, self.resolution, 1) glLineWidth(1.0) glBegin(GL_LINES) for line in self.lines: glVertex3f(*line[0]) glVertex3f(*line[1]) glColor4f(1.0, 0, 0, 1.0) for star in self.starSprites: x, y, z = translateCoords((star.x, star.y, star.z), self.position) glVertex3f(x, y, 0.0) glVertex3f(x, y, z) glEnd() glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) for star in self.starSprites: star.offset = self.position star.rotation = self.rotation star.spin = self.spin star.draw() def drawStarLabels(self): for star in self.starSprites: star.fontText.draw() def translateCoords(coords, offset): x1, y1, z1 = coords x2, y2, z2 = offset return x1-x2, y1-y2, z1-z2 class Star(object): def __init__(self, name, x, y, z, imageName='star.png'): self.name = name self.x = x self.y = y self.z = z self.color = (random.randint(0, 256), random.randint(0, 256), random.randint(0, 256), 255) ft = font.load('Arial', 14) self.fontText = font.Text(ft, text=name) self.rotation = 0 self.spin = 0 self.offset = (0, 0, 0) self.textureSurface = image.load('data/' + imageName) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) def draw(self): x, y, z = translateCoords((self.x, self.y, self.z), self.offset) model = (GLdouble * 16)() projection = (GLdouble * 16)() viewport = (GLint * 4)() glGetDoublev(GL_MODELVIEW_MATRIX, model) glGetDoublev(GL_PROJECTION_MATRIX, projection) glGetIntegerv(GL_VIEWPORT, viewport) winX = GLdouble() winY = GLdouble() winZ = GLdouble() gluProject(x, y, z, model, projection, viewport, winX, winY, winZ) starX = int(winX.value) starY = int(winY.value) starZ = int(winZ.value) self.fontText.x = starX if starY > 240: starY += 10 else: starY -= 20 self.fontText.y = starY #print "%d %d %d" % (starX, starY, starZ) glTranslatef(x, y, z) # keep the face of the star always facing forward glRotatef(-self.spin, 0.0, 0.0, 1.0) glRotatef(-self.rotation, 1.0, 0.0, 0.0) glColor4ub(*self.color) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, self.textureSurface.texture.id) glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 0.0) glTexCoord2f(1.0, 0.0); glVertex3f(1.0, -1.0, 0.0) glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, 0.0) glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0) glEnd() glDisable(GL_TEXTURE_2D) # reset the position glRotatef(self.rotation, 1.0, 0.0, 0.0) glRotatef(self.spin, 0.0, 0.0, 1.0) glTranslatef(-x, -y, -z) def parseConfigFile(file): doc = xml.dom.minidom.parse(file) starSystems = [] for node in doc.getElementsByTagName("system"): name = fetchText(node, "name") print name for star in node.getElementsByTagName("star"): starClass = star.getAttribute("class") for coords in node.getElementsByTagName("coords"): x = float(coords.getAttribute("x")) y = float(coords.getAttribute("y")) z = float(coords.getAttribute("z")) starSystems.append((name, x, y, z)) print "x=%0f y=%f z=%f" % (x, y, z) return starSystems def resize(width, height): if height==0: height=1 glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45, 1.0*width/height, 0.1, 100.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def init(): glShadeModel(GL_SMOOTH) glClearColor(0.0, 0.0, 0.0, 0.0) glClearDepth(1.0) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) glEnable(GL_TEXTURE_2D) def mode2d(): glLoadIdentity() glPushAttrib(GL_ENABLE_BIT) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glDisable(GL_LIGHTING) glDisable(GL_DEPTH_TEST) glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0, 640, 0, 480, -1, 1) glMatrixMode(GL_MODELVIEW) def mode3d(): glMatrixMode(GL_PROJECTION) glPopMatrix() glMatrixMode(GL_MODELVIEW) glPopAttrib() def on_key_press(sym, mod): global spin, rotate, auto if sym == key.UP: rotate += 2.0 elif sym == key.DOWN: rotate -= 2.0 elif sym == key.RIGHT: spin += 2.0 elif sym == key.LEFT: spin -= 2.0 elif sym == key.SPACE: auto = not auto if __name__ == '__main__': from pyglet import window win = window.Window() win.on_resize = resize win.on_key_press = on_key_press init() orb = GalacticMap() while not win.has_exit: win.dispatch_events() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) if auto: rotate += 0.2 spin += 0.1 orb.rotation = rotate orb.spin = spin orb.draw() mode2d() orb.drawStarLabels() mode3d() win.flip()