我需要你的帮助。使用 python,我必须通过 phong 模型实现我的 3D 形状的照明。我的图是一个三角形的二十面体。我能够构建这个形状,找到顶点的坐标,并计算出每个面的法线。
我用过pygame,pyopengl。
为了实现 phong 光照模型,我设法制作了环境光照和漫反射光照,但我不知道要使用哪些函数来实现镜面光照。
我试图用不同的参数应用诸如 glMaterialfv() 之类的函数,但对我来说没有用。
这是我的代码:
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
verticies = (
(0, - 0, 1.15894198417663574),
(0.63384598493576048, -0.63384598493576048, 0.63384598493576048),
(0.81949597597122192, 0, 0.81949597597122192),
(1.15894198417663574, 0, -0),
(0.81949597597122192, 0.81949597597122192, -0),
(0.81949597597122192, 0, -0.81949597597122192),
(0.63384598493576048, 0.63384598493576048, 0.63384598493576048),
(0.81949597597122192, -0.81949597597122192, 0),
(-0, 0.81949597597122192, 0.81949597597122192),
(-0.81949597597122192, 0, 0.81949597597122192),
(0.63384598493576048, 0.63384598493576048, -0.63384598493576048),
(0, 0, -1.15894198417663574),
(0, -0.81949597597122192, -0.81949597597122192),
(-0.81949597597122192, 0, -0.81949597597122192),
(0, 0.81949597597122192, -0.81949597597122192),
(0.63384598493576048, -0.63384598493576048, -0.63384598493576048),
(-0, 1.15894198417663574, 0),
(-0.81949597597122192, 0.81949597597122192, 0),
(-1.15894198417663574, 0, 0),
(-0.63384598493576048, 0.63384598493576048, 0.63384598493576048),
(0, -1.15894198417663574, 0),
(-0.81949597597122192, -0.81949597597122192, 0),
(0, -0.81949597597122192, 0.81949597597122192),
(-0.63384598493576048, -0.63384598493576048, 0.63384598493576048),
(-0.63384598493576048, 0.63384598493576048, -0.63384598493576048),
(-0.63384598493576048, -0.63384598493576048, -0.63384598493576048),
)
surfaces = (
(20, 21, 25, 12),
(21, 25, 13, 18),
(17, 24, 14, 16),
(18, 13, 24, 17),
(16, 14, 10, 4),
(3, 5, 15, 7),
(0, 2, 6, 8),
(0, 2, 1, 22),
(0, 22, 23, 9),
(0, 9, 19, 8),
(13, 11, 12, 25),
(11, 13, 24, 14),
(11, 14, 10, 5),
(11, 5, 15, 12),
(3, 5, 10, 4),
(17, 18, 9, 19),
(17, 19, 8, 16),
(16, 8, 6, 4),
(3, 2, 6, 4),
(3, 2, 1, 7),
(7, 1, 22, 20),
(20, 21, 23, 22),
(9, 23, 21, 18),
(15, 7, 20, 12),
)
normals = [
(-0.35740624923526854, -0.8628558767968414, -0.3574080425574267),
(-0.8628548655932644, -0.3574083665235253, -0.3574083665235253),
(-0.3574083665235253, 0.8628548655932644, -0.3574083665235253),
(-0.8628558767968414, 0.3574080425574267, -0.35740624923526854),
(0.3574080425574267, 0.8628558767968414, -0.35740624923526854),
(0.8628558767968414, -0.3574080425574267, -0.35740624923526854),
(0.35740624923526854, 0.3574080425574267, 0.8628558767968414),
(0.35740624923526854, -0.3574080425574267, 0.8628558767968414),
(-0.3574080425574267, -0.35740624923526854, 0.8628558767968414),
(-0.35740624923526854, 0.3574080425574267, 0.8628558767968414),
(-0.35740647831364963, -0.35740647831364963, -0.8628564298415289),
(-0.35740624923526854, 0.3574080425574267, -0.8628558767968414),
(0.3574080425574267, 0.35740624923526854, -0.8628558767968414),
(0.35740624923526854, -0.3574080425574267, -0.8628558767968414),
(0.8628558767968414, 0.3574080425574267, -0.35740624923526854),
(-0.8628564298415289, 0.35740647831364963, 0.35740647831364963),
(-0.3574083665235253, 0.8628548655932644, 0.3574083665235253),
(0.3574080425574267, 0.8628558767968414, 0.35740624923526854),
(0.8628558767968414, 0.3574080425574267, 0.35740624923526854),
(0.8628558767968414, -0.3574080425574267, 0.35740624923526854),
(0.3574083665235253, -0.8628548655932644, 0.3574083665235253),
(-0.35740624923526854, -0.8628558767968414, 0.3574080425574267),
(-0.8628548655932644, -0.3574083665235253, 0.3574083665235253),
(0.35740624923526854, -0.8628558767968414, -0.3574080425574267)
]
colors = (
(1,1,1),
(0,1,0),
(0,0,1),
(0,1,0),
(0,0,1),
(1,0,1),
(0,1,0),
(1,0,1),
(0,1,0),
(0,0,1),
)
edges = (
(16, 17),
(17, 18),
(18, 21),
(20, 21),
(3, 4),
(4, 16),
(7, 3),
(20, 7),
(0, 2),
(0, 9),
(0, 22),
(0, 8),
(11, 13),
(11, 12),
(11, 14),
(2, 3),
(8, 16),
(9, 18),
(22, 20),
(2, 1),
(1, 22),
(1, 7),
(5, 11),
(5, 15),
(15, 12),
(15, 7),
(5, 3),
(12, 20),
(16, 14),
(22, 23),
(23, 9),
(23, 21),
(13, 24),
(14, 24),
(17, 24),
(13, 25),
(12, 25),
(25, 21),
(13, 18),
(8, 6),
(2, 6),
(6, 4),
(10, 4),
(14, 10),
(5, 10),
(17, 19),
(19, 9),
(19, 8),
)
def Cube():
glBegin(GL_QUADS)
for i_surface, surface in enumerate(surfaces):
x = 0
glNormal3fv(normals[i_surface])
for vertex in surface:
#x+=1
glColor3fv(colors[x])
glVertex3fv(verticies[vertex])
glEnd()
glColor3fv(colors[0])
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()
def main():
global surfaces
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
clock = pygame.time.Clock()
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0, 0, -5)
# Источник света - "от нас"
glLight(GL_LIGHT0, GL_POSITION, (0, 0, 1, 0.4))
# Ambient lighting
glLightfv(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 1))
# Diffuse lighting
glLightfv(GL_LIGHT0, GL_DIFFUSE, (0, 0.5, 0.1, 0))
#---------------------------------Specular Lighting------------It does not work!!!-----------
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (1,1,1,0))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128)
#--------------------------------------------------------------------------------------------
glEnable(GL_DEPTH_TEST)
while True:
# Обрабатываем события
for event in pygame.event.get():
# Если нажимаем крестик на окошке - выходим
if event.type == pygame.QUIT:
pygame.quit()
quit()
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 )
#glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
glRotatef(10, 0, 1, 0)
elif keys[pygame.K_RIGHT]:
glRotatef(-10, 0, 1, 0)
elif keys[pygame.K_UP]:
glRotatef(10, 1, 0, 0)
elif keys[pygame.K_DOWN]:
glRotatef(-10, 1, 0, 0)
Cube()
glDisable(GL_LIGHT0)
glDisable(GL_LIGHTING)
glDisable(GL_COLOR_MATERIAL)
pygame.display.flip()
clock.tick(20)
if __name__ == '__main__':
main()