A collection of ModularPrograms that emulates the API of a single ModularProgram. A single Visual is often drawn in many different ways--viewed under different transforms, with different clipping boundaries, or with different colors as in picking and anaglyph stereo. Each draw may
| 4 | |
| 5 | |
| 6 | class MultiProgram(object): |
| 7 | """A collection of ModularPrograms that emulates the API of a single |
| 8 | ModularProgram. |
| 9 | |
| 10 | A single Visual is often drawn in many different ways--viewed under |
| 11 | different transforms, with different clipping boundaries, or with different |
| 12 | colors as in picking and anaglyph stereo. Each draw may require a different |
| 13 | program. To simplify this process, MultiProgram exposes an API that looks |
| 14 | very much like a single ModularProgram, but internally manages many |
| 15 | programs. |
| 16 | """ |
| 17 | |
| 18 | def __init__(self, vcode='', fcode='', gcode=None): |
| 19 | self._vcode = vcode |
| 20 | self._fcode = fcode |
| 21 | self._gcode = gcode |
| 22 | self._programs = weakref.WeakValueDictionary() |
| 23 | self._set_items = {} |
| 24 | self._next_prog_id = 0 |
| 25 | self._vert = MultiShader(self, 'vert') |
| 26 | self._frag = MultiShader(self, 'frag') |
| 27 | self._geom = None if gcode is None else MultiShader(self, 'geom') |
| 28 | |
| 29 | def add_program(self, name=None): |
| 30 | """Create a program and add it to this MultiProgram. |
| 31 | |
| 32 | It is the caller's responsibility to keep a reference to the returned |
| 33 | program. |
| 34 | |
| 35 | The *name* must be unique, but is otherwise arbitrary and used for |
| 36 | debugging purposes. |
| 37 | """ |
| 38 | if name is None: |
| 39 | name = 'program' + str(self._next_prog_id) |
| 40 | self._next_prog_id += 1 |
| 41 | |
| 42 | if name in self._programs: |
| 43 | raise KeyError("Program named '%s' already exists." % name) |
| 44 | |
| 45 | # create a program and update it to look like the rest |
| 46 | prog = ModularProgram(self._vcode, self._fcode, self._gcode) |
| 47 | for key, val in self._set_items.items(): |
| 48 | prog[key] = val |
| 49 | self.frag._new_program(prog) |
| 50 | self.vert._new_program(prog) |
| 51 | if self._geom is not None: |
| 52 | self.geom._new_program(prog) |
| 53 | |
| 54 | self._programs[name] = prog |
| 55 | return prog |
| 56 | |
| 57 | @property |
| 58 | def vert(self): |
| 59 | """A wrapper around all vertex shaders contained in this MultiProgram.""" |
| 60 | return self._vert |
| 61 | |
| 62 | @vert.setter |
| 63 | def vert(self, code): |
no outgoing calls
searching dependent graphs…