用OpenGL制作太阳能系统

时间:2018-03-11 11:40:28

标签: python opengl graphics 3d pyopengl

我正在尝试用OpenGL制作一个太阳系,但这个星球并不围绕着太阳旋转。这是围绕其他轴旋转的。如何解决这个问题?

首先,我画了一个太阳,然后,有第一个行星的旋转,平移和再次旋转。所以它应围绕太阳旋转并在它自己的轴上旋转,但这种情况并没有发生。

我也想制作一个行星旋转的圆圈。如何在XZ平面上制作圆圈(可能)

from __future__ import division
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

year = 0
day = 0

def init(): 
   glClearColor (0.0, 0.0, 0.0, 0.0)
   glShadeModel (GL_FLAT)


def display():

   global day, year

   glClear (GL_COLOR_BUFFER_BIT)

   glColor3f (1.0, 1.0, 0, 1)
   glPushMatrix()
   glutSolidSphere(1.0, 20, 16)   # draw sun

   glRotatef(year, 0.0, 1.0, 0.0)
   year = (year + 1) % 360

   glPushMatrix()
   glTranslatef(2.0, 0.0, 0.0)
   glRotatef(day, 0.0, 1.0, 0.0)
   day = (day + 1) % 360

   glColor3f (0, 0, 1.0);
   glutWireSphere(0.2, 10, 8)    # draw smaller planet
   glPopMatrix()

   glPushMatrix()
   glTranslatef(4.0, 0.0, 0.0)
   glRotatef(day, 0.0, 1.0, 0.0)
   glColor3f (1, 0, 0.0, 1)
   glutWireSphere(0.2, 10, 8)
   glPopMatrix()

   glPopMatrix()
   glutSwapBuffers()

   # delay
   for i in range(100000):
      pass

def reshape(w, h):
   glViewport (0, 0, w, h)
   glMatrixMode (GL_PROJECTION)
   glLoadIdentity ()
   gluPerspective(70.0, w/h, 1.0, 20.0)
   glMatrixMode(GL_MODELVIEW)
   glLoadIdentity()
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

glutInit()
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize(800, 800)
glutInitWindowPosition (100, 100)
glutCreateWindow("Transformation")
init ()
glutDisplayFunc(display)
glutIdleFunc(display)
glutReshapeFunc(reshape)
glutMainLoop()

1 个答案:

答案 0 :(得分:2)

  

行星应该落在太阳后面(看不见一段时间),然后回来后会看到它,但那不会发生。

您必须启用深度测试,并且必须清除深度缓冲区。

可以通过glEnable(GL_DEPTH_TEST)启用深度测试。默认深度函数glDepthFuncGL_LESS。这会导致跳过之前绘制的片段后面的片段:

在每帧之前,必须通过glClear(GL_DEPTH_BUFFER_BIT)清除深度缓冲区,以重新启动此过程。

display

的开头,将以下行添加到您的代码中
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glEnable( GL_DEPTH_TEST )

你需要创建一个带深度缓冲区的窗口(glutInitDisplayMode(GLUT_DEPTH)):

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)

查看预览:

enter image description here


  

你能说出如何在地球旋转的地方制作圆圈吗?

我建议使用time来设置模拟。以下示例显示了太阳,地球和月亮(当然,这是一个非常简化的模拟,具有完全错误的大小和距离关系):

import time

start_time = time.time()

def display():

    t = time.time() - start_time
    year_period = 5.0                  # 5 seconds for simulating one year 
    year     = (t / year_period)
    day      = 365 * year
    moon_sid = (365 / 27.3) * year

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
    glEnable( GL_DEPTH_TEST )

    glColor4f (1.0, 1.0, 0, 1)
    glPushMatrix()
    glutSolidSphere(1.0, 20, 16)             # sun

    glRotatef(year*360.0, 0.0, 1.0, 0.0)     # earth rotation around the sun 
    glTranslatef(3.0, 0.0, 0.0)              # earth location

    glPushMatrix()                           # push earth system 

    glPushMatrix()
    glRotatef(day*360.0, 0.0, 1.0, 0.0)      # earth spinn
    glRotatef(90-23.4, 1.0, 0.0, 0.0)        # earth axis
    glColor3f (0, 0, 1)                      # blue
    glutWireSphere(0.3, 10, 8)               # earth
    glPopMatrix()

    glPushMatrix()
    glRotatef(moon_sid*360.0, 0.0, 1.0, 0.0) # moon sidereal
    glTranslatef(1.0, 0.0, 0.0)              # distance moon to earth
    glRotatef(90, 1.0, 0.0, 0.0)
    glColor4f (0.4, 0.5, 0.6, 1)                         
    glutWireSphere(0.1, 10, 8)               # moon
    glPopMatrix()

    glPopMatrix()                            # pop earth system 

    glPopMatrix()
    glutSwapBuffers()

enter image description here