簡體   English   中英

openGL燈不會隨相機移動

[英]openGL light won't move with camera

幫助我了解為什么我的燈光固定在一個位置,而不會跟隨眼睛/相機。 openGL FAQ似乎表明您只是在對世界中的對象進行任何變換之前設置了燈光的位置,並且只能設置一次...但是燈光仍然保持在固定位置。

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. 通常,與投影矩陣堆棧相比,您希望將視圖轉換放在模型視圖矩陣堆棧上。 第126行,您設置gluLookAt實際上應該在第135行之后,您通過調用glLoadIdentity重置了模型視圖矩陣。 其原因是照明法線由模型視圖矩陣的一部分進行變換,並且不包括您的視圖變換可能會產生不良結果。

  2. 其次,您要在其他任何轉換之前指定燈光的位置(通過調用glLight( GL_LIGHT0, GL_POSITION, ...); )(假設首先執行文件頂部的python代碼)。

當您以這種方式指定光源的位置時,它會鎖定在眼睛坐標中(當調用glLight( ..., GL_POSITION, ... );光源的位置將由模型視圖矩陣頂部的矩陣進行轉換glLight( ..., GL_POSITION, ... ); )如果您希望燈光隨眼點移動,請在調用gluLookAt之后指定它,它將改變燈光的位置以隨眼睛移動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM