微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决球体旋转时如何设置固定的光?

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

我知道如果一个物体旋转,所有的“坐标系”都会移动,而不是物体,所以,我认为光是固定在系统上的。我试图找到最初使用三角法放置灯光的点,但没有得到肯定的结果。如何将灯光放置在固定位置以达到日/夜效果

这是我的代码

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,GL_RGB,surfrc[2],surfrc[3],GL_UNSIGNED_BYTE,rgbsurf)
    return textID

def texture(arch,arch2):
    textID = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D,textID)
    glPixelStorei(GL_UNPACK_ALIGNMENT,GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D,GL_LINEAR_MIPMAP_LINEAR)
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE)
    glTexImage2D(GL_TEXTURE_2D,arch2[0],arch2[1],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,0); glVertex2f(1,1)
    glEnd()
    gldisable(GL_TEXTURE_2D)

def esfep(vesf,resol,texture,rotpt,punt,tama):
    light_ambient =  [0.0,0.0,1.0]
    light_diffuse =  [1.0,1.0,1.0]
    light_position =  [1,1,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],-resol[0],resol[1])
    glTranslatef(float(punt[0]),float(punt[1]),-resol[1]) 
    glrotatef(270,0)
    glrotatef(rotpt,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,planpres,(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)

解决方法

glLighv被调用时,光源位置(GL_POSITION)和方向(GL_SPOT_DIRECTION)由当前模型视图矩阵转换。在调用 glLight 之前,确保模型视图矩阵是 Identity matrix,但将转换设置为模型视图矩阵:

def esfep(vesf,resol,texture,rotpt,punt,tama):
    light_ambient =  [0.0,0.0,1.0]
    light_diffuse =  [1.0,1.0,1.0]
    light_position =  [1,1,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],-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,0)
    glRotatef(rotpt,1)
    glScalef(1*tama/resol[1],1*tama/resol[1],1*tama/resol[1])
    
    # [...]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。