You need to enable JavaScript to run this app. 如何在Pygame+OpenGL场景中固定光源位置,实现旋转球体昼夜效果
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pygame+OpenGL场景中固定光源位置,实现旋转球体昼夜效果

问题解决方法

核心问题根源

你的代码存在两个核心错误导致光源随球体同步旋转:

  1. 矩阵栈用途错误:你将球体的平移、旋转、缩放等模型变换放到了GL_PROJECTION投影矩阵栈中,投影矩阵仅应该负责视口投影逻辑(比如glOrtho),所有物体的空间变换都应该放在GL_MODELVIEW模型视图矩阵栈中,矩阵栈用途混乱直接导致光照计算异常。
  2. 光源设置时机错误:你在应用球体旋转变换之前就设置了光源位置,OpenGL的glLightfv(GL_LIGHT0, GL_POSITION)会记录调用时的当前模型视图矩阵,将光源位置绑定到对应的坐标系下,你的设置时机导致光源被绑定到了球体的局部坐标系,自然会跟着球体一起旋转。

具体修改方案

直接替换你的esfep函数为以下内容即可:

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]
    # 方向光配置,w=0代表是平行光(模拟太阳光),前三个值为光照方向
    light_position =  [1, 0, 0, 0.0]
    
    # 第一步:设置投影矩阵,仅做投影变换
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(0,resol[0],resol[1],0,-resol[0],resol[1])
    
    # 第二步:切换到模型视图矩阵,初始加载单位矩阵(对应世界坐标系原点)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    
    # 第三步:在世界坐标系下设置固定光源,此时设置的光源位置不会随后续物体变换移动
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)
    
    # 第四步:仅在模型视图矩阵上应用球体的平移、旋转、缩放变换
    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])
    
    # 原有绘制逻辑保持不变
    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 

额外注意事项

你的原代码中sup_texture函数存在变量名笔误:定义的纹理ID变量为textID,但glBindTexture时使用了texID,需要统一变量名否则会运行报错。

如果需要模拟点光源效果,只需要将light_position的第四个参数改为1,前三个参数改为你期望的光源世界坐标即可,例如[1000, 0, 0, 1.0]就代表光源固定在世界坐标X轴1000的位置。

内容的提问来源于stack exchange,提问作者Calvarez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 17:54:03