from OpenGL.GL import * import pygame import hotshot import sys def loadImage(image): textureSurface = pygame.image.load(image) colorkey = textureSurface.get_at((0,0)) textureSurface.set_colorkey(colorkey, pygame.RLEACCEL) textureData = pygame.image.tostring(textureSurface, "RGBA") width = textureSurface.get_width() height = textureSurface.get_height() texture = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData) return texture, width, height class Font: def __init__(self, filename, fontspec=(10,12)): self.font, self.w, self.h = loadImage(filename) self.glyphw = fontspec[0] self.glyphh = fontspec[1] self.xchars = self.w / self.glyphw self.ychars = self.h / self.glyphh self.dls = {} def putcB(self, char): glBindTexture(GL_TEXTURE_2D, self.font) self.putc(char) def putc(self, char): bg, fg = (0,0,0), (1,1,1) if isinstance(char, tuple): char, fg, bg = char if isinstance(char, int): c = char if isinstance(char, str): c = ord(char) if bg != (0,0,0): glColor3f(*bg) self.__drawc(219) # FIXME: hack to avoid rebinding, draws a box. glColor3f(*fg) self.drawc(c) def drawc(self, c): if c in self.dls: glCallList(self.dls[c]) else: y,x = divmod(c, self.xchars) y = y * float(self.glyphh) x = x * float(self.glyphw) w = float(self.w) h = float(self.h) l = x/w r = l+self.glyphw/w t = y/h b = t+self.glyphh/h ls = glGenLists(1) glNewList(ls, GL_COMPILE) glBegin(GL_QUADS) glTexCoord2f(l,t); glVertex2f(0,0) glTexCoord2f(r,t); glVertex2f(self.glyphw,0) glTexCoord2f(r,b); glVertex2f(self.glyphw,self.glyphh) glTexCoord2f(l,b); glVertex2f(0,self.glyphh) glEnd() glEndList() self.dls[c] = ls glCallList(ls) def puts(self, str): glBindTexture(GL_TEXTURE_2D, self.font) for c in str: self.putc(c) glTranslatef(self.glyphw,0,0) class Cell: pass class Map: def __init__(self, font, width=64, height=40): self.font = isinstance(font, str) and Font(font) or font self.__cells = {} self.width, self.height = width, height def __getitem__(self, (x,y)): #if x < 0 or x > self.width or y < 0 or y > self.height: raise KeyError((x,y)) if (x,y) in self.__cells: return self.__cells[x,y] else: self.__cells[x,y] = Cell() return self.__cells[x,y] def cells(self): return self.__cells.iteritems() TREE='TREE' GROUND='GROUND' def main(): pygame.init() pygame.display.set_mode((640,480), pygame.OPENGL|pygame.DOUBLEBUF) font = Font("curses_800x600.bmp") map = Map(font) for y in range(map.height): for x in range(map.width): map[x,y].type = GROUND map[10,10].type = TREE map[19,11].type = TREE map[12,24].type = TREE map[21,17].type = TREE glMatrixMode(GL_PROJECTION) glEnable(GL_TEXTURE_2D) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_BLEND) glLoadIdentity() glOrtho(0, 640, 480, 0, -1, 1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glDisable(GL_DEPTH_TEST) clock = pygame.time.Clock() while 1: clock.tick(10) glClear(GL_COLOR_BUFFER_BIT) for (x,y),c in map.cells(): glLoadIdentity() glTranslatef(x*map.font.glyphw, y*map.font.glyphh, 0) if c.type is TREE: map.font.drawc(ord('*')) elif c.type is GROUND: map.font.drawc(ord('.')) pygame.display.flip() for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0) if __name__ == "__main__": #prof = hotshot.Profile("prof.log", 1) #prof.runcall(main) #prof.close() main()