Package toon :: Package effects :: Module chromakey
[hide private]
[frames] | no frames]

Source Code for Module toon.effects.chromakey

  1  #!/usr/bin/env python 
  2  """ 
  3  GLSL shaders with SDL, OpenGL texture and Python 
  4  """ 
  5  from pygame.locals import * 
  6  from OpenGL.GL import * 
  7  from OpenGL.error import NullFunctionError #TODO: port to all other shader. 
  8  from OpenGL.GLU import * 
  9  from rats.glsl import ShaderProgram 
 10  from rats.glsl import ShaderError 
 11  from toon import fx 
 12  from toon import optgroup 
 13   
 14  # globals 
 15  vert = """ 
 16  /** 
 17   * Vertex shader that does nothing 
 18   */ 
 19  // variables passed to the fragment shader 
 20  varying vec2 texcoord0; 
 21  varying vec2 texdim0; 
 22  void main() 
 23  { 
 24      gl_Position = ftransform(); 
 25      texcoord0 = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0); 
 26      texdim0 = vec2(abs(gl_TextureMatrix[0][0][0]), abs(gl_TextureMatrix[0][1][1])); 
 27  } 
 28  """ 
 29  frag = """ 
 30  /** 
 31   * Fragment shader for chroma-keying.  
 32   *  
 33   * (using a green or blue screen, or any background color) 
 34   *  
 35   * Main thing is, make sure the texcoord's arent  
 36   * normalized (so they are in the range of [0..w, 0..h] ) 
 37   *  
 38   * All params are vec3 in the range [0.0, 1.0] 
 39   *  
 40   * :param keying_color: The RGB keying color that will be made transparent. 
 41   * :param thresh: The distance from the color for a pixel to disappear. 
 42   *  
 43   * :author: Alexandre Quessy <alexandre@quessy.net> 2009 
 44   * :license: GNU Public License version 3 
 45   *  
 46   *  smoothstep with distance from target color 
 47   *  genType smoothStep(genType edge0, genType edge1, genType x); 
 48   *  The result will be zero if x <= edge0, 1  
 49   *  if x >= edge1 and performs smooth Hermite interpolation  
 50   *  between 0 and 1 when edge0 < x < edge1.  
 51   */ 
 52   
 53  // user-configurable variables (read-only) 
 54  uniform vec3 keying_color; 
 55  uniform float thresh; // [0, 1.732] 
 56  uniform float slope; // [0, 1] 
 57  // the texture 
 58  uniform sampler2DRect image; 
 59  // data passed from vertex shader: 
 60  varying vec2 texcoord0; 
 61  varying vec2 texdim0; 
 62  void main(void) 
 63  { 
 64      // sample from the texture  
 65      vec3 input_color = texture2DRect(image, texcoord0).rgb; 
 66      float d = abs(length(abs(keying_color.rgb - input_color.rgb))); 
 67      float edge0 = thresh * (1.0 - slope);  
 68      float alpha = smoothstep(edge0, thresh, d); 
 69      gl_FragColor = vec4(input_color, alpha);  
 70  } 
 71  """ 
 72   
73 -class ChromaKeyOptions(optgroup.OptionsGroup):
74 - def __init__(self):
75 self.target_color = [0.2, 0.0, 0.8] 76 self.thresh = 0.8 77 self.slope = 0.2 78 self.texture_id = 0
79
80 -class ChromaKeyEffect(fx.Effect):
81 """ 82 Chroma keying filter using GLSL. 83 """
84 - def __init__(self):
85 fx.Effect.__init__(self) 86 self.name = "chromakey" 87 self.program = None 88 self.options = ChromaKeyOptions()
89
90 - def setup(self):
91 """ 92 Loads the plugin 93 """ 94 global vert 95 global frag 96 try: 97 self.program = ShaderProgram() 98 self.program.add_shader_text(GL_VERTEX_SHADER_ARB, vert) 99 self.program.add_shader_text(GL_FRAGMENT_SHADER_ARB, frag) 100 self.program.linkShaders() 101 self.loaded = True 102 except NullFunctionError, e: 103 print("Error: %s" % (e.message)) 104 print("Disabling the chromakey effect") 105 except ShaderError, e: 106 print("Error: %s" % (e.message)) 107 print("Disabling the chromakey effect") 108 self.loaded = True
109
110 - def pre_draw(self):
111 if self.loaded and self.enabled: 112 try: 113 self.program.enable() 114 except Exception, e: 115 self.loaded = False 116 print(e.message) 117 else: 118 self.program.glUniform1i("image", self.options.texture_id) 119 self.program.glUniform3f("keying_color", *self.options.target_color) 120 self.program.glUniform1f("thresh", self.options.thresh) 121 self.program.glUniform1f("slope", self.options.slope)
122
123 - def post_draw(self):
124 if self.loaded and self.enabled: 125 try: 126 self.program.disable() 127 except Exception, e: 128 self.loaded = False 129 print(e.message)
130
131 -def create_effect():
132 """ 133 Factory for the effect in this module. 134 """ 135 return ChromaKeyEffect()
136