Reputation: 3
Help me understand why my light is at a fixed position and won't follow the eye/camera. The openGL FAQ seems to say you just set the light's position before doing any transforms for the objects in your world, and that you can set it only once... But the light still stays at a fixed position.
import pyglet
from pyglet.gl import *
from pyglet.window import key
from pyglet.graphics import draw
from vector_math import *
win = pyglet.window.Window()
keys = key.KeyStateHandler()
win.push_handlers(keys)
rtri = 0.0
eye_vec = [0, 0, 2]
center_vec = [0, 0, 0]
up_vec = [0, 1, 0]
center_dist = 3.0
glClearColor(0.0, 0.0, 0.0, 0.0) # This Will Clear The Background Color To Black
glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS) # The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST) # Enables Depth Testing
glEnable(GL_LINE_STIPPLE)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glShadeModel(GL_SMOOTH) # Enables Smooth Color Shading
glViewport(0,0,win.width,win.height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity() # Reset The Projection Matrix
# Calculate The Aspect Ratio Of The Window
gluPerspective(45.0, float(win.width) / float(win.height), 0.01, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glPushMatrix()
glTranslatef(0.0, 0.0, 0.5)
glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat * 4)(0.0, 0.0, 0.0, 1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat * 3)(40.0, 40.0, 40.0))
glLightfv(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, (GLfloat * 1) (.35))
glEnable(GL_LIGHT0)
glPopMatrix()
def move_eye_in(going_in):
global center_dist
global eye_vec
center_dist += (-0.3 if going_in else 0.3)
eye_vec = vec_scalar_mul(vec_normalize(eye_vec), center_dist)
def rotate_eye(is_left):
global eye_vec
print 'center_vec', center_vec
print 'eye_vec', eye_vec
center_minus_eye = vec_sub(center_vec, eye_vec)
print 'center_minus_eye', center_minus_eye
print 'up_vec', up_vec
look_vec = vec_scalar_mul(vec_normalize(vec_cross(up_vec, center_minus_eye)), 0.5)
print 'look_vec', look_vec
eye_plus_look_vec = vec_add(eye_vec, look_vec) if is_left else vec_sub(eye_vec, look_vec)
print 'eye_plus_look_vec', eye_plus_look_vec
eye_vec = vec_scalar_mul(vec_normalize(eye_plus_look_vec), center_dist)
def move_eye(x, y, z):
eye_vec[0] += x
eye_vec[1] += y
eye_vec[2] += z
def draw_pyramid(dim):
glBegin(GL_TRIANGLES)
glColor3f(1.0, 1.0, 0.0); # yellow
glVertex3f(0.0, dim, 0.0); # Top Of Triangle (Right)
glVertex3f(-dim, -dim, dim); # Left Of Triangle (Right)
glVertex3f(dim, -dim, dim);
glColor3f(1.0, 0.0, 0.0); # red
glVertex3f(0.0, dim, 0.0); # Top Of Triangle (Right)
glVertex3f(dim, -dim, dim); # Left Of Triangle (Right)
glVertex3f(dim, -dim, -dim);
glColor3f(0.0, 1.0, 0.0); # green
glVertex3f(0.0, dim, 0.0); # Top Of Triangle (Back)
glVertex3f(dim, -dim, -dim); # Left Of Triangle (Back)
glVertex3f(-dim, -dim, -dim)
glColor3f(0.0, 0.0, 1.0); # blue
glVertex3f(0.0, dim, 0.0); # Top Of Triangle (Left)
glVertex3f(-dim, -dim, -dim); # Left Of Triangle (Left)
glVertex3f(-dim, -dim, dim);
glEnd()
def makeUnitLineGrid(dim):
line_coords = []
for a in range(dim + 1):
for b in range(dim + 1):
line_coords.extend([
# vert lines
# a, 0, b,
# a, dim, b,
# horiz lines
0, a, b,
dim, a, b,
# depth lines
a, b, 0,
a, b, dim])
return line_coords
line_coords = makeUnitLineGrid(20)
@win.event
def on_draw():
handle_down_keys()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(90.0, float(win.width) / float(win.height), 0.001, 100.0)
# glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
global rtri
rtri += 1
gluLookAt(
eye_vec[0], eye_vec[1], eye_vec[2],
center_vec[0], center_vec[1], center_vec[2],
up_vec[0], up_vec[1], up_vec[2])
glPushMatrix()
# glTranslatef(0, 0, -0.5)
# glRotatef(rtri, 0.0, 0.0, 1.0)
# glRotatef(-90, 1.0, 0.0, 0.0)
glScalef(1/5.0, 1/5.0, 1/5.0)
draw_pyramid(3.0)
glPopMatrix()
glPushMatrix()
glTranslatef(3, 0, 0)
glRotatef(90, 0.0, 1.0, 0.0)
glScalef(1/5.0, 1/5.0, 1/5.0)
draw_pyramid(3.0)
glPopMatrix()
glPushMatrix()
glLineStipple(1, 0xFFF)
glTranslatef(-2.5, -2.5, -2.5)
glScalef(1.5, 1.5, 1.5)
glColor4f(1.0, 1.0, 0.0, 0.1); # yellow
glEnable(GL_LIGHTING)
draw(len(line_coords) / 3, GL_LINES,
('v3f', line_coords),
# ('c3B', colors),
)
glDisable(GL_LIGHTING)
glPopMatrix()
def handle_down_keys():
if keys[key.PAGEUP]:
move_eye_in(True)
elif keys[key.PAGEDOWN]:
move_eye_in(False)
elif keys[key.LEFT]:
rotate_eye(True)
elif keys[key.RIGHT]:
rotate_eye(False)
elif keys[key.UP]:
move_eye(0, 0.5, 0)
elif keys[key.DOWN]:
move_eye(0, -0.5, 0)
pyglet.app.run()
vector_math.py
import math
def vec_add(a, b):
return [a[0] + b[0], a[1] + b[1], a[2] + b[2]]
def vec_sub(a, b):
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
def vec_cross(a, b):
return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]
def vec_normalize(a):
mag = math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])
return [a[0] / mag, a[1] / mag, a[2] / mag]
def vec_scalar_mul(a, n):
return [a[0] * n, a[1] * n, a[2] * n]
Upvotes: 0
Views: 1413
Reputation: 9124
There seem to potentially be two problems with your code:
Generally, you want to put your viewing transformation on the model-view matrix stack, as compared to the projection matrix stack. Line 126, where you set gluLookAt
really should go after line 135, where you reset the model-view matrix by calling glLoadIdentity
. The reason for this is that lighting normals are transformed by the part of the model-view matrix, and not including your viewing transform will likely yield undesirable results.
Second, you're specifying the light's position (by calling glLight( GL_LIGHT0, GL_POSITION, ...);
) before any other transformation (assuming that the python code at the top of the files executes first).
When you specify a light's position in this manner, it gets locked in eye coordinates (a light's position is transformed by the matrix at the top of the model-view matrix when you call glLight( ..., GL_POSITION, ... );
) If you want the light to move with the eye point, specify it after your call to gluLookAt
, which will transform the light's position to move along with the eye.
Upvotes: 1