class_docstr: Shader program using Function instances as basis for its shaders.
  
  Automatically rebuilds program when functions have changed and uploads
  program variables.
class_docstr_tok: ["Shader","program","using","Function","instances","as","basis","for","its","shaders",".","Automatically","rebuilds","program","when","functions","have","changed","and","uploads","program","variables","."]
code: def __init__(self, vcode="", fcode="", gcode=None):
      Program.__init__(self)
  
      self.changed = EventEmitter(source=self, type="program_change")
  
      # Cache state of Variables so we know which ones require update
      self._variable_cache = WeakKeyDictionary()
  
      # List of settable variables to be checked for value changes
      self._variables = []
  
      self._vert = MainFunction("vertex", "")
      self._frag = MainFunction("fragment", "")
      self._vert._dependents[self] = None
      self._frag._dependents[self] = None
      self._geom = None
  
      self.vert = vcode
      self.frag = fcode
      self.geom = gcode
  
imports: from __future__ import division
  import logging
  from weakref import WeakKeyDictionary
  from ...gloo import Program
  from ...gloo.preprocessor import preprocess
  from ...util import logger
  from ...util.event import EventEmitter
  from .function import MainFunction
  from .variable import Variable
  from .compiler import Compiler
label_desc: Use image node_id 1 to create a new ModularProgram object from inherited base classes: Program with example: obj = ModularProgram(vcode, fcode, gcode)