2013-03-25 61 views
0

幫我理解爲什麼我的燈光處於固定位置,不會跟隨眼睛/相機。 openGL常見問題解答似乎表明,在對世界中的對象進行任何變換之前,您只需設置燈的位置,並且可以只設置一次......但燈仍然保持在固定的位置。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] 

回答

1

似乎有可能是兩個問題與您的代碼:

  1. 一般情況下,你想要把你的觀看轉變的模型視圖矩陣堆疊,與投影矩陣堆棧相比。 126行,你設置的gluLookAt確實應該在135行之後,在這裏你通過調用glLoadIdentity來重置模型視圖矩陣。原因在於照明法線由模型視圖矩陣的一部分轉換,不包括您的查看轉換可能會產生不良結果。其次,您在任何其他轉換(假設文件頂部的python代碼首先執行)之前指定燈的位置(通過調用glLight(GL_LIGHT0, GL_POSITION, ...);)。

當您指定一個光在這樣的位置,它就會被鎖定在眼座標(光的位置由矩陣在當你調用glLight(..., GL_POSITION, ...);模型 - 視圖矩陣頂部轉換),如果你想光與眼點一起移動,在您致電gluLookAt後指定它,這將改變光線的位置以便隨着眼睛移動。

+0

將gluLook放在135行後幾乎完全破壞它。我可以看到一條藍線,但無法通過移動來看到其他任何東西。 爲什麼#2不好?我以爲常見問題解答就是這樣做的,所以它會被鎖定在眼線上。我最初有我的glLightfv設置位置調用glMatrixMode(GL_MODELVIEW)/行136下,但這並沒有改變任何東西。 – user1612860 2013-03-25 04:42:56

+0

這是我讀的,它鏈接到的常見問題:http://stackoverflow.com/questions/5571534/opengl-light-source-that-follows-the-camera – user1612860 2013-03-25 04:52:53

+0

@ user1612860點#2地址燈「不是移動」。當你的代碼現在,燈的位置固定在眼座標上,所以你看到的結果應該像汽車前燈一樣;場景中的物體可能會四處移動,但光線始終來自相對於觀察者的相同方向。如果您想要「光線移動」,我將其解釋爲「相對於觀察者移動」,那麼在指定查看變換後您需要定位光線。 – radical7 2013-03-25 05:08:55