Search code examples
pythonopenglpyopenglopengl-compat

OPENGL Light Rotation


I am trying to set one stationary light source. In my program I have a cube which can be rotated.It seems like the light source is rotating too. But it should not

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
lightType = [-2.0, 0.0, -3.0, 1.0]
glLightfv(GL_LIGHT0, GL_POSITION, lightType)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
m = accum.get_rotation_matrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadMatrixf(m)
draw_cube()

UPD. Another example

def init():
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    lightType = [0, 0, 4, 1]
    glLightfv(GL_LIGHT0, GL_POSITION, lightType)
    glLightfv(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 0))
    glLightfv(GL_LIGHT0, GL_DIFFUSE, (0, 0, 0, 0))
    glLightfv(GL_LIGHT0, GL_SPECULAR, (1, 1, 1, 1))
    glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, 180)
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (0, 0, 1, 1))
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)

I expect that one part of the cube will always be lighted, but it os not: after some rotation cube is not lighted (pictures 1 and 2). I would like, for example, some part of the front face of the cube to be always lighted, regardless cube's rotation

enter image description here

enter image description here


Solution

  • When the light position is set, then the position is transformed by the current model view matrix (GL_MODELVIEW). See glLight and glMatrixMode.
    If the position is set, before the view matrix is set (model view is the Identity matrix), then the light position is not transformed and is set in view space. Hence the light moves with the point of view and is anchored to the camera.
    If you want to set the light position in world space, then you have to set the view matrix before the light position is set. Thus the the light position is transformed by the view matrix (The vie matrix transforms form world space to view space).

    glMatrixMode(GL_MODELVIEW)
    glLoadMatrixf(viewMatrix)
    
    lightType = [-2.0, 0.0, -3.0, 1.0]
    glLightfv(GL_LIGHT0, GL_POSITION, lightType)
    
    glMultMatrixf(modelMatrix)
    draw_cube()