在 OpenGL 中制作太阳系
Making a Solar System in OpenGL
我正尝试在 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()
Planet should go behind the sun (invisible for some time) and then it would be visible after coming back, but that' not happening.
您必须启用深度测试并且必须清除深度缓冲区。
可以通过glEnable(GL_DEPTH_TEST)
. The default depth function glDepthFunc
启用深度测试是GL_LESS
。这会导致跳过之前绘制的片段后面的片段:
在每一帧之前,必须通过glClear(GL_DEPTH_BUFFER_BIT)
清除深度缓冲区以重新启动此过程。
将以下行添加到您的代码中,在 display
的开头:
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glEnable( GL_DEPTH_TEST )
当然你必须创建一个 window 和深度缓冲区 (glutInitDisplayMode(GLUT_DEPTH)
):
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
查看预览:
Can you also tell how to make circle where the planet is revolving?
我建议使用 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()
我正尝试在 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()
Planet should go behind the sun (invisible for some time) and then it would be visible after coming back, but that' not happening.
您必须启用深度测试并且必须清除深度缓冲区。
可以通过glEnable(GL_DEPTH_TEST)
. The default depth function glDepthFunc
启用深度测试是GL_LESS
。这会导致跳过之前绘制的片段后面的片段:
在每一帧之前,必须通过glClear(GL_DEPTH_BUFFER_BIT)
清除深度缓冲区以重新启动此过程。
将以下行添加到您的代码中,在 display
的开头:
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glEnable( GL_DEPTH_TEST )
当然你必须创建一个 window 和深度缓冲区 (glutInitDisplayMode(GLUT_DEPTH)
):
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
查看预览:
Can you also tell how to make circle where the planet is revolving?
我建议使用 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()