帮助我理解为什么我的光线处于固定位置并且不会跟随眼睛/相机。 openGL常见问题解答似乎只是说你在为你的世界中的物体进行任何变换之前设置灯的位置,并且你只能设置它一次......但是灯仍然停留在固定的位置。
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]
答案 0 :(得分:1)
您的代码可能存在两个问题:
通常,与投影矩阵堆栈相比,您希望将查看转换放在模型视图矩阵堆栈上。您设置gluLookAt
的第126行确实应该在第135行之后,您可以通过调用glLoadIdentity
来重置模型视图矩阵。这样做的原因是照明法线由模型 - 视图矩阵的一部分变换,不包括您的观察变换可能会产生不良结果。
其次,您在任何其他转换之前指定灯光的位置(通过调用glLight( GL_LIGHT0, GL_POSITION, ...);
)(假设文件顶部的python代码首先执行)。
当您以这种方式指定灯光的位置时,它会被锁定在眼睛坐标中(当您调用{{{}时,光线的位置会被模型视图矩阵顶部的矩阵变换1}})如果您希望灯光与眼点一起移动,请在致电glLight( ..., GL_POSITION, ... );
后指定它,这将改变灯光的位置以随着眼睛移动。