def drawBPM(self, visibility, song, pos):
    if not song:
      return
    if not song.readyToGo:
      return


    v            = visibility
    w            = self.boardWidth

    track = song.track[self.player]

    glEnable(GL_TEXTURE_2D)

    for time, event in track.getEvents(pos - self.currentPeriod * 2, pos + self.currentPeriod * self.beatsPerBoard):
      if not isinstance(event, Bars):
        continue   

      glPushMatrix()

      z  = ((time - pos) / self.currentPeriod) / self.beatsPerUnit
      z2 = ((time + event.length - pos) / self.currentPeriod) / self.beatsPerUnit

      if z > self.boardLength:
        f = (self.boardLength - z) / (self.boardLength * .2)
      elif z < 0:
        f = min(1, max(0, 1 + z2))
      else:
        f = 1.0
        
      if event.barType == 0: #half-beat
        sw  = 0.1 #width
        self.bpm_halfbeat.texture.bind()
      elif event.barType == 1: #beat
        sw  = 0.1 #width
        self.bpm_beat.texture.bind()
      elif event.barType == 2: #measure
        sw  = 0.1 #width
        self.bpm_measure.texture.bind()

      bpm_vtx  = array([[-(w / 2), 0,  z + sw],
                         [-(w / 2), 0,  z - sw],
                         [(w / 2), 0,  z + sw],
                         [(w / 2), 0,  z - sw]], dtype=float32)

      bpm_tex  = array([[0.0, 1.0],
                         [0.0, 0.0],
                         [1.0, 1.0],
                         [1.0, 0.0]], dtype=float32)

      bpm_col  = array([[1, 1, 1, v],
                         [1, 1, 1, v],
                         [1, 1, 1, v],
                         [1, 1, 1, v]], dtype=float32)

      cmglDrawArrays(GL_TRIANGLE_STRIP, vertices=bpm_vtx, colors=bpm_col, texcoords=bpm_tex)

      glPopMatrix()

    glDisable(GL_TEXTURE_2D)
 def render(self, visibility = 1.0, topMost = False):
   try:
     # Save and clear both transformation matrices
     glMatrixMode(GL_PROJECTION)
     glPushMatrix()
     glLoadIdentity()
     glMatrixMode(GL_MODELVIEW)
     glPushMatrix()
     glLoadIdentity()
     # Draw the polygon and apply texture
     glBindTexture(GL_TEXTURE_2D, self.animTexs[self.curFrame])
     self.animList()
     # Restore both transformation matrices
     glPopMatrix()
     glMatrixMode(GL_PROJECTION)
     glPopMatrix()
   except:
     Log.error("AnimationPlayer: Error attempting to play animation")
  def render(self, visibility, topMost):
    font = self.engine.data.font

    # render the scene
    try:
      glMatrixMode(GL_PROJECTION)
      glPushMatrix()
      glLoadIdentity()
      gluPerspective(60, self.engine.view.aspectRatio, 0.1, 1000)
      glMatrixMode(GL_MODELVIEW)
      glLoadIdentity()
      
      glPushMatrix()
      self.camera.apply()
  
      self.render3D()
    finally:
      glPopMatrix()
      glMatrixMode(GL_PROJECTION)
      glPopMatrix()
      glMatrixMode(GL_MODELVIEW)
  def render(self, visibility, topMost):
    #MFH - display version in any menu:

    if not visibility:
      self.active = False
      return

    self.active = True
    if self.graphicMenu and self.menuBackground:
      self.engine.graphicMenuShown = True
    else:
      self.engine.graphicMenuShown = False
    
    self.engine.view.setOrthogonalProjection(normalize = True)
    try:
      v = (1 - visibility) ** 2
      # Default to this font if none was specified

      font = self.font
      tipFont = self.tipFont

      if self.fadeScreen:
        Dialogs.fadeScreen(v)
        
      wS, hS = self.engine.view.geometry[2:4]
        
      if self.graphicMenu and self.menuBackground:
        #volshebnyi - better menu scaling
        self.engine.drawImage(self.menuBackground, scale = (1.0,-1.0), coord = (wS/2,hS/2), stretched = 3)
      else:
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glEnable(GL_COLOR_MATERIAL)

      n = len(self.choices)
      x, y = self.pos

      for i, choice in enumerate(self.choices[self.viewOffset:self.viewOffset + self.viewSize]):
        if self.graphicMenu:
          if self.currentIndex == i:
            xpos = (.5,1)
          else:
            xpos = (0,.5)
          ypos = float(i+self.viewOffset)
          self.menuText.transform.reset()
          self.menuText.transform.scale(.5*self.menuScale,(-1.0/n*self.menuScale))
          self.menuText.transform.translate(wS*self.menux,(hS*self.menuy)-(hS*self.vSpace)*i)
          self.menuText.draw(rect = (xpos[0],xpos[1],ypos/n,(ypos+1.0)/n))
          #self.engine.drawImage(self.menuText, scale = (self.menuScale,-self.menuScale*2/n), coord = (wS*self.menux,hS*(self.menuy-self.vSpace*i)), rect = (xpos[0],xpos[1],ypos/n,(ypos+1.0)/n), stretched = 11)
        else:
          text = choice.getText(i + self.viewOffset == self.currentIndex)
          glPushMatrix()
          glRotate(v * 45, 0, 0, 1)

          scale = 0.002
          if self.mainMenu and self.theme < 2 and i % 2 == 1:#8bit
              scale = 0.0016

          w, h = font.getStringSize(" ", scale = scale)

          # Draw arrows if scrolling is needed to see all items
          if i == 0 and self.viewOffset > 0:
            self.engine.theme.setBaseColor((1 - v) * max(.1, 1 - (1.0 / self.viewOffset) / 3))
            glPushMatrix()
            glTranslatef(x - v / 4 - w * 2, y + h / 2, 0)
            self.renderTriangle(up = (0, -1), s = .015)
            glPopMatrix()
          elif i == self.viewSize - 1 and self.viewOffset + self.viewSize < n:
            self.engine.theme.setBaseColor((1 - v) * max(.1, 1 - (1.0 / (n - self.viewOffset - self.viewSize)) / 3))
            glPushMatrix()
            glTranslatef(x - v / 4 - w * 2, y + h / 2, 0)
            self.renderTriangle(up = (0, 1), s = .015)
            glPopMatrix()

          if i + self.viewOffset == self.currentIndex:
            if choice.tipText and self.showTips:
              if self.tipColor:
                c1, c2, c3 = self.tipColor
                glColor3f(c1,c2,c3)
              elif self.textColor:
                c1, c2, c3 = self.textColor
                glColor3f(c1,c2,c3)
              else:
                self.engine.theme.setBaseColor(1-v)
              tipScale = self.tipScale
              if self.tipScroll > -(self.tipSize) and self.tipScroll < 1:
                tipFont.render(choice.tipText, (self.tipScroll, self.tipY), scale = tipScale)
              if self.tipScrollMode == 0:
                if self.tipScrollB > -(self.tipSize) and self.tipScrollB < 1:
                  tipFont.render(choice.tipText, (self.tipScrollB, self.tipY), scale = tipScale)
            a = (math.sin(self.time) * .15 + .75) * (1 - v * 2)
            self.engine.theme.setSelectedColor(a)
            a *= -.005
            glTranslatef(a, a, a)
          else:
            self.engine.theme.setBaseColor(1 - v)      
        
          #MFH - settable color through Menu constructor
          if i + self.viewOffset == self.currentIndex and self.selectedColor:
            c1,c2,c3 = self.selectedColor
            glColor3f(c1,c2,c3)
          elif self.textColor:
            c1,c2,c3 = self.textColor
            glColor3f(c1,c2,c3)
        
          #MFH - now to catch " >" main menu options and blank them:
          if text == " >":
            text = ""
            
          if self.engine.data.submenuSelectFound and len(text) > 0 and not self.mainMenu and self.useSelectedBox:
            Tw, Th = font.getStringSize(text,scale)
            lineSpacing = font.getLineSpacing(scale)
            frameWidth = Tw*1.10
            #frameHeight = (Th+Th2)*1.10
            frameHeight = Th + lineSpacing
            boxXOffset = (x + (Tw/2))*wS
            boxYOffset = (1.0 - (y*4.0/3.0) - (Th*1.2/2))*hS
            subSelectHYFactor = 640.000/self.engine.view.aspectRatio
            subSelectHFactor = subSelectHYFactor/self.engine.data.subSelectImgH
            self.engine.data.submenuSelect.transform.reset()
            tempWScale = frameWidth*self.engine.data.subSelectWFactor
            tempHScale = -(frameHeight)*subSelectHFactor
            self.engine.data.submenuSelect.transform.scale(tempWScale,tempHScale)
            self.engine.data.submenuSelect.transform.translate(boxXOffset,boxYOffset)
            self.engine.data.submenuSelect.draw()
          
          font.render(text, (x - v / 4, y), scale = scale)
        
        
          v *= 2
          if self.theme == 1 and self.font == self.engine.data.pauseFont: # evilynux - Ugly workaround for Gh3
            y += h*.70      #Worldrave - Changed Pause menu spacing back to .70 from .65 for now.
          else:
            y += h
          glPopMatrix()
    
    
    finally:
      self.engine.view.resetProjection()
 def resetProjection(self):
   glMatrixMode(GL_PROJECTION)
   glPopMatrix()
   glMatrixMode(GL_MODELVIEW)
   glPopMatrix()
 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)