roc/pipeline.py
2011-06-20 21:45:02 -06:00

178 lines
4.1 KiB
Python
Executable file

from OpenGL.GL import *
import shader
import physics
from py3dutil import *
from enums import *
class pipeline_manager(object):
def __init__(self):
self.phase = 'move'
self.updates = []
self.renders = []
self.phases = [
('handle_input', {}),
('ai', {}),
('animate', {}),
('move', {}),
('collide', {'func': physics.mgr.postcollide}),
('prerender', {}),
('render', {})
]
self.pipelines = [
('camera', {}),
('player', {'lighting': False, 'shader': 'standard'}),
('model', {'lighting': False, 'shader': 'standard'}),
# ('shadow', {}),
# ('particle', {'lighting': False, 'depthsort': obarr(), 'nodepthbuffer': True, 'shader': 'sprite'}),
# ('sprite', {'lighting': False, 'depthsort': obarr(), 'nodepthbuffer': True, 'shader': 'sprite'}),
('composite1', {}),
('composite2', {}),
]
self.phase_index = {}
for i, phase in enumerate(self.phases):
self.phase_index[phase[0]] = i
self.updates.append(obarr())
self.pipeline_index = {}
for i, pipe in enumerate(self.pipelines):
self.pipeline_index[pipe[0]] = i
self.renders.append(obarr())
def update(self):
for i, updarr in enumerate(self.updates):
phase = self.phases[i]
self.phase = phase[0]
retval = False
repeat_count = 1
if 'repeat' in phase and phase[1]['repeat']:
repeat_count = phase[1]['repeat']
while repeat_count > 0:
if 'func' in phase:
retval = phase['func']()
else:
for o in updarr:
c = eval("o.%s" % (phase[0],))
if callable(c):
rv = c()
if rv:
retval = rv
if not ('repeat' in phase and phase[1]['repeat']) or retval:
repeat_count -= 1
else:
if 'fail_func' in phase[1]:
phase[1]['fail_func']()
break
physics.mgr.postcollide()
def render(self):
for i, renarr in enumerate(self.renders):
for ren in renarr:
ren.owner.calc_render_pos()
for i, renarr in enumerate(self.renders):
type, typedata = self.pipelines[i]
if 'depthsort' in typedata:
depthsort = typedata['depthsort']
depthsort.resize(len(renarr))
for i in range(len(renarr)):
depthsort[i] = renarr[i].owner.render_pos.mag()
renarr.sort(depthsort)
lighting_on = 'lighting' in typedata and typedata['lighting']
shader_on = 'shader' in typedata
depth_off = 'nodepthbuffer' in typedata and typedata['nodepthbuffer']
if lighting_on:
glEnable(GL_LIGHTING)
if shader_on:
shader.mgr.select(typedata['shader'])
if depth_off:
glDepthMask(GL_FALSE)
for o in renarr:
if lighting_on:
o.owner.illuminate()
o.owner.render(o.layer)
if depth_off:
glDepthMask(GL_TRUE)
if lighting_on:
glDisable(GL_LIGHTING)
if shader_on:
shader.mgr.select("ffp")
for i, renarr in enumerate(self.renders):
for ren in renarr:
ren.owner.clear_render_pos()
def init():
global mgr
mgr = pipeline_manager()
mgr = None
def register_ship(obj):
render_pipes = ('model',)
update_pipes = ('ai', 'move', 'collide')
register(obj, update_pipes)
def register_player(obj):
render_pipes = ('model',)
update_pipes = ('handle_input', 'move', 'collide')
register(obj, update_pipes)
def register_particles(obj):
render_pipes = ('particle',)
update_pipes = ('move',)
register(obj, update_pipes)
def register_direct(obj, update_pipes, render_pipes):
assert False
obj._pipeline_update = tuple(update_pipes)
obj._pipeline_render = tuple(render_pipes)
for phase in update_pipes:
i = mgr.phase_index[phase]
mgr.updates[i].append(obj)
for pipe in render_pipes:
i = mgr.pipeline_index[pipe]
mgr.renders[i].append(obj)
def register_auto(obj):
for role in obj.roles:
pass
def register(obj, update_pipes=None):
if update_pipes == None:
register_auto(obj)
obj._pipeline_update = tuple(update_pipes)
for phase in update_pipes:
i = mgr.phase_index[phase]
mgr.updates[i].append(obj)
for lc in obj.layers:
i = lc.layer.pipeline
mgr.renders[i].append(lc)
def unregister(obj):
update = obj._pipeline_update
del obj._pipeline_update
for lc in obj.layers:
ir = lc.layer.pipeline
mgr.renders[ir].remove(lc)
for u in update:
iu = mgr.phase_index[u]
mgr.updates[iu].remove(obj)