def rotate(self, angle):
   self.ops.append(lambda: glRotatef(math.degrees(angle), 0.0, 0.0, 1.0))
 def rotate(self):
     glRotatef(self.x, 1, 0, 0)
     glRotatef(self.y, 0, 1, 0)
     glRotatef(self.z, 0, 0, 1)
 def render(self, geomName = None):
   if geomName in self.fullGeoms:
     self.fullGeoms[geomName]()
     return
     
   # Prepare a new list for all the geometry
   if not self.geoms:
     for geom in self.doc.geometriesLibrary.items:
       self.geoms[geom.name] = cmglList()
       with self.geoms[geom.name]:
 
         for prim in geom.data.primitives:
           maxOffset = vertexOffset = normalOffset = 0
           vertexOffset = None
           normalOffset = None
           texcoordOffset = None
           vertices = None
           normals = None
           texcoords = None
 
           for input in prim.inputs:
             maxOffset = max(maxOffset, input.offset)
             if input.semantic == "VERTEX":
               vertexOffset = input.offset
               vertices = geom.data.FindSource(geom.data.vertices.FindInput("POSITION"))
               assert vertices.techniqueCommon.accessor.stride == 3
               vertices = self._unflatten(vertices.source.data, vertices.techniqueCommon.accessor.stride)
             elif input.semantic == "NORMAL":
               normalOffset = input.offset
               normals = geom.data.FindSource(input)
               normals = self._unflatten(normals.source.data, 3)
             elif input.semantic == "TEXCOORD":
               texcoordOffset = input.offset
               texcoords = geom.data.FindSource(input)
               texcoords = self._unflatten(texcoords.source.data, 2)
 
           if normalOffset is None:
             normals = geom.data.FindSource(geom.data.vertices.FindInput("NORMAL"))
             normals = self._unflatten(normals.source.data, 3)
             normalOffset = vertexOffset
 
           def drawElement(indices, offset, array, func):
             if offset is not None:
               func(*array[indices[offset]])
         
           if hasattr(prim, "polygons"):
             for poly in prim.polygons:
               glBegin(GL_POLYGON)
               for indices in self._unflatten(poly, maxOffset + 1):
                 drawElement(indices, normalOffset,   normals,   glNormal3f)
                 drawElement(indices, texcoordOffset, texcoords, glTexCoord2f)
                 drawElement(indices, vertexOffset,   vertices,  glVertex3f)
               glEnd()
           elif hasattr(prim, "triangles"):
            glBegin(GL_TRIANGLES)
            for indices in self._unflatten(prim.triangles, maxOffset + 1):
               drawElement(indices, normalOffset,   normals,   glNormal3f)
               drawElement(indices, texcoordOffset, texcoords, glTexCoord2f)
               drawElement(indices, vertexOffset,   vertices,  glVertex3f)
            glEnd()
     
   # Prepare a new display list for this particular geometry
   self.fullGeoms[geomName] = cmglList()
   with self.fullGeoms[geomName]:
   
     if self.geoms:
       # setup lights
       for scene in self.doc.visualScenesLibrary.items:
         for node in scene.nodes:
           for n, light in enumerate(node.iLights):
             if light.object:
               # TODO: hierarchical node transformation, other types of lights
               pos = [0.0, 0.0, 0.0, 1.0]
               for t in node.transforms:
                 if t[0] == "translate":
                   pos = t[1]
               self.setupLight(light.object, n, pos)
             
       # render geometry
       for scene in self.doc.visualScenesLibrary.items:
         for node in scene.nodes:
           if geomName is not None and node.name != geomName:
             continue
           for geom in node.iGeometries:
             if geom.object:
               #for mat in geom.bindMaterials:
               #  self.setupMaterial(mat)
               
               glPushMatrix()
               for t in node.transforms:
                 if t[0] == "translate":
                   glTranslatef(*t[1])
                 elif t[0] == "rotate":
                   glRotatef(t[1][3], t[1][0], t[1][1], t[1][2])
                 elif t[0] == "scale":
                   glScalef(*t[1])
               if geom.object.name in self.geoms:
                 self.geoms[geom.object.name]()
               glPopMatrix()
       glDisable(GL_LIGHTING)
       for n in range(8):
         glDisable(GL_LIGHT0 + n)
     
   # Render the new list
   self.render(geomName)
  def render(self, text, pos = (0, 0), rotate = 0, scale = DEFAULT_SCALE, shadowoffset = (.0022, .0005), align = LEFT, new = False):
    """
    Draw some text.

    @param text:      Text to draw
    @param pos:       Text coordinate tuple (x, y)
    @param rotate:    Angle to rotate text, in degrees
    @param scale:     Scale factor
    """
    # deufeufeu : new drawing relaying only on pygame.font.render
    #           : I know me miss special unicodes characters, but the gain
    #           : is really important.
    # evilynux : Use arrays to increase performance
    def drawSquare(w,h,tw,th):
        self.square_prim[1,0] = self.square_prim[3,0] = w
        self.square_prim[2,1] = self.square_prim[3,1] = h
        self.square_tex[0,1] = self.square_tex[1,1] = th
        self.square_tex[1,0] = self.square_tex[3,0] = tw
        cmglDrawArrays(GL_TRIANGLE_STRIP, vertices=self.square_prim, texcoords=self.square_tex)

    if not text:
        return

    try:
        t,w,h = self.stringsCache.get(text)
    except KeyError:
        s = self.font.render(text, True, (255,255,255))
        t = Texture()
        t.setFilter(GL_LINEAR, GL_LINEAR)
        t.setRepeat(GL_CLAMP, GL_CLAMP)
        t.loadSurface(s, alphaChannel = True)
        del s
        w, h = self.font.size(text)
        self.stringsCache.add(text,(t,w,h))

    x, y = pos
    scale *= self.scale
    w, h = w*scale*self.aspectRatioFactor, h*scale
    if align == CENTER: #we have already done all the calculating. Why not add this? - akedrou
      x -= (w/2)
    elif align == RIGHT:
      x -= w
    y -= (h/2)
    tw,th = t.size
    glEnable(GL_TEXTURE_2D)
    with cmglPushedMatrix():
      if rotate:
        if not isinstance(rotate, tuple):
          glRotatef(rotate, 0, 0, 1.0)
        else:
          glRotatef(0, *rotate)
      glTranslatef(x,y,0)
      t.bind()
      if self.outline:
        with cmglPushedAttrib(GL_CURRENT_BIT):
          glColor4f(0, 0, 0, .25 * glGetDoublev(GL_CURRENT_COLOR)[3])

          blur = 2 * DEFAULT_SCALE
          for offset in [(-.7, -.7), (0, -1), (.7, -.7), (-1, 0),
                         (1, 0), (-.7, .7), (0, 1), (.7, .7)]:
            with cmglPushedMatrix():
              glTranslatef(blur * offset[0], blur * offset[1], 0)
              drawSquare(w,h,tw,th)

      if self.shadow:
        with cmglPushedAttrib(GL_CURRENT_BIT):
          glColor4f(0, 0, 0, 1)
          with cmglPushedMatrix():
            glTranslatef(shadowoffset[0], shadowoffset[1], 0)
            drawSquare(w,h,tw,th)

      drawSquare(w,h,tw,th)

    glDisable(GL_TEXTURE_2D)