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', {}) ] 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() mgr = pipeline_manager() 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(obj, update_pipes): 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)