当球体旋转时,如何设置固定的灯光?

2024-10-03 23:17:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个球体旋转的场景,就像地球和太阳一样。我可以激活对象上的灯光,但我注意到旋转时灯光会随着对象移动,永远照亮同一个面。我想将灯光设置在一个固定点上,这样,当“地球”旋转时,照明将固定,从而产生白天和黑夜的效果

我知道如果一个物体旋转,所有的“坐标系”都会移动,而不是物体,所以,我认为光线是固定在这个系统上的。我试着用三角学找到光线最初被放置的位置,但没有得到积极的结果。如何将灯光放置在固定位置以达到白天/夜间效果

这是我的代码:

import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
#<some other libraries imports>

def sup_texture(surf):
    rgbsurf = pygame.image.tostring(surf, 'RGB')
    textID = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texID)
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    surfrc = surf.get_rect()
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surfrc[2], surfrc[3], 0, GL_RGB, GL_UNSIGNED_BYTE, rgbsurf)
    return textID

def texture(arch,arch2):
    textID = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, textID)
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,arch2[0], arch2[1], 0, GL_RGB, GL_UNSIGNED_BYTE, arch)
    glGenerateMipmap(GL_TEXTURE_2D)
    return textID

def oglprint(sup):
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glDisable(GL_LIGHTING)
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, sup)
    glBegin(GL_QUADS)
    glTexCoord2f(0, 0); glVertex2f(-1, 1)
    glTexCoord2f(0, 1); glVertex2f(-1, -1)
    glTexCoord2f(1, 1); glVertex2f(1, -1)
    glTexCoord2f(1, 0); glVertex2f(1, 1)
    glEnd()
    glDisable(GL_TEXTURE_2D)

def esfep(vesf,resol,texture,rotpt,punt,tama):
    light_ambient =  [0.0, 0.0, 0.0, 1.0]
    light_diffuse =  [1.0, 1.0, 1.0, 1.0]
    light_position =  [1, 1, 0, 0.0]
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    rotpt = rotpt + vesf  
    glOrtho(0,resol[0],resol[1],0,-resol[0],resol[1])
    glTranslatef(float(punt[0]),float(punt[1]),-resol[1]) 
    glRotatef(270, 1, 0, 0)
    glRotatef(rotpt, 0, 0, 1)
    glScalef(1*tama/resol[1],1*tama/resol[1],1*tama/resol[1])
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glEnable(GL_COLOR_MATERIAL)
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE )
    esf = gluNewQuadric()
    gluQuadricTexture(esf, GL_TRUE)
    glDisable(GL_DEPTH_TEST)
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, texture)
    gluSphere(esf,round(resol[1]/2), 50, 50)
    gluDeleteQuadric(esf)
    glDisable(GL_TEXTURE_2D)
    glDisable(GL_DEPTH_TEST) 
    return rotpt 

pygame.init()

resol = (1366,768)
opcp = pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.OPENGL | pygame.FULLSCREEN
displayG = pygame.display.set_mode(resol,opcp)
display = pygame.Surface(resol)

imgpl = pygame.image.load('texture.jpg')
imgplt = imgpl.get_size()
imgpl = pygame.transform.smoothscale(imgpl,(1000,500))
imgpltd = pygame.image.tostring(imgpl,'RGB',False)
planpres = texture(imgpltd,imgplt)
rotpt = randint(270,360)
timer = pygame.time.Clock()
RE = tab(display)
while True:                
    #<some pygame stuff and display blitting>
    opsurf = pygame.Surface.copy(display)
    pantsp = sup_texture(opsurf)
    botact = 1
    while botact == 1:
        timer.tick(20) 
        oglprint(pantsp)                  
        rotpt = esfep(0.05,resol,planpres,rotpt,(0,resol[1] + resol[1]/4.5),1000)  #this is the printing of the sphere. 
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit() 
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x_mouse, y_mouse = pygame.mouse.get_pos()
                dot = (x_mouse,y_mouse)
                for x in range(len(RE)):
                    if RE[x].collidepoint(dot):
                        #<some stuff>
                        botact = 0
                        glDeleteTextures(pantsp)

Tags: displayrgbpygamelightglmousetextureglenable
1条回答
网友
1楼 · 发布于 2024-10-03 23:17:54

调用^{}时,灯光位置(GL_POSITION)和方向(GL_SPOT_DIRECTION)由当前模型视图矩阵进行变换。在调用glLight之前,确保模型视图矩阵是Identity matrix,但要将转换设置为模型视图矩阵:

def esfep(vesf,resol,texture,rotpt,punt,tama):
    light_ambient =  [0.0, 0.0, 0.0, 1.0]
    light_diffuse =  [1.0, 1.0, 1.0, 1.0]
    light_position =  [1, 1, 0, 0.0]
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse)
    
    # set projection matrix
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(0,resol[0],resol[1],0,-resol[0],resol[1])
    
    # set model view identity matrix
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    # set light position (multiplied by identity matrix)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)
    
    # set model view transformations
    rotpt = rotpt + vesf  
    glTranslatef(float(punt[0]),float(punt[1]),-resol[1]) 
    glRotatef(270, 1, 0, 0)
    glRotatef(rotpt, 0, 0, 1)
    glScalef(1*tama/resol[1],1*tama/resol[1],1*tama/resol[1])
    
    # [...]

相关问题 更多 >