Used context managers to control GL attributes and matrices. No more stray GL_BLEND, much faster!

This commit is contained in:
Quantum 2014-02-02 16:47:05 -05:00
parent 44889fbf11
commit 83d8baeb8e
2 changed files with 268 additions and 282 deletions

View file

@ -365,7 +365,7 @@ class Applet(pyglet.window.Window):
progress_bar(10, self.height - 240, self.width - 20, 50, progress) progress_bar(10, self.height - 240, self.width - 20, 50, progress)
self._info_label.draw() self._info_label.draw()
def on_draw(self, glMatrix=GLfloat * 16): def on_draw(self, glMatrixBuffer=GLfloat * 16):
if not self.loaded: if not self.loaded:
return self.draw_loading() return self.draw_loading()
@ -392,79 +392,67 @@ class Applet(pyglet.window.Window):
x, y, z = entity.location x, y, z = entity.location
pitch, yaw, roll = entity.rotation pitch, yaw, roll = entity.rotation
glPushMatrix() with glMatrix(), glRestore(GL_CURRENT_BIT):
glTranslatef(x, y, z) glTranslatef(x, y, z)
glRotatef(pitch, 1, 0, 0) glRotatef(pitch, 1, 0, 0)
glRotatef(yaw, 0, 1, 0) glRotatef(yaw, 0, 1, 0)
glRotatef(roll, 0, 0, 1) glRotatef(roll, 0, 0, 1)
glPushAttrib(GL_CURRENT_BIT)
glCallList(entity.id)
if self.debug:
glPushMatrix()
glLineWidth(0.25)
glPolygonOffset(1, 1)
glDisable(GL_LIGHTING)
glDisable(GL_TEXTURE_2D)
glColor3f(0, 1, 0)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glCallList(entity.id) glCallList(entity.id)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) if self.debug:
glEnable(GL_LIGHTING) with glMatrix(), glRestore(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_LINE_BIT):
glEnable(GL_TEXTURE_2D) glLineWidth(0.25)
glPopMatrix() glPolygonOffset(1, 1)
glPopAttrib() glDisable(GL_LIGHTING)
glPopMatrix() glDisable(GL_TEXTURE_2D)
glColor3f(0, 1, 0)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glCallList(entity.id)
has_corona = hasattr(entity, 'corona') and entity.corona has_corona = hasattr(entity, 'corona') and entity.corona
has_atmosphere = hasattr(entity, 'atmosphere') and entity.atmosphere has_atmosphere = hasattr(entity, 'atmosphere') and entity.atmosphere
if self.atmosphere and (has_corona or has_atmosphere): if self.atmosphere and (has_corona or has_atmosphere):
glPushMatrix() with glMatrix(), glRestore(GL_ENABLE_BIT):
x0, y0, z0 = entity.location x0, y0, z0 = entity.location
glTranslatef(x0, y0, z0)
glTranslatef(x0, y0, z0) matrix = glMatrixBuffer()
matrix = glMatrix() glGetFloatv(GL_MODELVIEW_MATRIX, matrix)
glGetFloatv(GL_MODELVIEW_MATRIX, matrix) matrix[0: 3] = [1, 0, 0]
matrix[0: 3] = [1, 0, 0] matrix[4: 7] = [0, 1, 0]
matrix[4: 7] = [0, 1, 0] matrix[8:11] = [0, 0, 1]
matrix[8:11] = [0, 0, 1] glLoadMatrixf(matrix)
glLoadMatrixf(matrix) glEnable(GL_BLEND)
if has_atmosphere: if has_atmosphere:
glCallList(entity.atmosphere) glCallList(entity.atmosphere)
if has_corona: if has_corona:
x, y, z = c.direction() x, y, z = c.direction()
glTranslatef(-x, -y, -z) glTranslatef(-x, -y, -z)
glCallList(entity.corona) glCallList(entity.corona)
glPopMatrix()
if self.cloud and hasattr(entity, 'cloudmap') and entity.cloudmap: if self.cloud and hasattr(entity, 'cloudmap') and entity.cloudmap:
glPushMatrix() with glMatrix(), glRestore(GL_ENABLE_BIT):
glEnable(GL_BLEND) glEnable(GL_BLEND)
glEnable(GL_ALPHA_TEST) glEnable(GL_ALPHA_TEST)
glTranslatef(*entity.location) glTranslatef(*entity.location)
pitch, yaw, roll = entity.rotation pitch, yaw, roll = entity.rotation
glRotatef(pitch, 1, 0, 0) glRotatef(pitch, 1, 0, 0)
glRotatef(yaw, 0, 1, 0) glRotatef(yaw, 0, 1, 0)
glRotatef(roll, 0, 0, 1) glRotatef(roll, 0, 0, 1)
glCallList(entity.cloudmap) glCallList(entity.cloudmap)
glDisable(GL_ALPHA_TEST)
glDisable(GL_BLEND)
glPopMatrix()
if self.orbit and hasattr(entity, 'get_orbit') and hasattr(entity, 'parent'): if self.orbit and hasattr(entity, 'get_orbit') and hasattr(entity, 'parent'):
parent = entity.parent parent = entity.parent
distance = get_distance(parent) distance = get_distance(parent)
if distance < parent.orbit_show: if distance < parent.orbit_show:
glPushMatrix() with glMatrix(), glRestore(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT):
glTranslatef(*entity.parent.location) glTranslatef(*entity.parent.location)
glDisable(GL_LIGHTING) glDisable(GL_LIGHTING)
glPushAttrib(GL_LINE_BIT | GL_CURRENT_BIT) solid = distance < parent.orbit_opaque
glColor4f(1, 1, 1, 1 if distance < parent.orbit_opaque else glColor4f(1, 1, 1, 1 if solid else
(1 - (distance - parent.orbit_opaque) / parent.orbit_blend)) (1 - (distance - parent.orbit_opaque) / parent.orbit_blend))
glLineWidth(1) if not solid:
glCallList(entity.get_orbit()) glEnable(GL_BLEND)
glPopAttrib() glLineWidth(1)
glEnable(GL_LIGHTING) glCallList(entity.get_orbit())
glPopMatrix()
glColor4f(1, 1, 1, 1) glColor4f(1, 1, 1, 1)
glDisable(GL_TEXTURE_2D) glDisable(GL_TEXTURE_2D)
@ -473,7 +461,6 @@ class Applet(pyglet.window.Window):
if self.info: if self.info:
ortho(width, height) ortho(width, height)
if self.info_precise: if self.info_precise:
info = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s, %s/s\n' info = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s, %s/s\n'
'Direction(pitch=%.2f, yaw=%.2f, roll=%.2f)\nTick: %d' % 'Direction(pitch=%.2f, yaw=%.2f, roll=%.2f)\nTick: %d' %
@ -484,15 +471,10 @@ class Applet(pyglet.window.Window):
(pyglet.clock.get_fps(), c.x, c.y, c.z, self.speed, self.get_time_per_second())) (pyglet.clock.get_fps(), c.x, c.y, c.z, self.speed, self.get_time_per_second()))
self.label.text = info self.label.text = info
self.label.draw() self.label.draw()
with glRestore(GL_CURRENT_BIT | GL_LINE_BIT):
glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT) glLineWidth(2)
cx, cy = width / 2, height / 2
glLineWidth(2) glColor4f(0, 1, 0, 1)
circle(10, 20, (cx, cy))
cx, cy = width / 2, height / 2 glPopAttrib()
glColor4f(0, 1, 0, 1)
circle(10, 20, (cx, cy))
glPopAttrib()
frustrum() frustrum()

View file

@ -5,7 +5,7 @@ from random import random, gauss, choice
TWOPI = pi * 2 TWOPI = pi * 2
__all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'disk', 'sphere', 'colourball', 'torus', 'belt', __all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'disk', 'sphere', 'colourball', 'torus', 'belt',
'flare', 'normal_sphere', 'glSection', 'progress_bar'] 'flare', 'normal_sphere', 'glSection', 'glMatrix', 'glRestore', 'progress_bar']
class glSection(object): class glSection(object):
@ -19,6 +19,25 @@ class glSection(object):
glEnd() glEnd()
class glRestore(object):
def __init__(self, flags):
self.flags = flags
def __enter__(self):
glPushAttrib(self.flags)
def __exit__(self, exc_type, exc_val, exc_tb):
glPopAttrib()
class glMatrix(object):
def __enter__(self):
glPushMatrix()
def __exit__(self, exc_type, exc_val, exc_tb):
glPopMatrix()
def compile(pointer, *args, **kwargs): def compile(pointer, *args, **kwargs):
display = glGenLists(1) display = glGenLists(1)
glNewList(display, GL_COMPILE) glNewList(display, GL_COMPILE)
@ -49,126 +68,117 @@ def frustrum():
def crosshair(size, (cx, cy)): def crosshair(size, (cx, cy)):
glBegin(GL_LINES) with glSection(GL_LINES):
glVertex2f(cx - size, cy) glVertex2f(cx - size, cy)
glVertex2f(cx + size, cy) glVertex2f(cx + size, cy)
glVertex2f(cx, cy - size) glVertex2f(cx, cy - size)
glVertex2f(cx, cy + size) glVertex2f(cx, cy + size)
glEnd()
def circle(r, seg, (cx, cy)): def circle(r, seg, (cx, cy)):
glBegin(GL_LINE_LOOP) with glSection(GL_LINE_LOOP):
for i in xrange(seg): for i in xrange(seg):
theta = TWOPI * i / seg theta = TWOPI * i / seg
glVertex2f(cx + cos(theta) * r, cy + sin(theta) * r) glVertex2f(cx + cos(theta) * r, cy + sin(theta) * r)
glEnd()
def disk(rinner, router, segs, tex): def disk(rinner, router, segs, tex):
glEnable(GL_TEXTURE_2D) with glRestore(GL_ENABLE_BIT):
glDisable(GL_LIGHTING) glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, tex) glEnable(GL_BLEND)
res = segs * 5 glDisable(GL_LIGHTING)
glBindTexture(GL_TEXTURE_2D, tex)
res = segs * 5
glBegin(GL_TRIANGLE_STRIP) with glSection(GL_TRIANGLE_STRIP):
texture = 0 factor = TWOPI / res
factor = TWOPI / res theta = 0
theta = 0 for n in xrange(res + 1):
for n in xrange(res + 1): theta += factor
theta += factor x = cos(theta)
x = cos(theta) y = sin(theta)
y = sin(theta) glTexCoord2f(0, 0)
glTexCoord2f(0, texture) glVertex2f(rinner * x, rinner * y)
glVertex2f(rinner * x, rinner * y) glTexCoord2f(1, 0)
glTexCoord2f(1, texture) glVertex2f(router * x, router * y)
glVertex2f(router * x, router * y)
texture ^= 1
glEnd()
glEnable(GL_LIGHTING)
glDisable(GL_TEXTURE_2D)
def flare(rinner, router, res, prob, tex): def flare(rinner, router, res, prob, tex):
glEnable(GL_TEXTURE_2D) with glRestore(GL_ENABLE_BIT):
glDisable(GL_LIGHTING) glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, tex) glDisable(GL_LIGHTING)
last_x = 1 glBindTexture(GL_TEXTURE_2D, tex)
last_y = 0 last_x = 1
last_theta = 0 last_y = 0
factor = TWOPI / res last_theta = 0
rdelta = (router - rinner) factor = TWOPI / res
glBegin(GL_QUADS) rdelta = (router - rinner)
for i in xrange(res + 1): with glSection(GL_QUADS):
theta = last_theta + factor for i in xrange(res + 1):
x = cos(theta) theta = last_theta + factor
y = sin(theta) x = cos(theta)
if random() > prob: y = sin(theta)
distance = rinner + rdelta * random() if random() > prob:
avg_theta = (last_theta + theta) / 2 distance = rinner + rdelta * random()
x0, y0 = rinner * last_x, rinner * last_y avg_theta = (last_theta + theta) / 2
x1, y1 = rinner * x, rinner * y x0, y0 = rinner * last_x, rinner * last_y
x2, y2 = distance * cos(avg_theta), distance * sin(avg_theta) x1, y1 = rinner * x, rinner * y
glTexCoord2f(0, 0) x2, y2 = distance * cos(avg_theta), distance * sin(avg_theta)
glVertex2f(x0, y0) glTexCoord2f(0, 0)
glTexCoord2f(0, 1) glVertex2f(x0, y0)
glVertex2f(x1, y1) glTexCoord2f(0, 1)
glTexCoord2f(1, 0) glVertex2f(x1, y1)
glVertex2f(x2, y2) glTexCoord2f(1, 0)
glTexCoord2f(1, 1) glVertex2f(x2, y2)
glVertex2f(x2, y2) glTexCoord2f(1, 1)
last_theta = theta glVertex2f(x2, y2)
last_x = x last_theta = theta
last_y = y last_x = x
glEnd() last_y = y
glEnable(GL_LIGHTING)
glDisable(GL_TEXTURE_2D)
def sphere(r, lats, longs, tex, lighting=True, fv4=GLfloat * 4): def sphere(r, lats, longs, tex, lighting=True, fv4=GLfloat * 4):
""" """
Sphere function from the OpenGL red book. Sphere function from the OpenGL red book.
""" """
sphere = gluNewQuadric() with glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
gluQuadricDrawStyle(sphere, GLU_FILL) sphere = gluNewQuadric()
gluQuadricTexture(sphere, True) gluQuadricDrawStyle(sphere, GLU_FILL)
if lighting: gluQuadricTexture(sphere, True)
gluQuadricNormals(sphere, GLU_SMOOTH) if lighting:
gluQuadricNormals(sphere, GLU_SMOOTH)
glEnable(GL_TEXTURE_2D) glEnable(GL_TEXTURE_2D)
if lighting: if lighting:
glDisable(GL_BLEND) glDisable(GL_BLEND)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(1, 1, 1, 0)) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(1, 1, 1, 0))
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 0)) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 0))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125)
else: else:
glDisable(GL_LIGHTING) glDisable(GL_LIGHTING)
glBindTexture(GL_TEXTURE_2D, tex) glBindTexture(GL_TEXTURE_2D, tex)
gluSphere(sphere, r, lats, longs) gluSphere(sphere, r, lats, longs)
glBindTexture(GL_TEXTURE_2D, 0) gluDeleteQuadric(sphere)
glDisable(GL_TEXTURE_2D)
glEnable(GL_LIGHTING)
glEnable(GL_BLEND)
gluDeleteQuadric(sphere)
def colourball(r, lats, longs, colour, fv4=GLfloat * 4): def colourball(r, lats, longs, colour, fv4=GLfloat * 4):
""" """
Sphere function from the OpenGL red book. Sphere function from the OpenGL red book.
""" """
sphere = gluNewQuadric() with glRestore(GL_ENABLE_BIT):
sphere = gluNewQuadric()
glDisable(GL_BLEND) glDisable(GL_BLEND)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(*colour)) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(*colour))
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 1)) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 1))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125)
gluSphere(sphere, r, lats, longs) gluSphere(sphere, r, lats, longs)
glEnable(GL_BLEND) glEnable(GL_BLEND)
gluDeleteQuadric(sphere) gluDeleteQuadric(sphere)
try: try:
@ -186,60 +196,56 @@ except ImportError:
width, height = normal_map.size width, height = normal_map.size
gray_scale = len(normal[0, 0]) == 1 gray_scale = len(normal[0, 0]) == 1
glEnable(GL_TEXTURE_2D) with glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
if lighting: glEnable(GL_TEXTURE_2D)
glDisable(GL_BLEND) if lighting:
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(1, 1, 1, 0)) glDisable(GL_BLEND)
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 0)) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(1, 1, 1, 0))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 0))
else: glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125)
glDisable(GL_LIGHTING) else:
glBindTexture(GL_TEXTURE_2D, tex) glDisable(GL_LIGHTING)
glBindTexture(GL_TEXTURE_2D, tex)
twopi_divide = TWOPI / divide twopi_divide = TWOPI / divide
pi_divide = pi / divide pi_divide = pi / divide
glBegin(GL_TRIANGLE_STRIP) with glSection(GL_TRIANGLE_STRIP):
for j in xrange(divide + 1): for j in xrange(divide + 1):
phi1 = j * twopi_divide phi1 = j * twopi_divide
phi2 = (j + 1) * twopi_divide phi2 = (j + 1) * twopi_divide
for i in xrange(divide + 1): for i in xrange(divide + 1):
theta = i * pi_divide theta = i * pi_divide
s = phi2 / TWOPI s = phi2 / TWOPI
u = min(int(s * width), width - 1) u = min(int(s * width), width - 1)
t = theta / pi t = theta / pi
v = min(int(t * height), height - 1) v = min(int(t * height), height - 1)
if gray_scale: if gray_scale:
x = y = z = normal[u, v] x = y = z = normal[u, v]
else: else:
x, y, z = normal[u, v] x, y, z = normal[u, v]
dx, dy, dz = sin(theta) * cos(phi2), sin(theta) * sin(phi2), cos(theta) dx, dy, dz = sin(theta) * cos(phi2), sin(theta) * sin(phi2), cos(theta)
nx, ny, nz = x / 127.5 - 1, y / 127.5 - 1, z / 127.5 - 1 # Make into [-1, 1] nx, ny, nz = x / 127.5 - 1, y / 127.5 - 1, z / 127.5 - 1 # Make into [-1, 1]
nx, nz = cos(theta) * nx + sin(theta) * nz, -sin(theta) * nx + cos(theta) * nz nx, nz = cos(theta) * nx + sin(theta) * nz, -sin(theta) * nx + cos(theta) * nz
nx, ny = cos(phi2) * nx - sin(phi2) * ny, sin(phi2) * nx + cos(phi2) * ny nx, ny = cos(phi2) * nx - sin(phi2) * ny, sin(phi2) * nx + cos(phi2) * ny
glNormal3f(nx, ny, nz) glNormal3f(nx, ny, nz)
glTexCoord2f(s, 1 - t) # GL is bottom up glTexCoord2f(s, 1 - t) # GL is bottom up
glVertex3f(r * dx, r * dy, r * dz) glVertex3f(r * dx, r * dy, r * dz)
s = phi1 / TWOPI # x s = phi1 / TWOPI # x
u = min(int(s * width), width - 1) u = min(int(s * width), width - 1)
if gray_scale: if gray_scale:
x = y = z = normal[u, v] x = y = z = normal[u, v]
else: else:
x, y, z = normal[u, v] x, y, z = normal[u, v]
dx, dy = sin(theta) * cos(phi1), sin(theta) * sin(phi1) dx, dy = sin(theta) * cos(phi1), sin(theta) * sin(phi1)
nx, ny, nz = x / 127.5 - 1, y / 127.5 - 1, z / 127.5 - 1 nx, ny, nz = x / 127.5 - 1, y / 127.5 - 1, z / 127.5 - 1
nx, nz = cos(theta) * nx + sin(theta) * nz, -sin(theta) * nx + cos(theta) * nz nx, nz = cos(theta) * nx + sin(theta) * nz, -sin(theta) * nx + cos(theta) * nz
nx, ny = cos(phi1) * nx - sin(phi1) * ny, sin(phi1) * nx + cos(phi1) * ny nx, ny = cos(phi1) * nx - sin(phi1) * ny, sin(phi1) * nx + cos(phi1) * ny
glNormal3f(nx, ny, nz) glNormal3f(nx, ny, nz)
glTexCoord2f(s, 1 - t) glTexCoord2f(s, 1 - t)
glVertex3f(r * dx, r * dy, r * dz) glVertex3f(r * dx, r * dy, r * dz)
glEnd()
glDisable(GL_TEXTURE_2D)
glEnable(GL_LIGHTING)
glEnable(GL_BLEND)
def belt(radius, cross, object, count): def belt(radius, cross, object, count):
@ -248,14 +254,13 @@ def belt(radius, cross, object, count):
r = gauss(radius, cross) r = gauss(radius, cross)
x, y, z = cos(theta) * r, gauss(0, cross), sin(theta) * r x, y, z = cos(theta) * r, gauss(0, cross), sin(theta) * r
glPushMatrix() with glMatrix():
glTranslatef(x, y, z) glTranslatef(x, y, z)
scale = gauss(1, 0.5) scale = gauss(1, 0.5)
if scale < 0: if scale < 0:
scale = 1 scale = 1
glScalef(scale, scale, scale) glScalef(scale, scale, scale)
glCallList(choice(object)) glCallList(choice(object))
glPopMatrix()
try: try:
@ -265,72 +270,71 @@ except ImportError:
""" """
Torus function from the OpenGL red book. Torus function from the OpenGL red book.
""" """
glPushAttrib(GL_CURRENT_BIT) with glRestore(GL_CURRENT_BIT):
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(*material)) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(*material))
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 1)) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 1))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess)
major_s = TWOPI / n_major major_s = TWOPI / n_major
minor_s = TWOPI / n_minor minor_s = TWOPI / n_minor
def n(x, y, z): def n(x, y, z):
m = 1.0 / sqrt(x * x + y * y + z * z) m = 1.0 / sqrt(x * x + y * y + z * z)
return x * m, y * m, z * m return x * m, y * m, z * m
for i in xrange(n_major): for i in xrange(n_major):
a0 = i * major_s a0 = i * major_s
a1 = a0 + major_s a1 = a0 + major_s
x0 = cos(a0) x0 = cos(a0)
y0 = sin(a0) y0 = sin(a0)
x1 = cos(a1) x1 = cos(a1)
y1 = sin(a1) y1 = sin(a1)
glBegin(GL_TRIANGLE_STRIP) with glSection(GL_TRIANGLE_STRIP):
for j in xrange(n_minor + 1):
b = j * minor_s
c = cos(b)
r = minor_radius * c + major_radius
z = minor_radius * sin(b)
for j in xrange(n_minor + 1): glNormal3f(*n(x0 * c, y0 * c, z / minor_radius))
b = j * minor_s glVertex3f(x0 * r, y0 * r, z)
c = cos(b)
r = minor_radius * c + major_radius
z = minor_radius * sin(b)
glNormal3f(*n(x0 * c, y0 * c, z / minor_radius)) glNormal3f(*n(x1 * c, y1 * c, z / minor_radius))
glVertex3f(x0 * r, y0 * r, z) glVertex3f(x1 * r, y1 * r, z)
glNormal3f(*n(x1 * c, y1 * c, z / minor_radius))
glVertex3f(x1 * r, y1 * r, z)
glEnd()
glPopAttrib()
def progress_bar(x, y, width, height, filled): def progress_bar(x, y, width, height, filled):
x1 = x with glRestore(GL_ENABLE_BIT):
x2 = x + width glDisable(GL_TEXTURE_2D)
y1 = y glDisable(GL_BLEND)
y2 = y - height x1 = x
y3 = 0.65 * y1 + 0.35 * y2 x2 = x + width
y4 = 0.25 * y1 + 0.75 * y2 y1 = y
y2 = y - height
y3 = 0.65 * y1 + 0.35 * y2
y4 = 0.25 * y1 + 0.75 * y2
glColor3f(0.6, 0.6, 0.6) glColor3f(0.6, 0.6, 0.6)
with glSection(GL_LINE_LOOP): with glSection(GL_LINE_LOOP):
glVertex2f(x1, y1) glVertex2f(x1, y1)
glVertex2f(x1, y2) glVertex2f(x1, y2)
glVertex2f(x2, y2) glVertex2f(x2, y2)
glVertex2f(x2, y1) glVertex2f(x2, y1)
x1 += 1 x1 += 1
y1 -= 1 y1 -= 1
x2 = x + width * filled - 1 x2 = x + width * filled - 1
with glSection(GL_TRIANGLE_STRIP): with glSection(GL_TRIANGLE_STRIP):
glColor3f(0.81, 1, 0.82) glColor3f(0.81, 1, 0.82)
glVertex2f(x1, y1) glVertex2f(x1, y1)
glVertex2f(x2, y1) glVertex2f(x2, y1)
glColor3f(0, 0.83, 0.16) glColor3f(0, 0.83, 0.16)
glVertex2f(x1, y3) glVertex2f(x1, y3)
glVertex2f(x2, y3) glVertex2f(x2, y3)
glVertex2f(x1, y4) glVertex2f(x1, y4)
glVertex2f(x2, y4) glVertex2f(x2, y4)
glColor3f(0.37, 0.92, 0.43) glColor3f(0.37, 0.92, 0.43)
glVertex2f(x1, y2) glVertex2f(x1, y2)
glVertex2f(x2, y2) glVertex2f(x2, y2)