0

帮助我了解为什么我的灯处于固定位置并且不会跟随眼睛/相机。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()

矢量数学.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]
4

1 回答 1

1

您的代码似乎可能存在两个问题:

  1. 通常,与投影矩阵堆栈相比,您希望将查看转换放在模型视图矩阵堆栈上。第 126 行,你gluLookAt真正设置的地方应该在第 135 行之后,在那里你通过调用来重置模型视图矩阵glLoadIdentity。这样做的原因是光照法线由模型视图矩阵的一部分进行转换,不包括您的视图转换可能会产生不良结果。

  2. 其次,您glLight( GL_LIGHT0, GL_POSITION, ...);在任何其他转换之前(假设文件顶部的 python 代码首先执行)指定灯光的位置(通过调用)。

当您以这种方式指定灯光的位置时,它会锁定在眼睛坐标中(当您调用时,灯光的位置由模型视图矩阵顶部的矩阵转换glLight( ..., GL_POSITION, ... );)如果您希望灯光随眼睛点移动,在调用 之后指定它gluLookAt,这将改变灯光的位置以随眼睛移动。

于 2013-03-25T04:35:28.437 回答