Pyopengl:即使在中心,照明也不会向所有方向传播
Pyopengl: Lighting does not go in all directions even though it is in the center
OpenGL 中的光照仅朝向球体的左侧,尽管光线不可能到达那里,因为它位于球体的右侧。光线也朝向立方体的背面,但它应该朝向各个方向,因为它位于立方体的中间。如何让光线朝各个方向而不是一个方向照射?
完整代码:
import random
import time
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
width = 500
height = 500
random_number = 0
turned = 0
angle = 0
switch = False
vertices = [(-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5), (-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)]
faces = [(4, 0, 3, 7), (1, 0, 4, 5), (0, 1, 2, 3), (1, 5, 6, 2), (3, 2, 6, 7), (5, 4, 7, 6)]
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1)]
def draw_shapes():
global turned, switch, random_number, angle
glDisable(GL_TEXTURE_2D)
glPushMatrix()
if turned >= 90:
random_number = random.randint(0, 2)
turned = angle = 0
if random_number == 0:
glRotatef(angle, 0, 1, 0)
elif random_number == 1:
glRotatef(angle, 1, 0, 0)
else:
glRotatef(angle, 0, 0, 1)
turned += 1
angle += 1
# glColor3fv((.16, .16, .16))
glBegin(GL_QUADS)
for i, face in enumerate(faces):
for surftex, vertex in enumerate(face):
if surftex == 0:
glTexCoord2f(1.0, 1.0)
elif surftex == 1:
glTexCoord2f(1.0, 0.0)
elif surftex == 2:
glTexCoord2f(0.0, 0.0)
elif surftex == 3:
glTexCoord2f(0.0, 1.0)
glVertex3fv(vertices[vertex])
glEnd()
glPopMatrix()
glDisable(GL_TEXTURE_2D)
glPushMatrix()
# glColor3fv((.16, .16, .16))
glTranslatef(-3, 0, 0)
Quadric = gluNewQuadric()
gluSphere(Quadric, 1, 50, 50)
glPopMatrix()
def showScreen():
global width, height
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
glLightfv(GL_LIGHT0, GL_POSITION, (0, 0, 0, 1)) # point light from the left, top, front
glLightfv(GL_LIGHT0, GL_AMBIENT, (1, 0, 0, 1))
glEnable(GL_DEPTH_TEST)
draw_shapes()
glutSwapBuffers()
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
glutReshapeWindow(width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, (width / height), 0.0001, 1000)
glViewport(0, 0, width, height)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -7)
# glRotatef(3, 1, 0, 0)
def keyboard(key, x_pos, y_pos):
print(key, x_pos, y_pos)
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
wind = glutCreateWindow("OpenGL")
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutReshapeFunc(reshapeWindow)
glutKeyboardFunc(keyboard)
gluPerspective(45, (width / height), 0.0001, 100)
while True:
glutMainLoopEvent()
glutPostRedisplay()
time.sleep(0.01)
立方体是光源,位于场景的中心。球体位于立方体的左侧,并在右侧发光。这似乎是正确的。请注意,光线没有被物体阻挡。光线取决于表面的法向量。因此你需要设置法向量 glNormal
(See also How does the calculation of the light model work in a shader program?):
vertices = [(-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5), (-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)]
faces = [(4, 0, 3, 7), (1, 0, 4, 5), (0, 1, 2, 3), (1, 5, 6, 2), (3, 2, 6, 7), (5, 4, 7, 6)]
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1)]
textureCoords = [(1, 1), (1, 0), (0, 0), (0, 1)]
normals = [(-1, 0, 0), (0, -1, 0), (0, 0, -1), (1, 0, 0), (0, 1, 0), (0, 0, 1)]
def draw_shapes():
# [...]
glBegin(GL_QUADS)
for i, face in enumerate(faces):
glNormal3fv(normals[i])
for surftex, vertex in enumerate(face):
glTexCoord2fv(textureCoords[surftex])
glVertex3fv(vertices[vertex])
glEnd()
# [...]
仅当光矢量的方向与法线矢量的方向相反时,表面才会被照亮。如果您还希望背面发光,则需要设置 GL_LIGHT_MODEL_TWO_SIDE
(参见 glLightModelfv
):
glLightModeliv(GL_LIGHT_MODEL_TWO_SIDE, 1)
OpenGL 中的光照仅朝向球体的左侧,尽管光线不可能到达那里,因为它位于球体的右侧。光线也朝向立方体的背面,但它应该朝向各个方向,因为它位于立方体的中间。如何让光线朝各个方向而不是一个方向照射?
完整代码:
import random
import time
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
width = 500
height = 500
random_number = 0
turned = 0
angle = 0
switch = False
vertices = [(-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5), (-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)]
faces = [(4, 0, 3, 7), (1, 0, 4, 5), (0, 1, 2, 3), (1, 5, 6, 2), (3, 2, 6, 7), (5, 4, 7, 6)]
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1)]
def draw_shapes():
global turned, switch, random_number, angle
glDisable(GL_TEXTURE_2D)
glPushMatrix()
if turned >= 90:
random_number = random.randint(0, 2)
turned = angle = 0
if random_number == 0:
glRotatef(angle, 0, 1, 0)
elif random_number == 1:
glRotatef(angle, 1, 0, 0)
else:
glRotatef(angle, 0, 0, 1)
turned += 1
angle += 1
# glColor3fv((.16, .16, .16))
glBegin(GL_QUADS)
for i, face in enumerate(faces):
for surftex, vertex in enumerate(face):
if surftex == 0:
glTexCoord2f(1.0, 1.0)
elif surftex == 1:
glTexCoord2f(1.0, 0.0)
elif surftex == 2:
glTexCoord2f(0.0, 0.0)
elif surftex == 3:
glTexCoord2f(0.0, 1.0)
glVertex3fv(vertices[vertex])
glEnd()
glPopMatrix()
glDisable(GL_TEXTURE_2D)
glPushMatrix()
# glColor3fv((.16, .16, .16))
glTranslatef(-3, 0, 0)
Quadric = gluNewQuadric()
gluSphere(Quadric, 1, 50, 50)
glPopMatrix()
def showScreen():
global width, height
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
glLightfv(GL_LIGHT0, GL_POSITION, (0, 0, 0, 1)) # point light from the left, top, front
glLightfv(GL_LIGHT0, GL_AMBIENT, (1, 0, 0, 1))
glEnable(GL_DEPTH_TEST)
draw_shapes()
glutSwapBuffers()
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
glutReshapeWindow(width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, (width / height), 0.0001, 1000)
glViewport(0, 0, width, height)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -7)
# glRotatef(3, 1, 0, 0)
def keyboard(key, x_pos, y_pos):
print(key, x_pos, y_pos)
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
wind = glutCreateWindow("OpenGL")
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutReshapeFunc(reshapeWindow)
glutKeyboardFunc(keyboard)
gluPerspective(45, (width / height), 0.0001, 100)
while True:
glutMainLoopEvent()
glutPostRedisplay()
time.sleep(0.01)
立方体是光源,位于场景的中心。球体位于立方体的左侧,并在右侧发光。这似乎是正确的。请注意,光线没有被物体阻挡。光线取决于表面的法向量。因此你需要设置法向量 glNormal
(See also How does the calculation of the light model work in a shader program?):
vertices = [(-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5), (-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)]
faces = [(4, 0, 3, 7), (1, 0, 4, 5), (0, 1, 2, 3), (1, 5, 6, 2), (3, 2, 6, 7), (5, 4, 7, 6)]
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1)]
textureCoords = [(1, 1), (1, 0), (0, 0), (0, 1)]
normals = [(-1, 0, 0), (0, -1, 0), (0, 0, -1), (1, 0, 0), (0, 1, 0), (0, 0, 1)]
def draw_shapes():
# [...]
glBegin(GL_QUADS)
for i, face in enumerate(faces):
glNormal3fv(normals[i])
for surftex, vertex in enumerate(face):
glTexCoord2fv(textureCoords[surftex])
glVertex3fv(vertices[vertex])
glEnd()
# [...]
仅当光矢量的方向与法线矢量的方向相反时,表面才会被照亮。如果您还希望背面发光,则需要设置 GL_LIGHT_MODEL_TWO_SIDE
(参见 glLightModelfv
):
glLightModeliv(GL_LIGHT_MODEL_TWO_SIDE, 1)