Convert orbits to VBO

This commit is contained in:
Quantum 2018-08-25 00:06:33 -04:00
parent a2620fc3bc
commit bfdefe43ef
2 changed files with 35 additions and 17 deletions

View file

@ -5,7 +5,7 @@ from pyglet.gl import *
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from six.moves import range from six.moves import range
from punyverse.glgeom import compile, glMatrix, glRestore, belt, Sphere, Disk from punyverse.glgeom import compile, glMatrix, glRestore, belt, Sphere, Disk, OrbitVBO
from punyverse.model import load_model, WavefrontVBO from punyverse.model import load_model, WavefrontVBO
from punyverse.orbit import KeplerOrbit from punyverse.orbit import KeplerOrbit
from punyverse.texture import get_best_texture, load_clouds from punyverse.texture import get_best_texture, load_clouds
@ -177,7 +177,7 @@ class Body(Entity):
self.rotation_angle = 360.0 / rotation if rotation else 0 self.rotation_angle = 360.0 / rotation if rotation else 0
# Orbit calculation # Orbit calculation
self.orbit_id = None self.orbit_vbo = None
self.orbit_cache = None self.orbit_cache = None
def update(self): def update(self):
@ -202,23 +202,14 @@ class Body(Entity):
# Cache key is the three orbital plane parameters and eccentricity # Cache key is the three orbital plane parameters and eccentricity
cache = (self.orbit.eccentricity, self.orbit.longitude, self.orbit.inclination, self.orbit.argument) cache = (self.orbit.eccentricity, self.orbit.longitude, self.orbit.inclination, self.orbit.argument)
if self.orbit_cache == cache: if self.orbit_cache == cache:
return self.orbit_id return self.orbit_vbo
if self.orbit_id is not None: if self.orbit_vbo is not None:
glDeleteLists(self.orbit_id, 1) self.orbit_vbo.close()
id = glGenLists(1) self.orbit_vbo = OrbitVBO(self.orbit)
glNewList(id, GL_COMPILE)
glBegin(GL_LINE_LOOP)
for theta in range(360):
x, z, y = self.orbit.orbit(theta)
glVertex3f(x, y, z)
glEnd()
glEndList()
self.orbit_id = id
self.orbit_cache = cache self.orbit_cache = cache
return id return self.orbit_vbo
def _draw_orbits(self, distance): def _draw_orbits(self, distance):
with glMatrix(self.parent.location), glRestore(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT): with glMatrix(self.parent.location), glRestore(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT):
@ -228,7 +219,7 @@ class Body(Entity):
if not solid: if not solid:
glEnable(GL_BLEND) glEnable(GL_BLEND)
glLineWidth(1) glLineWidth(1)
glCallList(self.get_orbit()) self.get_orbit().draw()
def draw(self, options): def draw(self, options):
self._draw(options) self._draw(options)

View file

@ -209,6 +209,33 @@ class Sphere(object):
glBindBuffer(GL_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0)
class OrbitVBO(object):
def __init__(self, orbit):
buffer = 360 * 3 * [0]
for theta in range(360):
x, z, y = orbit.orbit(theta)
buffer[3*theta:3*theta+3] = [x, y, z]
self.vbo = array_to_gl_buffer(buffer)
def draw(self):
with glRestoreClient(GL_CLIENT_VERTEX_ARRAY_BIT):
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, 12, 0)
glDrawArrays(GL_LINE_LOOP, 0, 360)
glBindBuffer(GL_ARRAY_BUFFER, 0)
def close(self):
if self.vbo is not None:
vbo = c_uint(self.vbo)
glDeleteBuffers(1, byref(vbo))
self.vbo = None
def __del__(self):
self.close()
def belt(radius, cross, object, count): def belt(radius, cross, object, count):
for i in range(count): for i in range(count):
theta = TWOPI * random() theta = TWOPI * random()