【问题标题】:Making a Solar System in OpenGL在 OpenGL 中制作太阳系
【发布时间】:2018-08-19 13:11:36
【问题描述】:

我正在尝试在 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()

【问题讨论】:

标签: python opengl graphics 3d pyopengl


【解决方案1】:

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

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

深度测试可以通过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)

查看预览:



你能告诉我如何在行星旋转的地方画圈吗?

我建议使用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()

【讨论】:

  • 你能告诉我如何在地球公转的地方画圈吗?
猜你喜欢
  • 2013-04-19
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多