Saturday 6 April 2013

Using retained shape for performance in processing.py

   1 # CubicGridRetained
   2 #
   3 # You may need to increase the maximum available memory
   4 # by passing -mx1000m to jvm (in run script if you use that)
   5 #
   6 BOX_SIZE = 20
   7 MARGIN = BOX_SIZE * 2
   8 DEPTH = 400
   9 boxFill = None
  10 grid = None
  11 fcount = 0
  12 lastm = 0
  13 frate =  0
  14 FINT = 3
  15 
  16 def setup(): 
  17   size(640, 360, P3D)
  18   frameRate(60)
  19   noSmooth()
  20   noStroke()
  21   global grid
  22   grid = createShape(GROUP)
  23 
  24   # Build grid using multiple 
  25   for i in range(-DEPTH / 2 + MARGIN, DEPTH / 2 - MARGIN, BOX_SIZE):
  26     for j in range(-height + MARGIN, height - MARGIN, BOX_SIZE):
  27       for k in range(-width + MARGIN,  width - MARGIN, BOX_SIZE):
  28         # Base fill color on counter values, abs function
  29         # ensures values stay within legal range
  30         boxFill = color(abs(i), abs(j), abs(k), 50)
  31         sz = [BOX_SIZE, BOX_SIZE, BOX_SIZE]
  32         cube = createShape(BOX, sz)
  33         cube.setFill(boxFill)
  34         cube.translate(k, j, i)
  35         grid.addChild(cube)
  36 
  37 def draw(): 
  38   background(255)
  39 
  40   hint(DISABLE_DEPTH_TEST)
  41 
  42   # Center and spin grid
  43   pushMatrix()
  44   translate(width / 2, height / 2, -DEPTH)
  45   rotateY(frameCount * 0.01)
  46   rotateX(frameCount * 0.01)
  47   global grid
  48   shape(grid)
  49   popMatrix()
  50 
  51   hint(ENABLE_DEPTH_TEST)
  52   global fcount, lastm, frate
  53   fcount += 1
  54   m = millis()
  55   if (m - lastm > 1000 * FINT): 
  56     frate = float(fcount) / FINT
  57     fcount = 0
  58     lastm = m
  59     print("fps: %d" %  frate)
  60   
  61   fill(0)
  62   text("fps: %d" %  frate, 10, 20)
  63 

Processing.py now updated

Thanks to work by Ralf Biedert processing.py has recently been update to use jython-2.7b1 and processing-2.0b8.  It might be interesting to follow his fork in the meantime it has been pulled into the original by Jonathan Feinberg. So you can even update it yourself to the development version of vanilla processing if you wish (strange thing is why opengl is still kept in libraries folder instead of alongside core as P2D and P3D are both rendered using opengl). Here is another Shader example translated to processing.py.
   1 monjori = None
   2 
   3 def setup():
   4   size(640, 360, P2D)
   5   noStroke()
   6   global monjori
   7   monjori = loadShader("monjori.glsl")
   8   monjori.set("resolution", float(width), float(height))
   9   
  10 
  11 def draw():
  12   monjori.set("time", millis() / 1000.0)
  13   shader(monjori) 
  14   # The rect is needed to make the fragment shader go through every pixel of
  15   # the screen, but is not used for anything else since the rendering is entirely
  16   # generated by the shader.  
  17   fill(0)
  18   rect(0, 0, width, height)