title: How to use gluUnProject in python/pyglet properly?
body: <p>I am trying to get <code>gluUnProject</code> to work in pyglet to get the mouse position relative to the background (which gets moved via <code>glTranslatef</code> and <code>glScalef</code>). This it what I have and while it gives me a position it is not the correct one: </p>
  
  <pre><code>def mouse_unproject(x,y):
      pmat = (pyglet.gl.GLdouble * 16)()
      mvmat = (pyglet.gl.GLdouble * 16)()
      view = (pyglet.gl.GLint * 4)()
      px = (pyglet.gl.GLdouble)()
      py = (pyglet.gl.GLdouble)()
      pz = (pyglet.gl.GLdouble)()
      pyglet.gl.glGetDoublev(pyglet.gl.GL_MODELVIEW_MATRIX, mvmat)
      pyglet.gl.glGetDoublev(pyglet.gl.GL_PROJECTION_MATRIX, pmat)
      pyglet.gl.glGetIntegerv(pyglet.gl.GL_VIEWPORT, view)
      pyglet.gl.gluUnProject(x, y, 0, mvmat, pmat, view, px, py, pz)
      return (px.value,py.value)
  </code></pre>
  
  <p>Entire Source Code:</p>
  
  <pre><code>from pyglet.image.codecs.png import PNGImageDecoder
  from pyglet.window import key, mouse
  from ship import Ships
  import pyglet
  import numpy as np
  import csv
  
  def mouse_unproject(x,y):
      pmat = (pyglet.gl.GLdouble * 16)()
      mvmat = (pyglet.gl.GLdouble * 16)()
      view = (pyglet.gl.GLint * 4)()
      px = (pyglet.gl.GLdouble)()
      py = (pyglet.gl.GLdouble)()
      pz = (pyglet.gl.GLdouble)()
      pyglet.gl.glGetDoublev(pyglet.gl.GL_MODELVIEW_MATRIX, mvmat)
      pyglet.gl.glGetDoublev(pyglet.gl.GL_PROJECTION_MATRIX, pmat)
      pyglet.gl.glGetIntegerv(pyglet.gl.GL_VIEWPORT, view)
      pyglet.gl.gluUnProject(x, y, 0, mvmat, pmat, view, px, py, pz)
      return (px.value,py.value)
  
  class Game:
      def __init__(self):
          self.pause = False
          self.ships = []
  
  class Overlay:
      def __init__(self):
          self.radar = pyglet.sprite.Sprite(img=pyglet.image.load('pictures/radar.png',decoder=PNGImageDecoder()))
          self.radar_indicator = pyglet.sprite.Sprite(img=pyglet.image.load('pictures/radar_indicator.png',decoder=PNGImageDecoder()))
          self.radar.update(x=1014,y=630)
          self.radar.opacity = 200
          self.indicator_scale = 1
  
      def draw(self,ships,scale):
          d = 25 * scale
  
          self.radar.draw()
  
          for s in ships:
              x = (((s.icon.x)//d)+1019)
              y = (((s.icon.y)//d)+635)
              pyglet.graphics.draw(4,pyglet.gl.GL_QUADS,('v2f',(x-1,y-1,x+2,y-1,x+2,y+2,x-1,y+2)),('c3B',(0,255,0,0,255,0,0,255,0,0,255,0)))
  
  class Background:
      def __init__(self):
          self.image = pyglet.image.load('pictures/star_background.png',decoder=PNGImageDecoder())
          self.scale = 1
          self.up = False
          self.down = False
          self.right = False
          self.left = False
          self.speed = 15
          self.translation= [0,0]
          self.total_scale = 1
  
  window = pyglet.window.Window(1280,800)
  ship_classes = {}
  
  with open('shipclasses.csv',mode='r') as csv_file:
      line_counter = 0
      csv_reader = csv.reader(csv_file)
      for row in csv_reader:
          if not line_counter == 0:
              index = 0
              class_dic = {}
              for atr in row:
                  class_dic[headers[index]] = atr
                  index += 1
              ship_classes[row[0]] = class_dic
          else:
              headers = row
          line_counter += 1
  print(ship_classes)
  
  stars = Background()
  player = Ships(True,(640,400),False,ship_classes['Valkyrie'])
  keys = key.KeyStateHandler()
  window.push_handlers(keys)
  game = Game()
  game.ships.append(player)
  overlay = Overlay()
  pause_text = pyglet.text.Label('PAUSE',font_name='Times New Roman',font_size=30,x=window.width//2, y=(window.height * 2)//3,anchor_x='center', anchor_y='center')
  
  @window.event
  def update(dt):
      for s in game.ships:
          s.update(dt)
  pyglet.clock.schedule_interval(update, 0.02)
  
  @window.event
  def background_motion(dt):
      if stars.left:
          pyglet.gl.glTranslatef(stars.speed, 0, 0)
          stars.translation[0] += stars.speed
      if stars.right:
          pyglet.gl.glTranslatef(-stars.speed, 0, 0)
          stars.translation[0] -= stars.speed
      if stars.up:
          pyglet.gl.glTranslatef(0, -stars.speed, 0)
          stars.translation[1] -= stars.speed
      if stars.down:
          pyglet.gl.glTranslatef(0, stars.speed, 0)
          stars.translation[1] += stars.speed
  pyglet.clock.schedule_interval(background_motion, 0.05)
  
  @window.event
  def on_mouse_scroll(x, y, scroll_x, scroll_y):
      if scroll_y &gt; 0:
          stars.scale += 0.01
          stars.total_scale += 0.01
  
      elif scroll_y &lt; 0:
          stars.scale -= 0.01
          stars.total_scale -= 0.01
  
  @window.event
  def on_mouse_press(x, y, button, modifiers):
      if button == mouse.RIGHT and player.course_setting:
          player.heading = (x,y)
          player.course_setting = False
          player.course = True
          player.update(0)
  
  @window.event
  def on_mouse_motion(x, y, dx, dy):
      if player.course_setting:
          player.projected_heading = mouse_unproject(x,y)
  
  @window.event
  def on_key_press(symbol, modifiers):
      if symbol == key.SPACE:
          if game.pause:
              game.pause = False
          else:
              game.pause = True
  
      elif symbol == key.W:
          stars.up = True
  
      elif symbol == key.S:
          stars.down = True
  
      elif symbol == key.D:
          stars.right = True
  
      elif symbol == key.A:
          stars.left = True
  
      elif symbol == key.C:
          if player.course_setting:
              player.course_setting = False
          else:
              player.course_setting = True
              player.update_projected()
  
      elif symbol == key.V:
          if player.course_setting:
              if player.max_v:
                  player.max_v = False
              else:
                  player.max_v = True
  
          elif player.course:
              if player.course_max_v:
                  player.course_max_v = False
              else:
                  player.course_max_v = True
  
  @window.event
  def on_key_release(symbol, modifiers):
      if symbol == key.W:
          stars.up = False
  
      elif symbol == key.S:
          stars.down = False
  
      elif symbol == key.D:
          stars.right = False
  
      elif symbol == key.A:
          stars.left = False
  
  @window.event
  def on_draw():
      window.clear()
  
      pyglet.gl.glScalef(stars.scale,stars.scale, 1, 1)
  
      stars.image.blit(0,0)
      for s in game.ships:
          s.draw()
  
      pyglet.gl.glPushMatrix()
      pyglet.gl.glLoadIdentity()
  
      #HUD Start
      overlay.draw(game.ships,stars.scale)
      if game.pause:
          pause_text.draw()
      #HUD End
  
      pyglet.gl.glPopMatrix()
      stars.scale = 1
  
  if __name__ == '__main__':
      pyglet.app.run()
  </code></pre>
  
  <p>Ship file:</p>
  
  <pre><code>from pyglet.image.codecs.png import PNGImageDecoder
  import pyglet
  import numpy as np
  
  class Ships:
      def __init__(self,player_ship,position,hostile,Class):
          self.velocity_vector = [0,0]
          self.Class = Class['Class Name']
          self.type = Class['Type']
          self.health = int(Class['Health'])
          self.shield = int(Class['Shield'])
          self.acelleration_magnitude = (float(Class['Acceleration(g)']) * 9.8) / 20000
          self.acelleration_angle = 0
          self.acelleration_vector = [0,0]
          self.alive = True
          self.player_ship = player_ship
          self.hostile = hostile
          self.velocity_magnitude = 0
          self.course = False
          self.heading = position
          self.course_setting = False
          self.target_velocity = 25
          self.velocity_angle = 0
          self.projected_heading = position
          self.displacement_vector = list(position)
          self.max_v = False
          self.course_max_v = False
          self.scale_factor = 1
  
          if not self.hostile:
              course_icon = pyglet.image.load('pictures/friendly_course_icon.png',decoder=PNGImageDecoder())
              course_icon.anchor_x = course_icon.width // 2
              course_icon.anchor_y = course_icon.height // 2
  
              ship_icon = pyglet.image.load('pictures/friendly_ship.png', decoder=PNGImageDecoder())
              ship_icon.anchor_x = ship_icon.width // 2
              ship_icon.anchor_y = ship_icon.height // 2
  
              self.icon = pyglet.sprite.Sprite(img=ship_icon)
  
              self.projected_acelleration_icon = pyglet.sprite.Sprite(img=course_icon )
              self.projected_deceleration_icon = pyglet.sprite.Sprite(img=course_icon)
              self.projected_heading_icon = pyglet.sprite.Sprite(img=course_icon)
              self.course_acelleration_icon = pyglet.sprite.Sprite(img=course_icon)
              self.course_deceleration_icon = pyglet.sprite.Sprite(img=course_icon)
              self.heading_icon = pyglet.sprite.Sprite(img=course_icon)
  
          else:
              self.color = (255, 100, 0)
  
          self.icon.x = position[0]
          self.icon.y = position[1]
  
      def update_projected(self):
          if self.course_setting and self.player_ship:
  
              self.projected_course_x = self.projected_heading[0] - self.icon.x
              self.projected_course_y = self.projected_heading[1] - self.icon.x
  
              if self.max_v:
                  self.projected_deceleration = (np.sqrt(((self.projected_course_x ** 2) + (self.projected_course_y ** 2))) / 2)
  
              else:
                  self.projected_deceleration =np.sqrt(((self.projected_course_x ** 2) + (self.projected_course_y ** 2))) - ((self.target_velocity ** 2) / (2 * self.acelleration_magnitude))
                  self.projected_acelleration = (((self.target_velocity ** 2) - (self.velocity_magnitude ** 2)) / (2 * self.acelleration_magnitude)) / 1000
  
  
      def update(self,update_time):
          if self.health &lt;= 0:
              self.alive = False
  
          if not self.alive:
              return
  
          self.update_projected()
  
          if self.velocity_vector[1] != 0:
              self.velocity_angle = np.arctan2(self.velocity_vector[0],self.velocity_vector[1])
  
          self.velocity_magnitude = np.sqrt((self.velocity_vector[0] ** 2) + (self.velocity_vector[1] ** 2))
  
          if self.course:
              if (self.icon.y - self.heading[1]) != 0:
                  self.acelleration_angle = np.arctan2((self.heading[0] - self.icon.x), (self.heading[1] - self.icon.y))
  
              self.sina = np.sin(self.acelleration_angle)
              self.cosa = np.cos(self.acelleration_angle)
  
              self.course_x = self.heading[0] - self.icon.x
              self.course_y = self.icon.y - self.heading[1]
  
              self.course_displacement = np.sqrt(((self.course_x ** 2) + (self.course_y ** 2)))
  
              self.acelleration_vector[0] = (self.acelleration_magnitude * self.sina)
              self.acelleration_vector[1] = (self.acelleration_magnitude * self.cosa)
  
              if self.course_displacement &lt;= ((self.velocity_magnitude ** 2) / (2 * self.acelleration_magnitude)) or (not self.course_max_v and self.velocity_magnitude &gt; self.target_velocity):
                  self.velocity_vector[0] -= self.acelleration_vector[0] * update_time
                  self.velocity_vector[1] -= self.acelleration_vector[1] * update_time
  
              elif self.course_max_v or self.velocity_magnitude &lt; self.target_velocity:
                  self.velocity_vector[0] += self.acelleration_vector[0] * update_time
                  self.velocity_vector[1] += self.acelleration_vector[1] * update_time
  
              if self.course_max_v:
                  self.course_deceleration = (np.sqrt(((self.projected_course_x ** 2) + (self.projected_course_y ** 2))) / 2)
  
              else:
                  self.course_deceleration = self.course_displacement - ((self.target_velocity ** 2) / (2 * self.acelleration_magnitude))
                  self.course_acelleration = ((self.target_velocity ** 2) - (self.velocity_magnitude ** 2)) / (2 * self.acelleration_magnitude)
  
              if -1 &lt;= self.course_displacement &lt;= 1:
                  self.course = False
  
          self.displacement_vector[0] += (self.velocity_vector[0] * update_time)
          self.displacement_vector[1] += (self.velocity_vector[1] * update_time)
  
  
      def draw(self):
  
          self.icon.update(x=int(round(self.displacement_vector[0])) ,y=int(round(self.displacement_vector[1])))
  
          if self.course_setting and self.player_ship:
              self.projected_angle = np.arctan2(((self.projected_heading[0]) - (self.icon.x)), ((self.projected_heading[1]) - (self.icon.y)))
  
              self.projected_heading_icon.update(x=self.projected_heading[0],y=self.projected_heading[1])
              self.projected_heading_icon.draw()
  
              pyglet.graphics.draw(2,pyglet.gl.GL_LINES,('v2f',(self.icon.x,self.icon.y,self.projected_heading_icon.x,self.projected_heading_icon.y)),('c3B',(0, 70, 0,0, 70, 0)))
  
              self.projected_deceleration_icon.x = int(round((self.projected_deceleration * np.sin(self.projected_angle)))) + self.icon.x
              self.projected_deceleration_icon.y = int(round((self.projected_deceleration * np.cos(self.projected_angle)))) + self.icon.y
  
              self.projected_deceleration_icon.draw()
  
              if not self.max_v:
                  self.projected_acelleration_icon.x = int(round(((self.projected_acelleration * np.sin(self.projected_angle))))) + self.icon.x
                  self.projected_acelleration_icon.y = int(round(((self.projected_acelleration * np.cos(self.projected_angle))))) + self.icon.y
  
                  self.projected_acelleration_icon.draw()
  
          if self.course:
              self.heading_icon.update(x=int(round(self.heading[0])) ,y=int(round(self.heading[1])))
              self.heading_icon.draw()
  
              pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.icon.x, self.icon.y, self.heading_icon.x, self.heading_icon.y)), ('c3B', (0, 70, 0, 0, 70, 0)))
  
              self.course_deceleration_icon.x = int(round(self.course_deceleration * np.sin(self.acelleration_angle))) + self.icon.x
              self.course_deceleration_icon.y = int(round(self.course_deceleration * np.cos(self.acelleration_angle))) + self.icon.y
  
              self.course_deceleration_icon.draw()
  
              if not self.course_max_v:
                  self.course_acelleration_icon.x = int(round(self.course_acelleration * np.sin(self.acelleration_angle)))
                  self.course_acelleration_icon.y = int(round(self.course_acelleration * np.cos(self.acelleration_angle)))
  
                  self.course_acelleration_icon.draw()
  
          self.icon.draw()
  
          if False:
              pygame.draw.line(surface, self.color, tuple(self.position), tuple((self.position[0] + int(15 * np.sin(self.velocity_angle)), self.position[1] + int(15 * np.cos(self.velocity_angle)))), 2)
  </code></pre>