def renderTriangle(self, up = (0, 1), s = .2):
   left = (-up[1], up[0])
   glBegin(GL_TRIANGLES)
   glVertex2f( up[0] * s,  up[1] * s)
   glVertex2f((-up[0] + left[0]) * s, (-up[1] + left[1]) * s)
   glVertex2f((-up[0] - left[0]) * s, (-up[1] - left[1]) * s)
   glEnd()
  def renderIncomingNeck(self, visibility, song, pos, time, neckTexture):   #MFH - attempt to "scroll" an incoming guitar solo neck towards the player
    if not song:
      return
    if not song.readyToGo:
      return
    
    def project(beat):
      return 0.125 * beat / self.beatsPerUnit    # glorandwarf: was 0.12

    v            = visibility
    w            = self.boardWidth
    l            = self.boardLength

    #offset       = (pos - self.lastBpmChange) / self.currentPeriod + self.baseBeat 
    offset = 0

    z  = ((time - pos) / self.currentPeriod) / self.beatsPerUnit

    color = (1,1,1)

    glEnable(GL_TEXTURE_2D)
    if neckTexture:
      neckTexture.texture.bind()


    glBegin(GL_TRIANGLE_STRIP)
    glColor4f(color[0],color[1],color[2], 0)
    glTexCoord2f(0.0, project(offset - 2 * self.beatsPerUnit))
    #glVertex3f(-w / 2, 0, -2)
    glVertex3f(-w / 2, 0, z)   #point A
    glTexCoord2f(1.0, project(offset - 2 * self.beatsPerUnit))
    #glVertex3f( w / 2, 0, -2)
    glVertex3f( w / 2, 0, z)   #point B

    
    glColor4f(color[0],color[1],color[2], v)
    glTexCoord2f(0.0, project(offset - 1 * self.beatsPerUnit))
    #glVertex3f(-w / 2, 0, -1)
    glVertex3f(-w / 2, 0, z+1)   #point C
    glTexCoord2f(1.0, project(offset - 1 * self.beatsPerUnit))
    #glVertex3f( w / 2, 0, -1)
    glVertex3f( w / 2, 0, z+1)   #point D
    
    glTexCoord2f(0.0, project(offset + l * self.beatsPerUnit * .7))
    #glVertex3f(-w / 2, 0, l * .7)
    glVertex3f(-w / 2, 0, z+2+l * .7) #point E
    glTexCoord2f(1.0, project(offset + l * self.beatsPerUnit * .7))
    #glVertex3f( w / 2, 0, l * .7)
    glVertex3f( w / 2, 0, z+2+l * .7) #point F
    
    glColor4f(color[0],color[1],color[2], 0)
    glTexCoord2f(0.0, project(offset + l * self.beatsPerUnit))
    #glVertex3f(-w / 2, 0, l)
    glVertex3f(-w / 2, 0, z+2+l)    #point G
    glTexCoord2f(1.0, project(offset + l * self.beatsPerUnit))
    #glVertex3f( w / 2, 0, l)
    glVertex3f( w / 2, 0, z+2+l)    #point H
    glEnd()
    
    glDisable(GL_TEXTURE_2D)
  def drawSideBars(self, visibility, song, pos):
    if not song:
      return
    if not song.readyToGo:
      return

    def project(beat):
      return 0.125 * beat / self.beatsPerUnit  # glorandwarf: was 0.12

    v            = visibility
    w            = self.boardWidth + 0.15
    l            = self.boardLength

    offset       = (pos - self.lastBpmChange) / self.currentPeriod + self.baseBeat 

    c = (1,1,1)

    board_tex  = array([[0.0, project(offset - 2 * self.beatsPerUnit)],
                         [1.0, project(offset - 2 * self.beatsPerUnit)],
                         [0.0, project(offset - 1 * self.beatsPerUnit)],
                         [1.0, project(offset - 1 * self.beatsPerUnit)],
                         [0.0, project(offset + l * self.beatsPerUnit * .7)],
                         [1.0, project(offset + l * self.beatsPerUnit * .7)],
                         [0.0, project(offset + l * self.beatsPerUnit)],
                         [1.0, project(offset + l * self.beatsPerUnit)]], dtype=float32)

    glEnable(GL_TEXTURE_2D)
    if self.theme == 2 and self.instrument.starPowerActive and self.oSideBars:
      self.oSideBars.texture.bind()
    else:
      self.sideBars.texture.bind()

    cmglDrawArrays(GL_TRIANGLE_STRIP, vertices=self.sidebars_vtx, colors=self.board_col, texcoords=board_tex)
    
    glDisable(GL_TEXTURE_2D)
    
    if self.theme == 1:   
      if shaders.enable("sololight"):
        shaders.modVar("color",shaders.var["solocolor"])
        shaders.setVar("offset",(-3.5,-w/2))
        glBegin(GL_TRIANGLE_STRIP)
        glVertex3f(w / 2-1.0, 0.4, -2)
        glVertex3f(w / 2+1.0, 0.4, -2)
        glVertex3f(w / 2-1.0, 0.4, l)
        glVertex3f(w / 2+1.0, 0.4, l)
        glEnd()   
        shaders.setVar("offset",(-3.5,w/2))
        shaders.setVar("time",shaders.time()+0.5)
        glBegin(GL_TRIANGLE_STRIP)
        glVertex3f(-w / 2+1.0, 0.4, -2)
        glVertex3f(-w / 2-1.0, 0.4, -2)
        glVertex3f(-w / 2+1.0, 0.4, l)
        glVertex3f(-w / 2-1.0, 0.4, l)
        glEnd()  
        shaders.disable()
 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 renderNeck(self, visibility, song, pos):     
    if not song:
      return
    if not song.readyToGo:
      return
    
    v            = visibility
    w            = self.boardWidth
    l            = self.boardLength

    offset       = (pos - self.lastBpmChange) / self.currentPeriod + self.baseBeat 

    #myfingershurt: every theme can have oNeck:

    if self.guitarSolo and self.guitarSoloNeck != None and self.guitarSoloNeckMode == 1:
      neck = self.guitarSoloNeck
    elif self.scoreMultiplier > 4 and self.bassGrooveNeck != None and self.bassGrooveNeckMode == 1:
      neck = self.bassGrooveNeck
    elif self.instrument.starPowerActive and not (self.spcount2 != 0 and self.spcount < 1.2) and self.oNeck and self.scoreMultiplier <= 4 and self.ovrneckoverlay == False:
      neck = self.oNeck
    else:
      neck = self.neckDrawing

    
    self.renderNeckMethod(v*self.neckAlpha[1], offset, neck)
    
    if self.guitarSolo and self.guitarSoloNeck != None and self.guitarSoloNeckMode == 2:   #static overlay
      self.renderNeckMethod(v*self.neckAlpha[2], 0, self.guitarSoloNeck)
      
    elif self.bgcount > 0 and self.bassGrooveNeck != None and self.bassGrooveNeckMode == 2:   #static bass groove overlay
      self.renderNeckMethod(v*self.bgcount*self.neckAlpha[3], 0, self.bassGrooveNeck)
      
    if self.spcount2 != 0 and self.spcount < 1.2 and self.oNeck:   #static overlay
      if self.oNeckovr != None and (self.scoreMultiplier > 4 or self.guitarSolo or self.ovrneckoverlay == True):
        neck = self.oNeckovr
        alpha = False
      else:
        neck = self.oNeck
        alpha = True          

      self.renderNeckMethod(v*self.spcount*self.neckAlpha[4], offset, neck, alpha)
      
    
      
    if self.instrument.starPowerActive and not (self.spcount2 != 0 and self.spcount < 1.2) and self.oNeck and (self.scoreMultiplier > 4 or self.guitarSolo or self.ovrneckoverlay == True):   #static overlay
      if self.oNeckovr != None:
        neck = self.oNeckovr
        alpha = False
      else:
        neck = self.oNeck
        alpha = True

      self.renderNeckMethod(v*self.neckAlpha[4], offset, neck, alpha)

    if shaders.enabled:
      shaders.globals["basspos"] = shaders.var["fret"][self.player][0]
      shaders.globals["notepos"] = shaders.var["fret"][self.player][1:]
      shaders.globals["bpm"] = self.instrument.currentBpm
      shaders.globals["songpos"] = pos
      shaders.globals["spEnabled"] = self.instrument.starPowerActive
      shaders.globals["isFailing"] = self.isFailing
      shaders.globals["isMultChanged"] = (shaders.var["scoreMult"][self.player] != self.scoreMultiplier)
      if shaders.globals["isMultChanged"]:
        shaders.var["multChangePos"][self.player] = pos
      shaders.globals["scoreMult"] = self.scoreMultiplier
      shaders.var["scoreMult"][self.player] = self.scoreMultiplier
      shaders.globals["isDrum"] = self.isDrum
      shaders.globals["soloActive"] = self.guitarSolo
      
      posx = shaders.time()
      fret = []
      neckcol = (0,0,0)
      
      notecolors = list(self.engine.theme.noteColors)
      if self.isDrum:
        notecolors[4] = notecolors[0]
        notecolors[0] = self.engine.theme.noteColors[5]
        
        
      for i in range(5):
        blend = max(shaders.var["fret"][self.player][i] - posx + 1.5,0.01)
        neckcol = mixColors(neckcol, notecolors[i], blend)

      shaders.var["color"][self.player]=neckcol
      
    if shaders.enable("neck"):
      shaders.setVar("fretcol",neckcol)
      shaders.update()
      glBegin(GL_TRIANGLE_STRIP)
      glVertex3f(-w / 2, 0.1, -2)
      glVertex3f(w / 2, 0.1, -2)
      glVertex3f(-w / 2, 0.1, l)
      glVertex3f(w / 2, 0.1, l)
      glEnd()
      shaders.disable()
    else:
      if self.isFailing:
        self.renderNeckMethod(self.failcount, 0, self.failNeck)
        
    if (self.guitarSolo or self.instrument.starPowerActive) and self.theme == 1:
      shaders.var["solocolor"]=(0.3,0.7,0.9,0.6)
    else:
      shaders.var["solocolor"]=(0.0,)*4