Converting Java code to Python

edited May 2018 in Python Mode

Hi everyone,

I'm trying to convert this sketch (from the PixelfFlow library) to Python but I'm having difficulties understanding some part of it. Especially the following part:

// callback for scene display (used in GBAA)
    DwSceneDisplay scene_display = new DwSceneDisplay() {  
      @ Override
      public void display(PGraphics3D canvas) {
        displayScene(canvas); 
      }
    };

Would love your help !

Answers

  • edited May 2018
    • I believe that's called class anonymous instantiation in Java.
    • In which we add extra stuff to a class at the same time we're instantiating it.
    • I don't believe Python (or Jython) got an exactly such syntax though. Not sure...
    • A class anonymous instantiation is pretty much a Java inner class created on-the-fly.
    • And it has access to almost anything its enclosing function and class got, similar to JS closures.
    • For example, displayScene() is a method of class DepthOfField_Demo; which in turn is a subclass of PApplet; which is being invoked inside the anonymous instance of DwSceneDisplay!
    • It means that the object referenced by local variable scene_display has now direct access not only to class DwSceneDisplay's members, but also to DepthOfField_Demo & PApplet's members! @-)
  • edited May 2018 Answer ✓

    Although Python doesn't have an exact syntax for it, there are easy workarounds. #:-S

    We can define an inner subclass 1st, and then instantiate it next, rather than both actions at the same statement: :ar!

    class MySceneDisplay(DwSceneDisplay): # 1st half of the workaround
        def display(_, canvas): self.displayScene(canvas)
    
    scene_display = MySceneDisplay() # 2nd half of the workaround
    

    That's assumed you're converting it to a ".py" file. L-)
    If it's a ".pyde" file, replace self.displayScene(canvas) w/ just displayScene(canvas)

    The variable self (by convention) refers to the current instance of subclass DepthOfField_Demo.

    But if you write it as a regular ".pyde" file, cut off that DepthOfField_Demo wrapper completely. >-)

  • edited May 2018

    BtW, I had to do something like that here: :ar!
    https://Gist.GitHub.com/GoToLoop/a476ac6a01d18700240853fed33c0e57

    But for Java's class TimerTask instead of PixelFlow's class DwSceneDisplay. :>

  • edited May 2018

    @GoToLoop -- Thanks a ton for all the information and clarifications.

    I might ask for help on this thread again as I'm not sure to be able to fully convert the Java sketch.

  • edited May 2018

    I'm struggling again with the following snippet:

    PGraphics3D pg_render;
    PGraphics3D pg_dof;
    PGraphics3D pg_tmp;
    

    ...

    public boolean resizeScreen(){
    
        boolean[] RESIZED = {false};
    
        pg_render = DwUtils.changeTextureSize(this, pg_render, width, height, 8, RESIZED);
        pg_dof    = DwUtils.changeTextureSize(this, pg_dof   , width, height, 0, RESIZED);
        pg_tmp    = DwUtils.changeTextureSize(this, pg_tmp   , width, height, 0, RESIZED, GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    

    It seems that each function is being declared with itself in argument (?!):

    pg_render = DwUtils.changeTextureSize(this, pg_render, ...);

    Also I'm not sure to understand why the RESIZED variable (a boolean) is instantiated with curly braces.

    Would really appreciate your help @GoToLoop

  • Not declared, assigned. They are declared up top, here:

    PGraphics3D pg_render;
    PGraphics3D pg_dof;
    PGraphics3D pg_tmp;
    

    So during assignment, a PGraphics3D object is passed to DwUtils.changeTextureSize(), which returns a PGraphics3D, and the returned object is assigned to the variable pg_render.

    Assigning a variable using itself as an argument is really common; you do it all the time.

    float x = 2;
    x = pow(x, 4); // assign with self as argument
    
  • Re:

    why the RESIZED variable (a boolean) is instantiated with curly braces

    This is just declaring the members of an array on initialization. It is an array of booleans with one member.

    For example:

    int[] nums = {1, 2, 3};
    String[] words = {"foo", "bar", "baz"};
    boolean[] RESIZED = {false};
    

    et cetera.

  • edited May 2018

    For some odd reasons, a PGraphics object can't use its resize() method: [-X
    https://Processing.org/reference/PImage_resize_.html

    Even though a PGraphics is technically a PImage, it is not possible to rescale the image data found in a PGraphics.

    A PGraphics needs to be cloned as an actual vanilla PImage via its method get(), so resize() can be finally used on it: :-B
    https://Processing.org/reference/PImage_get_.html

    If you want to resize PGraphics content, first get a copy of its image data using the get() method, and call resize() on the PImage that is returned.

    After that, another PGraphics needs to be created w/ those new dimensions via createGraphics(): :-\"
    https://Processing.org/reference/createGraphics_.html

    Then as a final step, transfer the rescaled PImage's pixels[] to the new PGraphics's pixels[] via arrayCopy(): :-bd
    https://Processing.org/reference/arrayCopy_.html

    That's why the passed PGraphics variable needs to be reassigned to the new rescaled PGraphics returned by changeTextureSize(); so it now points to the modified PGraphics rather than its previous 1. :bz

  • In short, b/c a PGraphics object can't be mutated in situ for rescaling purposes, those changes need to be transferred to another PGraphics. #:-S

    And its variable needs to be reassigned to that new PGraphics if we want that to point to it. 8-X

  • @jeremydouglass @GoToLoop Thank you both of you for the very comprehensive explanations.

    As far as I understand a python transcription of the snippet would roughly look like this:

    in setup():

    global pg_render, pg_dof, pg_tmp, geombuffer ...
    
    context = DwPixelFlow(this)
    scene_display = MySceneDisplay() 
    geombuffer = DwScreenSpaceGeometryBuffer(context, scene_display)
    dof = DepthOfField(context)
    
    pg_render = createGraphics(width, height, P3D)
    pg_dof = createGraphics(width, height, P3D)
    pg_tmp = createGraphics(width, height, P3D)
    
    
    pg_render = DwUtils.changeTextureSize(this, pg_render, width, height, 8, [False])
    pg_dof    = DwUtils.changeTextureSize(this, pg_dof, width, height, 0, [False])
    pg_tmp    = DwUtils.changeTextureSize(this, pg_tmp, width, height, 0, [False], GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    

    in draw():

    if APPLY_DOF:
      geombuffer.update(pg_render)
    
      DwFilter.get(context).gaussblur.apply(geombuffer.pg_geom, geombuffer.pg_geom, pg_tmp, int(Math.pow(mult_blur, 0.33)))
    
      dof.param.focus_pos = [0.5, 0.5]
      dof.param.focus_pos[0] = map(mouseX+0.5, 0, width , 0, 1)
      dof.param.focus_pos[1] = map(mouseY+0.5, 0, height, 1, 0)
      dof.param.mult_blur = mult_blur
      dof.apply(pg_render, pg_dof, geombuffer)
    
      DwFilter.get(context).copy.apply(pg_dof, pg_render)
    

    class():

    class MySceneDisplay(DwSceneDisplay): 
        def display(_, canvas): displayScene(canvas)
    

    The problems I'm facing:

    • in setup GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT doesn't seem to work.
    • in draw geombuffer.update(pg_render) doesn't work either and I guess it's because I didn't declared pg_render correctly (because there's no such thing as PGraphics3D pg_render in Python)
  • edited May 2018 Answer ✓

    ... GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT don't seem to work.

    Have you imported the interface GL2 from package com.jogamp.opengl before using its constants? :-\"
    http://JogAmp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GL2.html

    import com.jogamp.opengl.GL2; --> from com.jogamp.opengl import GL2

    (because there's no such thing as PGraphics3D pg_render; in Python)

    PGraphics3D is the declared datatype which variable pg_render accepts to be assigned w/ under Java.

    Under Python however, variables hold any datatype reference. No restriction at all! 8->

    Under Java, all reference datatype fields are initialized w/ null by default. ~O)

    Under Python, simply assign them w/ None in order to have the same default behavior. :\">

    PGraphics3D pg_render; --> pg_render = None

    Take a look at the link below in order to learn the default initial value for each Java datatype: ~O)
    https://Docs.Oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

  • edited May 2018

    Thank you for pointing out this omission. Unfortunately, I'm still stuck on line 43:

    for some reason geombuffer.update(pg_render) prevents the sketch from running correctly. I suspect pg_render not to be correctly instantiated...

    add_library('PixelFlow')
    add_library('peasycam')
    from com.jogamp.opengl import GL2
    import java.util.Locale
    
    liste = []
    
    def setup():
        global geombuffer, context, scene_display, dof, magnifier, pg_render, pg_dof, pg_tmp
        size(800, 600, P3D)
        cam = PeasyCam(this, 1000)
        context = DwPixelFlow(this)
        scene_display = MySceneDisplay() 
        geombuffer = DwScreenSpaceGeometryBuffer(context, scene_display)
        dof = DepthOfField(context)
    
        mag_h = int(height/3)
        magnifier = DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h)
    
        pg_render = DwUtils.changeTextureSize(this, None, width, height, 8, [False])
        pg_dof    = DwUtils.changeTextureSize(this, None, width, height, 0, [False])
        pg_tmp    = DwUtils.changeTextureSize(this, None, width, height, 0, [False], GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    
        for e in range(100):
            liste.append(PVector(random(width), random(height), random(height)))
    
        cam.feed()
        perspective(60 * DEG_TO_RAD, width/float(height), 2, 6000)
    
        stroke(255)
        strokeWeight(10)
    
    
    def draw():
        background(0)
    
        displaySceneWrap(pg_render)
    
        geombuffer.update(pg_render)
    
    
    def displaySceneWrap(canvas):
        canvas.beginDraw()
        DwUtils.copyMatrices(this.g, canvas)
        canvas.blendMode(PConstants.BLEND)
        canvas.background(2)
        displayScene(canvas)
        canvas.endDraw()
    
    
    def displayScene(canvas):
        canvas.directionalLight(255, 255, 255, 200,600,400)
        canvas.directionalLight(255, 255, 255, -200,-600,-400)
        canvas.ambientLight(64, 64, 64)
    
        if canvas == geombuffer.pg_geom:
            canvas.background(255, 255)
            canvas.pgl.clearColor(1, 1, 1, 6000)
            canvas.pgl.clear(PGL.COLOR_BUFFER_BIT)
    
        sceneShape(canvas)
    
    
    def sceneShape(canvas):
        translate(-width/2, -height/2)
        for e in liste:
            point(e.x, e.y, e.z)
    
    
    class MySceneDisplay(DwSceneDisplay): 
        def display(_, canvas): displayScene(canvas)
    
  • edited May 2018

    I wonder if you 1st was able to transpile back the ".java" sketch as a ".pde" in order to run it under Java Mode? :-?

    • Like removing the statement w/ the package keyword.
    • The public class DepthOfField_Demo extends PApplet { statement & its corresponding closing curly brace.
    • And of course, the whole public static void main(String args[]) { code block. #:-S

    That whole code is æsthetically messy. But here's what I've come w/ as a ".pde" file w/o changing the original ".java" 1 much: :P

    "Depth_of_Field.pde":

    // Depth of Field (DoF) (1.20)
    // Thomas Diewald (diwi) (2017-Oct-07)
    
    // GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
    // DepthOfField_Demo/DepthOfField_Demo.java
    
    import static java.util.Locale.ENGLISH;
    
    import com.jogamp.opengl.GL2;
    
    import peasy.PeasyCam;
    
    import com.thomasdiewald.pixelflow.java.DwPixelFlow;
    import com.thomasdiewald.pixelflow.java.geometry.DwCube;
    import com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DepthOfField;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwSceneDisplay;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwScreenSpaceGeometryBuffer;
    import com.thomasdiewald.pixelflow.java.utils.DwMagnifier;
    import com.thomasdiewald.pixelflow.java.utils.DwUtils;
    
    static final String POSITION = "position: (%7.3f, %7.3f, %7.3f)\n";
    static final String ROTATION = "rotation: (%7.3f, %7.3f, %7.3f)\n";
    static final String LOOK_AT  = "look-at:  (%7.3f, %7.3f, %7.3f)\n";
    static final String DISTANCE = "distance: (%7.3f)\n";
    
    static final String FPS = "   [fps %6.2f]";
    
    boolean start_fullscreen = false;
    
    int viewport_w = 1000;
    int viewport_h = 600;
    int viewport_x = 200;
    int viewport_y = 0;
    
    // camera control
    PeasyCam peasycam;
    
    // library context
    DwPixelFlow context;
    
    PShape shp_scene;
    
    PGraphics3D pg_render;
    PGraphics3D pg_dof;
    PGraphics3D pg_tmp;
    
    DepthOfField dof;
    DwScreenSpaceGeometryBuffer geombuffer;
    
    DwMagnifier magnifier;
    
    boolean apply_dof = true;
    
    void settings() {
      if (!start_fullscreen)  size(viewport_w, viewport_h, P3D);
      else {
        fullScreen(P3D);
        viewport_w = displayWidth;
        viewport_h = displayHeight;
        viewport_x = 0;
        viewport_y = 0;
      }
    
      noSmooth();
    }
    
    void setup() {
      surface.setResizable(true);
      surface.setLocation(viewport_x, viewport_y);
    
      // camera
      peasycam = new PeasyCam(this, -4.083, -6.096, 7.000, 1300);
      peasycam.setRotations(1.085, -0.477, 2.910);
    
      // main library context
      context = new DwPixelFlow(this);
      context.print();
      context.printGL();
    
      // callback for scene display (used in GBAA)
      DwSceneDisplay scene_display = new DwSceneDisplay() {  
        @ Override public void display(PGraphics3D canvas) {
          displayScene(canvas);
        }
      };
    
      geombuffer = new DwScreenSpaceGeometryBuffer(context, scene_display);
    
      dof = new DepthOfField(context);
    
      int mag_h = height/3;
      magnifier = new DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h);
    
      frameRate(1000);
    }
    
    void draw() {
      resizeScreen();
      displaySceneWrap(pg_render);
      DwFilter.get(context).gamma.apply(pg_render, pg_render);
    
      int mult_blur = 30;
    
      if (apply_dof) {
        geombuffer.update(pg_render);
    
        DwFilter.get(context).gaussblur.apply(geombuffer.pg_geom, geombuffer.pg_geom, 
          pg_tmp, (int) Math.pow(mult_blur, 0.33));
    
        //      dof.param.focus     = map(mouseX, 0, width, 0, 1);
        dof.param.focus_pos = new float[]{0.5, 0.5};
        dof.param.focus_pos[0] = map(mouseX+0.5, 0, width, 0, 1);
        dof.param.focus_pos[1] = map(mouseY+0.5, 0, height, 1, 0);
        dof.param.mult_blur = mult_blur;
        dof.apply(pg_render, pg_dof, geombuffer);
    
        DwFilter.get(context).copy.apply(pg_dof, pg_render);
      }
    
      magnifier.apply(pg_render, mouseX, mouseY);
      magnifier.displayTool();
    
      DwUtils.beginScreen2D(g);
      //    peasycam.beginHUD();
      {
        blendMode(REPLACE);
        clear();
        image(pg_render, 0, 0);
        //      image(geombuffer.pg_geom, 0, 0);
    
        magnifier.display(g, 0, height-magnifier.h);
    
        blendMode(BLEND);
    
        pushMatrix();
        float cursor_s = 10;
    
        float fpx = dof.param.focus_pos[0] * width;
        float fpy = (1.0 - dof.param.focus_pos[1]) * height;
    
        blendMode(EXCLUSION);
        translate(fpx, fpy);
        strokeWeight(1);
        stroke(255, 200);
        line(-cursor_s, 0, +cursor_s, 0);
        line(0, -cursor_s, 0, +cursor_s);
        blendMode(BLEND);
        popMatrix();
      }
      //    peasycam.endHUD();
      DwUtils.endScreen2D(g);
    
      String txt_fps = String.format(getClass().getName() + FPS, frameRate);
      surface.setTitle(txt_fps);
    }
    
    void keyReleased() {
      if (keyCode == 'C') printCam();
      else if (key == ' ') apply_dof = !apply_dof;
    }
    
    boolean resizeScreen() { // dynamically resize render-targets
      final boolean[] resized = { false };
    
      pg_render = DwUtils.changeTextureSize(this, pg_render, width, height, 8, resized);
      pg_dof    = DwUtils.changeTextureSize(this, pg_dof, width, height, 0, resized);
      pg_tmp    = DwUtils.changeTextureSize(this, pg_tmp, width, height, 0, resized, 
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
      //    geombuffer.resize(width, height)
    
      if (resized[0]) {
        // nothing here
      }
    
      peasycam.feed();
      perspective(60 * DEG_TO_RAD, width/(float)height, 2, 6000);
    
      return resized[0];
    }
    
    void displaySceneWrap(PGraphics3D canvas) {
      canvas.beginDraw();
      DwUtils.copyMatrices((PGraphics3D) this.g, canvas);
    
      canvas.blendMode(PConstants.BLEND);
      canvas.background(2);
      displayScene(canvas);
      canvas.endDraw();
    }
    
    void displayScene(PGraphics3D canvas) {
      canvas.directionalLight(255, 255, 255, 200, 600, 400);
      canvas.directionalLight(255, 255, 255, -200, -600, -400);
      canvas.ambientLight(64, 64, 64);
    
      if (canvas == geombuffer.pg_geom) {
        canvas.background(255, 255);
        canvas.pgl.clearColor(1, 1, 1, 6000);
        canvas.pgl.clear(PGL.COLOR_BUFFER_BIT);
      }
    
      sceneShape(canvas);
    }
    
    void sceneShape(PGraphics3D canvas) {
      if (shp_scene != null) {
        canvas.shape(shp_scene);
        return;
      }
    
      shp_scene = createShape(GROUP);
    
      int num_boxes = 50;
      int num_spheres = 50;
      float bb_size = 800;
      float xmin = -bb_size;
      float xmax = +bb_size;
      float ymin = -bb_size;
      float ymax = +bb_size;
      float zmin =  0;
      float zmax = +bb_size;
    
      colorMode(HSB, 360, 1, 1);
      randomSeed(0);
    
      for (int i = 0; i < num_boxes; i++) {
        float px = random(xmin, xmax);
        float py = random(ymin, ymax);
        float sx = random(200) + 10;
        float sy = random(200) + 10;
        float sz = random(zmin, zmax);
    
        float off = 45;
        float base = 0;
        float hsb_h = base + random(-off, off);
        float hsb_s = 1;
        float hsb_b = random(0.1, 1.0);
        int shading = color(hsb_h, hsb_s, hsb_b);
    
        PShape shp_box = createShape(BOX, sx, sy, sz);
        shp_box.setFill(true);
        shp_box.setStroke(false);
        shp_box.setFill(shading);
        shp_box.translate(px, py, sz*.5);
        shp_scene.addChild(shp_box);
      }
    
      DwCube cube_smooth = new DwCube(4);
      DwCube cube_facets = new DwCube(2);
    
      for (int i = 0; i < num_spheres; i++) {
        float px = random(xmin, xmax);
        float py = random(ymin, ymax);
        float pz = random(zmin, zmax);
        float rr = random(50) + 50;
        boolean facets = true;//(i%2 == 0);
    
        float off = 20;
        float base = 225;
        float hsb_h = base + random(-off, off);
        float hsb_s = 1;
        float hsb_b = random(0.1, 1.0);
        int shading = color(hsb_h, hsb_s, hsb_b);
    
        PShape shp_sphere = createShape(PShape.GEOMETRY);
        if (facets) {
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, false);
        } else {
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, true);
        }
    
        shp_sphere.setStroke(!true);
        shp_sphere.setStroke(color(0));
        shp_sphere.setStrokeWeight(0.01 / rr);
        shp_sphere.setFill(true);
        shp_sphere.setFill(shading);
        shp_sphere.resetMatrix();
        shp_sphere.scale(rr);
        shp_sphere.translate(px, py, pz);
        shp_scene.addChild(shp_sphere);
      }
    
      colorMode(RGB, 255, 255, 255);
    
      PShape shp_rect = createShape(RECT, -1000, -1000, 2000, 2000);
      shp_rect.setStroke(false);
      shp_rect.setFill(true);
      shp_rect.setFill(color(255));
    
      shp_scene.addChild(shp_rect);
    }
    
    PShape createGridXY(int lines, float s) {
      PShape shp_gridxy = createShape();
      shp_gridxy.beginShape(LINES);
      shp_gridxy.stroke(0);
      shp_gridxy.strokeWeight(1);
      float d = lines*s;
    
      for (int i = 0; i <= lines; i++) {
        shp_gridxy.vertex(-d, -i*s, 0); 
        shp_gridxy.vertex(d, -i*s, 0);
        shp_gridxy.vertex(-d, +i*s, 0); 
        shp_gridxy.vertex(d, +i*s, 0);
    
        shp_gridxy.vertex(-i*s, -d, 0); 
        shp_gridxy.vertex(-i*s, d, 0);
        shp_gridxy.vertex(+i*s, -d, 0); 
        shp_gridxy.vertex(+i*s, d, 0);
      }
    
      shp_gridxy.endShape();
      return shp_gridxy;
    }
    
    void printCam() {
      float[] pos = peasycam.getPosition();
      float[] rot = peasycam.getRotations();
      float[] lat = peasycam.getLookAt();
      float   dis = (float) peasycam.getDistance();
    
      System.out.printf(ENGLISH, POSITION, pos[0], pos[1], pos[2]);
      System.out.printf(ENGLISH, ROTATION, rot[0], rot[1], rot[2]);
      System.out.printf(ENGLISH, LOOK_AT, lat[0], lat[1], lat[2]);
      System.out.printf(ENGLISH, DISTANCE, dis);
    }
    
  • edited May 2018

    @GoToLoop Apologies for the late reply. Wow, I don't know how to thank you for all the work and time you've dedicated to this .pde transcription, really. It's going to be very helpful for my own .pyde transcription. I'll let you know when I'm done working on this DoF sketch.

  • edited May 2018

    I'm back with another question, sorry. I still have a persistent issue with the resizeScreen() function and more particularly with thepg_render and pg_tmp grahics buffers variables.

    When running the .pyde script I get the following error messages:

    GammaCorrection.apply shader | GL_ERROR: invalid operation GammaCorrection.apply | GL_ERROR: invalid operation GammaCorrection.apply | GL_ERROR: invalid framebuffer operation

    This occurs at line 110 (Java script) or 58 (Python version):

    DwFilter.get(context).gamma.apply(pg_render, pg_render)

    Do you know what could be the problem here ?

    Here below, for comparison purposes:

    • a shortened version of the original DoF example sketch in Java (working)
    • the Python transcription of this version (not working)

    Java

    import java.util.Locale;
    import com.jogamp.opengl.GL2;
    import com.thomasdiewald.pixelflow.java.DwPixelFlow;
    import com.thomasdiewald.pixelflow.java.geometry.DwCube;
    import com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DepthOfField;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwSceneDisplay;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwScreenSpaceGeometryBuffer;
    import com.thomasdiewald.pixelflow.java.utils.DwMagnifier;
    import com.thomasdiewald.pixelflow.java.utils.DwUtils;
    
    import peasy.*;
    import processing.core.PApplet;
    import processing.core.PConstants;
    import processing.core.PShape;
    import processing.opengl.PGL;
    import processing.opengl.PGraphics3D;
    
    
      boolean START_FULLSCREEN = !true;
    
      int viewport_w = 1280;
      int viewport_h = 720;
      int viewport_x = 230;
      int viewport_y = 0;
    
      // camera control
      PeasyCam peasycam;
    
      // library context
      DwPixelFlow context;
    
      PGraphics3D pg_render;
      PGraphics3D pg_dof;
      PGraphics3D pg_tmp;
    
      DepthOfField dof;
      DwScreenSpaceGeometryBuffer geombuffer;
    
      boolean APPLY_DOF = true;
    
    
      public void settings() {
        if(START_FULLSCREEN){
          viewport_w = displayWidth;
          viewport_h = displayHeight;
          viewport_x = 0;
          viewport_y = 0;
          fullScreen(P3D);
        } else {
          size(viewport_w, viewport_h, P3D);
        }
        smooth(0);
      }
    
    
      public void setup() {
    
        // camera
        peasycam = new PeasyCam(this, -4.083,  -6.096,   7.000, 1300);
        peasycam.setRotations(  1.085,  -0.477,   2.910);
    
        // main library context
        context = new DwPixelFlow(this);
        context.print();
        context.printGL();
    
        // callback for scene display (used in GBAA)
        DwSceneDisplay scene_display = new DwSceneDisplay() {  
          @Override
          public void display(PGraphics3D canvas) {
            displayScene(canvas); 
          }
        };
    
        geombuffer = new DwScreenSpaceGeometryBuffer(context, scene_display);
    
        dof = new DepthOfField(context);
    
        frameRate(1000);
      }
    
    
    
      // dynamically resize render-targets
      public boolean resizeScreen(){
    
        boolean[] RESIZED = {false};
    
        pg_render = DwUtils.changeTextureSize(this, pg_render, width, height, 8, RESIZED);
        pg_dof    = DwUtils.changeTextureSize(this, pg_dof   , width, height, 0, RESIZED);
        pg_tmp    = DwUtils.changeTextureSize(this, pg_tmp   , width, height, 0, RESIZED, GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
    
        peasycam.feed();
        perspective(60 * DEG_TO_RAD, width/(float)height, 2, 6000);
    
        return RESIZED[0];
      }
    
    
    
      public void draw() {
    
        resizeScreen();
    
        displaySceneWrap(pg_render);
    
        DwFilter.get(context).gamma.apply(pg_render, pg_render);
    
        int mult_blur = 30;
        geombuffer.update(pg_render);
    
        DwFilter.get(context).gaussblur.apply(geombuffer.pg_geom, geombuffer.pg_geom, pg_tmp, (int) Math.pow(mult_blur, 0.33f));
    
    ////      dof.param.focus     = map(mouseX, 0, width, 0, 1);
        dof.param.focus_pos = new float[]{0.5f, 0.5f};
        dof.param.focus_pos[0] = map(mouseX+0.5f, 0, width , 0, 1);
        dof.param.focus_pos[1] = map(mouseY+0.5f, 0, height, 1, 0);
        dof.param.mult_blur = mult_blur;
        dof.apply(pg_render, pg_dof, geombuffer);
    
        DwFilter.get(context).copy.apply(pg_dof, pg_render);
    
    
        DwUtils.beginScreen2D(g);
        {
          blendMode(REPLACE);
          clear();
          image(pg_render, 0, 0);    
        }
        DwUtils.endScreen2D(g);
      }
    
    
    
      public void displaySceneWrap(PGraphics3D canvas){
        canvas.beginDraw();
        DwUtils.copyMatrices((PGraphics3D) this.g, canvas);
        // background
        canvas.blendMode(PConstants.BLEND);
        canvas.background(2);
        displayScene(canvas);
        canvas.endDraw();
      }
    
    
    
      // render something
      public void displayScene(PGraphics3D canvas){
        // lights
        canvas.directionalLight(255, 255, 255, 200,600,400);
        canvas.directionalLight(255, 255, 255, -200,-600,-400);
        canvas.ambientLight(64, 64, 64);
    
        if(canvas == geombuffer.pg_geom){
          canvas.background(255, 255);
          canvas.pgl.clearColor(1, 1, 1, 6000);
          canvas.pgl.clear(PGL.COLOR_BUFFER_BIT);
        }
    
    
        sceneShape(canvas);
      }
    
      PShape shp_scene;
    
      public void sceneShape(PGraphics3D canvas){
        if(shp_scene != null){
          canvas.shape(shp_scene);
          return;
        }
    
        shp_scene = createShape(GROUP);
    
        int num_spheres = 50;
        float bb_size = 800;
        float xmin = -bb_size;
        float xmax = +bb_size;
        float ymin = -bb_size;
        float ymax = +bb_size;
        float zmin =  0;
        float zmax = +bb_size;
    
        colorMode(HSB, 360, 1, 1);
    
        DwCube cube_smooth = new DwCube(4);
        DwCube cube_facets = new DwCube(2);
    
        for(int i = 0; i < num_spheres; i++){
          float px = random(xmin, xmax);
          float py = random(ymin, ymax);
          float pz = random(zmin, zmax);
          float rr = random(50) + 50;
          boolean facets = true;//(i%2 == 0);
    
          float off = 20;
          float base = 225;
          float hsb_h = base + random(-off,off);
          float hsb_s = 1;
          float hsb_b = random(0.1f,1.0f);
          int shading = color(hsb_h, hsb_s, hsb_b);
    
          PShape shp_sphere = createShape(PShape.GEOMETRY);
          if(facets){
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, false);
          } else {
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, true);
          }
    
          shp_sphere.setStroke(!true);
          shp_sphere.setStroke(color(0));
          shp_sphere.setStrokeWeight(0.01f / rr);
          shp_sphere.setFill(true);
          shp_sphere.setFill(shading);
          shp_sphere.resetMatrix();
          shp_sphere.scale(rr);
          shp_sphere.translate(px, py, pz);
          shp_scene.addChild(shp_sphere);
        }
    
      }
    

    Python

    add_library('PixelFlow')
    add_library('peasycam')
    from com.jogamp.opengl import GL2
    import java.util.Locale
    
    liste = []
    viewport_w = 1280
    viewport_h = 720
    viewport_x = 0
    viewport_y = 0
    FS = False
    
    def settings():
        global viewport_w, viewport_h
        if FS:
            viewport_w = displayWidth
            viewport_h = displayHeight
            viewport_x = 0
            viewport_y = 0
            fullScreen(P3D)
        else:
            size(viewport_w, viewport_h, P3D)
        smooth(0)
    
    
    def setup():
        global context, scene_display, geombuffer, dof, cam
    
        cam = PeasyCam(this, -4.083,  -6.096,   7.000, 1300)
    
        context = DwPixelFlow(this)
        context.print()
        context.printGL()
    
        scene_display = MySceneDisplay() 
        geombuffer = DwScreenSpaceGeometryBuffer(context, scene_display)
        dof = DepthOfField(context)
    
    
    def resizeScreen():
        global pg_render, pg_dof, pg_tmp
        RESIZED = [False]
        pg_render = DwUtils.changeTextureSize(this, None, width, height, 8, RESIZED)
        pg_dof    = DwUtils.changeTextureSize(this, None, width, height, 0, RESIZED)
        pg_tmp    = DwUtils.changeTextureSize(this, None, width, height, 0, RESIZED, GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    
        cam.feed()
        perspective(60 * DEG_TO_RAD, width/float(height), 2, 6000)
    
        return RESIZED[0]
    
    
    def draw():
        resizeScreen()
    
        displaySceneWrap(pg_render)
    
        DwFilter.get(context).gamma.apply(pg_render, pg_render)
    
        mult_blur = 30
    
        geombuffer.update(pg_render)
    
        DwFilter.get(context).gaussblur.apply(geombuffer.pg_geom, geombuffer.pg_geom, pg_tmp, int(Math.pow(mult_blur, 0.33)))
    
        dof.param.focus_pos = float(0.5, 0.5)
        dof.param.focus_pos[0] = map(mouseX+0.5, 0, width, 0, 1)
        dof.param.focus_pos[1] = map(mouseY+0.5, 0, height, 1, 0)
        dof.param.mult_blur = mult_blur
        dof.apply(pg_render, pg_dof, geombuffer)
    
        DwFilter.get(context).copy.apply(pg_dof, pg_render)
    
        DwUtils.beginScreen2D(g)
        blendMode(REPLACE)
        clear()
        image(pg.render,0,0)
        DwUtils.endScreen2D(g)
    
    
    def displaySceneWrap(canvas):
        canvas.beginDraw()
        DwUtils.copyMatrices(this.g, canvas)
        canvas.blendMode(PConstants.BLEND)
        canvas.background(2)
        displayScene(canvas)
        canvas.endDraw()
    
    def displayScene(canvas):
        canvas.directionalLight(255, 255, 255, 200,600,400)
        canvas.directionalLight(255, 255, 255, -200,-600,-400)
        canvas.ambientLight(64, 64, 64)
    
        if canvas == geombuffer.pg_geom:
            canvas.background(255, 255)
            canvas.pgl.clearColor(1, 1, 1, 6000)
            canvas.pgl.clear(PGL.COLOR_BUFFER_BIT)
    
        sceneShape(canvas)
    
    
    def sceneShape(canvas): 
    
        shp_scene = createShape(GROUP)
    
        if shp_scene != None:
            canvas.shape(shp_scene)
            return   
    
        num_spheres = 50
        bb_size = 800
        xmin = -bb_size
        xmax = +bb_size
        ymin = -bb_size
        ymax = +bb_size
        zmin =  0
        zmax = +bb_size
    
        colorMode(HSB, 360, 1, 1)
    
        cube_smooth = DwCube(4)
        cube_facets = DwCube(2)
    
        for i in range(num_spheres):
            px = random(xmin, xmax)
            py = random(ymin, ymax)
            pz = random(zmin, zmax)
            facets = True
    
            off = 20
            base =225
            hsb_h = base + random(-off, off)
            hsb_s = 1
            hsb_b = random(0.1, 1.0)
            shading = color(hsb_h, hsb_s, hsb_b)
    
        shp_sphere = createShape(PShape.GEOMETRY)
        if facets:
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, False)
        else:
            DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, True)
    
        shp_sphere.setStroke(False);
        shp_sphere.setStroke(color(0));
        shp_sphere.setStrokeWeight(0.01 / rr);
        shp_sphere.setFill(True);
        shp_sphere.setFill(shading);
        shp_sphere.resetMatrix();
        shp_sphere.scale(rr);
        shp_sphere.translate(px, py, pz);
        shp_scene.addChild(shp_sphere);
    
    
    class MySceneDisplay(DwSceneDisplay): 
        def display(_, canvas): displayScene(canvas)
    
  • edited May 2018

    In other words, and to make it easier to understand...

    In the working Java sketch I have something like this:

    public void setup() {
        ...
    
    public boolean resizeScreen(){
    
      boolean[] RESIZED = {false};
    
      pg_render = DwUtils.changeTextureSize(this, pg_render, width, height, 8, RESIZED);
      pg_dof    = DwUtils.changeTextureSize(this, pg_dof   , width, height, 0, RESIZED);
      pg_tmp    = DwUtils.changeTextureSize(this, pg_tmp   , width, height, 0, RESIZED, GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
    
      peasycam.feed();
      perspective(60 * DEG_TO_RAD, width/(float)height, 2, 6000);
    
      return RESIZED[0];
      }
    
    
    
    public void draw() {
    
      resizeScreen();
    
      displaySceneWrap(pg_render);
    
      DwFilter.get(context).gamma.apply(pg_render, pg_render);
      ...
    

    Python version

    def setup():
        ...
    
    def resizeScreen():
    
        RESIZED = [False]
    
        pg_render = DwUtils.changeTextureSize(this, None, width, height, 8, RESIZED)
        pg_dof    = DwUtils.changeTextureSize(this, None, width, height, 0, RESIZED)
        pg_tmp    = DwUtils.changeTextureSize(this, None, width, height, 0, RESIZED, GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    
        cam.feed()
        perspective(60 * DEG_TO_RAD, width/float(height), 2, 6000)
    
        return RESIZED[0]
    
    
    def draw():
        resizeScreen()
    
        displaySceneWrap(pg_render)
    
        DwFilter.get(context).gamma.apply(pg_render, pg_render)
        ...
    

    However, although the Python version looks similar to the Java script, it doesn't work (Processing suddenly quits).

    When I add: global pg_render, pg_dof, pg_tmp just below def resizeScreen() the script runs but then I get the errors I mentionned before:

    GammaCorrection.apply shader | GL_ERROR: invalid operation GammaCorrection.apply | GL_ERROR: invalid operation GammaCorrection.apply | GL_ERROR: invalid framebuffer operation

    Would love your insight @GoToLoop

  • I really would like some help with that Python script... it's been weeks i'm working on that Depth of Field effect without finding a proper solution. Could you give me a hand finding what's wrong with the .pyde script ?

  • edited May 2018

    Hi @solub! It took a long time, but I've just finished refactoring "Depth_of_Field.pde". #:-S

    Now that I've reorganized this sketch, I'm ready to convert it to a ".pyde" file. :)>-

    Just w8 a lil' more. Stay w/ the latest ".pde" file for now: :-\"

    /**
     * Depth of Field (DoF) (1.20)
     * Thomas Diewald (diwi) (2017-Oct-07)
    
     * GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
     * DepthOfField_Demo/DepthOfField_Demo.java
    
     * Refactor by GoToLoop (v1.4.2) (2018-May-18) (PDE v3.3.5)
     * Forum.Processing.org/two/discussion/27905/converting-java-code-to-python#Item_18
     */
    
    import com.thomasdiewald.pixelflow.java.DwPixelFlow;
    import com.thomasdiewald.pixelflow.java.geometry.DwIndexedFaceSetAble;
    import com.thomasdiewald.pixelflow.java.geometry.DwCube;
    import com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DepthOfField;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwSceneDisplay;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwScreenSpaceGeometryBuffer;
    import com.thomasdiewald.pixelflow.java.utils.DwMagnifier;
    import com.thomasdiewald.pixelflow.java.utils.DwUtils;
    
    import peasy.PeasyCam;
    
    import com.jogamp.opengl.GL2;
    
    import static java.util.Locale.ENGLISH;
    import java.util.Formatter;
    
    final Formatter formatter = new Formatter(ENGLISH);
    
    static final String POSITION = "position: (%8.2f, %8.2f, %8.2f)\n";
    static final String ROTATION = "rotation: (%8.2f, %8.2f, %8.2f)\n";
    static final String LOOK__AT = "look-at:  (%8.2f, %8.2f, %8.2f)\n";
    static final String DISTANCE = "distance: (%8.2f)\n";
    
    final String TITLE = getClass().getName() + "   [fps %6.2f]";
    
    static final int BB_SIZE = 800, BB_OFFSET = BB_SIZE >> 2;
    static final int BB_TOTAL = BB_SIZE + BB_OFFSET;
    static final int BB_COORD = -BB_TOTAL, BB_DIAM = BB_TOTAL << 1;
    
    static final int XMIN = -BB_SIZE, XMAX = BB_SIZE;
    static final int YMIN = -BB_SIZE, YMAX = BB_SIZE;
    static final int ZMIN = 0, ZMAX = BB_SIZE;
    
    static final int BOX_DIAM = BB_OFFSET + BB_OFFSET/20;
    static final int SPH_MIN_D = BB_OFFSET >> 2, SPH_MAX_D = BB_OFFSET >> 1;
    
    static final int BOXES = 50, SPHERES = 50;
    
    static final int CROSS_S = 10, ZFAR = 6000;
    static final int MULT_BLUR = 30, BLUR_POW = (int) pow(MULT_BLUR, 1/3.0);
    static final float RAD60 = 60*DEG_TO_RAD, FPS = 60;
    
    static final color BASE_COL = 0x80FFFFFF, CROSS_COL = 0xd0FFFFFF;
    
    static final long SEED = 0;
    static final boolean FIXED_SEED = false;
    
    static final boolean FULLSCREEN = false, RESIZABLE = false;
    boolean apply_dof = false, alt_render = false;
    
    final boolean[] resized = new boolean[1];
    
    final DwIndexedFaceSetAble cube_smooth = new DwCube(4), cube_facets = new DwCube(2);
    
    PGraphics3D pg_render, pg_dof, pg_tmp;
    PShape shp_scene;
    
    PeasyCam peasy;
    
    DwPixelFlow context;
    DwFilter dw_filter;
    DepthOfField dof;
    DwScreenSpaceGeometryBuffer geombuffer;
    DwMagnifier magnifier;
    
    void settings() {
      if (FULLSCREEN) fullScreen(P3D);
      else size(displayWidth*9/10, displayHeight*9/10, P3D);
      noSmooth();
    }
    
    void setup() {
      frameRate(FPS);
      cursor(CROSS);
    
      if (RESIZABLE)  getSurface().setResizable(true);
      getSurface().setLocation(displayWidth - width >> 1, 8);
    
      peasy = new PeasyCam(this, -4.083, -6.096, 7, 2000);
      peasy.setRotations(1.085, -.477, 2.91);
    
      dw_filter = DwFilter.get(context = new DwPixelFlow(this));
      context.print();
      context.printGL();
    
      dof = new DepthOfField(context);
      dof.param.mult_blur = MULT_BLUR;
    
      final DwSceneDisplay scene_display = new DwSceneDisplay() {  
        @ Override final public void display(final PGraphics3D canvas) {
          displayScene(canvas);
        }
      };
    
      geombuffer = new DwScreenSpaceGeometryBuffer(context, scene_display);
    
      final int mag_h = height/3;
      magnifier = new DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h);
    }
    
    void draw() {
      final PGraphics canv = getGraphics();
      final DepthOfField.Param param = dof.param;
    
      setTitle();
      resizeScreen();
      displaySceneWrap(pg_render, canv);
      dw_filter.gamma.apply(pg_render, pg_render);
    
      if (apply_dof)  applyDoF(param);
      renderScene(param, canv);
    }
    
    void keyPressed() {
      final int k = keyCode;
    
      if (k == ENTER | k == RETURN)  shp_scene = null;
      else if (k == 'C' | k == CONTROL)  printCam();
      else if (k == 'P' | k == BACKSPACE)  looping ^= true;
      else if (k == ' ')  apply_dof ^= true;
      else if (k == SHIFT)  alt_render ^= true;
    }
    
    void applyDoF(final DepthOfField.Param param) {
      final PGraphicsOpenGL geom = geombuffer.pg_geom;
      dw_filter.gaussblur.apply(geom, geom, pg_tmp, BLUR_POW);
    
      param.focus_pos[0] = map(mouseX + .5, 0, width, 00, 1);
      param.focus_pos[1] = map(mouseY + .5, 0, height, 1, 0);
      dof.apply(pg_render, pg_dof, geombuffer);
    
      dw_filter.copy.apply(pg_dof, pg_render);
    }
    
    void renderScene(final DepthOfField.Param param, final PGraphics canv) {
      final PGraphics pg = alt_render? geombuffer.pg_geom : pg_render;
    
      magnifier.apply(pg, mouseX, mouseY);
      magnifier.displayTool();
    
      DwUtils.beginScreen2D(canv);
      //peasy.beginHUD();
    
      blendMode(REPLACE);
      image(pg, 0, 0);
      magnifier.display(pg, 0, height - magnifier.h);
    
      final float fpx = param.focus_pos[0] * width;
      final float fpy = (1 - param.focus_pos[1]) * height;
    
      blendMode(EXCLUSION);
      strokeCap(PROJECT);
      stroke(CROSS_COL);
      line(fpx - CROSS_S, fpy, fpx + CROSS_S, fpy);
      line(fpx, fpy - CROSS_S, fpx, fpy + CROSS_S);
      blendMode(BLEND);
    
      //peasy.endHUD();
      DwUtils.endScreen2D(canv);
    }
    
    boolean resizeScreen() { // dynamically resize render-targets
      final int w = width, h = height;
    
      perspective(RAD60, (float) w/h, 2, ZFAR);
      peasy.feed();
    
      boolean happened = resized[0] = false;
      pg_render = DwUtils.changeTextureSize(this, pg_render, w, h, 8, resized);
      happened |= resized[0];
    
      resized[0] = false;
      pg_dof = DwUtils.changeTextureSize(this, pg_dof, w, h, 0, resized);
      happened |= resized[0];
    
      resized[0] = false;
      pg_tmp = DwUtils.changeTextureSize(this, pg_tmp, w, h, 0, resized, 
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
      geombuffer.update(pg_render);
      return happened | resized[0];
    }
    
    void displaySceneWrap(final PGraphics3D canvas, final PGraphics canv) {
      DwUtils.copyMatrices((PGraphicsOpenGL) canv, canvas);
      canvas.beginDraw();
      canvas.background(2);
      displayScene(canvas);
      canvas.endDraw();
    }
    
    void displayScene(final PGraphics3D canvas) {
      canvas.directionalLight(255, 255, 255, 200, 600, 400);
      canvas.directionalLight(255, 255, 255, -200, -600, -400);
      canvas.ambientLight(64, 64, 64);
    
      if (canvas == geombuffer.pg_geom) {
        canvas.background(-1);
        canvas.pgl.clearColor(1, 1, 1, ZFAR);
        canvas.pgl.clear(PGL.COLOR_BUFFER_BIT);
      }
    
      if (shp_scene == null)  shp_scene = makeShape();
      canvas.shape(shp_scene);
    }
    
    PShape makeShape() {
      final PShape scene = createShape(GROUP);
    
      pushStyle();
      colorMode(HSB, 360, 1, 1);
      noStroke();
    
      if (FIXED_SEED)  randomSeed(SEED);
    
      for (int i = 0; i < BOXES; ++i) {
        final float px = random(XMIN, XMAX), py = random(YMIN, YMAX);
        final float sx = random(BOX_DIAM, BOX_DIAM), sy = random(BOX_DIAM, BOX_DIAM);
        final float sz = random(ZMIN, ZMAX);
    
        fill(random(-45, 45), 1, random(.1, 1));
        final PShape shp_box = createShape(BOX, sx, sy, sz);
        shp_box.translate(px, py, sz*.5);
        scene.addChild(shp_box);
      }
    
      for (int i = 0; i < SPHERES; ++i) {
        final float px = random(XMIN, XMAX), py = random(YMIN, YMAX);
        final float pz = random(ZMIN, ZMAX), rr = random(SPH_MIN_D, SPH_MAX_D);
    
        fill(random(205, 245), 1, random(.1, 1));
        final PShape shp_sphere = createShape(PShape.GEOMETRY);
        shp_sphere.scale(rr);
        shp_sphere.translate(px, py, pz);
        scene.addChild(shp_sphere);
    
        if ((i&1) == 0)
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, false);
        else
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, true);
      }
    
      fill(BASE_COL);
      scene.addChild(createShape(RECT, BB_COORD, BB_COORD, BB_DIAM, BB_DIAM));
    
      popStyle();
      return scene;
    }
    
    static final void clearFormatter(final Formatter f) {
      ((StringBuilder) f.out()).setLength(0);
    }
    
    void setTitle() {
      clearFormatter(formatter);
      getSurface().setTitle(formatter.format(TITLE, frameRate).toString());
    }
    
    void printCam() {
      final float[] pos = peasy.getPosition();
      final float[] rot = peasy.getRotations();
      final float[] lat = peasy.getLookAt();
      final double  dis = peasy.getDistance();
    
      clearFormatter(formatter);
    
      println(formatter.
        format(POSITION, pos[0], pos[1], pos[2]).
        format(ROTATION, rot[0], rot[1], rot[2]).
        format(LOOK__AT, lat[0], lat[1], lat[2]).
        format(DISTANCE, dis));
    }
    
  • From the bottom of my heart... Thank You

  • edited May 2018

    Here's my Python Mode attempt. However, it's not working yet, it's just pitch black! :-&

    This statement crashes the sketch: geombuffer.update(pg_render) within resizeScreen(). Even when following exactly what it does, it doesn't seem to render anything. :o3

    https://GitHub.com/diwi/PixelFlow/blob/master/src/com/thomasdiewald/pixelflow/java/render/skylight/DwScreenSpaceGeometryBuffer.java#L67-L79

    public void update(PGraphics3D pg_src){
      
      resize(pg_src.width, pg_src.height);
      
      pg_geom.beginDraw();
      updateMatrices(pg_src);
      pg_geom.blendMode(PConstants.REPLACE);
      pg_geom.clear();
      pg_geom.shader(shader);
      pg_geom.noStroke();
      scene_display.display(pg_geom);
      pg_geom.endDraw();
    }
    

    So I'm at loss about it! Sorry. X_X Try finding help on diwi or jdf. ^#(^

    """
     * Depth of Field (DoF) (1.20)
     * Thomas Diewald (diwi) (2017-Oct-07)
     
     * GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
     * DepthOfField_Demo/DepthOfField_Demo.java
     
     * Refactor by GoToLoop (v1.4.2) (2018-May-18) (PDE v3.3.5)
     * Forum.Processing.org/two/discussion/27905/
     * converting-java-code-to-python#Item_20
    """
    
    add_library('PixelFlow')
    add_library('peasycam')
    
    from com.jogamp.opengl import GL2
    from processing.opengl import PGL
    
    from java.util import Formatter, Locale
    from jarray import zeros
    
    formatter = Formatter(Locale.ENGLISH)
    
    POSITION = 'position: (%8.2f, %8.2f, %8.2f)\n'
    ROTATION = 'rotation: (%8.2f, %8.2f, %8.2f)\n'
    LOOK__AT = 'look-at:  (%8.2f, %8.2f, %8.2f)\n'
    DISTANCE = 'distance: (%8.2f)\n'
    
    TITLE = __file__[:-5] + '   [fps %6.2f]'
    
    BB_SIZE = 800
    BB_OFFSET = BB_SIZE >> 2
    BB_TOTAL = BB_SIZE + BB_OFFSET
    BB_COORD, BB_DIAM = -BB_TOTAL, BB_TOTAL << 1
    
    XMIN, XMAX = -BB_SIZE, BB_SIZE
    YMIN, YMAX = -BB_SIZE, BB_SIZE
    ZMIN, ZMAX = 0, BB_SIZE
    
    BOX_DIAM = BB_OFFSET + BB_OFFSET/20
    SPH_MIN_D, SPH_MAX_D = BB_OFFSET >> 2, BB_OFFSET >> 1
    
    BOXES, SPHERES = 50, 50
    BOX_RANGE, SPH_RANGE = tuple(range(BOXES)), tuple(range(SPHERES))
    
    CROSS_S, ZFAR = 10, 6000
    MULT_BLUR, FPS = 30, 60
    BLUR_POW, RAD60 = pow(MULT_BLUR, 1/3.0), 60*DEG_TO_RAD
    
    BASE_COL, CROSS_COL = 0x80FFFFFF, 0xd0FFFFFF
    
    SEED, FIXED_SEED = 0, False
    FULLSCREEN, RESIZABLE = False, False
    apply_dof, alt_render = False, False
    
    resized = zeros(1, 'z')
    cube_smooth, cube_facets = DwCube(4), DwCube(2)
    shp_scene = pg_render = pg_dof = pg_tmp = None
    
    def settings():
        if FULLSCREEN: fullScreen(P3D) 
        else: size(this.displayWidth*9/10, this.displayHeight*9/10, P3D)
        noSmooth()
    
    
    def setup():
        frameRate(FPS); cursor(CROSS)
    
        global surf, canv
        surf, canv = this.surface, this.graphics
    
        if RESIZABLE: surf.resizable = True
        surf.setLocation(this.displayWidth - width >> 1, 8)
    
        global peasy
        peasy = PeasyCam(this, -4.083, -6.096, 7, 2000)
        peasy.setRotations(1.085, -.477, 2.91)
    
        global context, dw_filter, dof, param, geombuffer, magnifier
    
        context = DwPixelFlow(this)
        dw_filter = DwFilter.get(context)
        context.print(); context.printGL()
    
        dof = DepthOfField(context)
        param = dof.param
        param.mult_blur = MULT_BLUR
    
        class SceneDisplay(DwSceneDisplay):
            def display(_, canvas): displayScene(canvas)
    
    
        geombuffer = DwScreenSpaceGeometryBuffer(context, SceneDisplay())
    
        mag_h = height/3
        magnifier = DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h)
    
    
    def draw():
        setTitle(); resizeScreen(); displaySceneWrap(pg_render)
        dw_filter.gamma.apply(pg_render, pg_render)
    
        apply_dof and applyDoF()
        renderScene()
    
    
    def keyPressed():
        global apply_dof, alt_render, shp_scene
        k = chr(keyCode) if key != CODED else keyCode
    
        if k == 'P' or k == BACKSPACE: noLoop() if this.looping else loop()
        elif k == 'C' or k == CONTROL: printCam()
        elif k == ' ': apply_dof ^= True
        elif k == SHIFT: alt_render ^= True
        elif k == ENTER or k == RETURN: shp_scene = None
    
    
    def applyDoF():
        geom = geombuffer.pg_geom
        dw_filter.gaussblur.apply(geom, geom, pg_tmp, BLUR_POW)
    
        param.focus_pos[0] = map(mouseX + .5, 0, width, 00, 1)
        param.focus_pos[1] = map(mouseY + .5, 0, height, 1, 0)
        dof.apply(pg_render, pg_dof, geombuffer)
    
        dw_filter.copy.apply(pg_dof, pg_render)
    
    
    def renderScene():
        pg = geombuffer.pg_geom if alt_render else pg_render
    
        magnifier.apply(pg, mouseX, mouseY)
        magnifier.displayTool()
    
        DwUtils.beginScreen2D(canv)
        # peasy.beginHUD()
    
        blendMode(REPLACE); image(pg, 0, 0)
        magnifier.display(pg, 0, height - magnifier.h)
    
        fpx = param.focus_pos[0] * width
        fpy = (1 - param.focus_pos[1]) * height
    
        blendMode(EXCLUSION); strokeCap(PROJECT); stroke(CROSS_COL)
        line(fpx - CROSS_S, fpy, fpx + CROSS_S, fpy)
        line(fpx, fpy - CROSS_S, fpx, fpy + CROSS_S)
        blendMode(BLEND)
    
        # peasy.endHUD()
        DwUtils.endScreen2D(canv)
    
    
    def resizeScreen():
        global pg_render, pg_dof, pg_tmp
        w = width; h = height
    
        perspective(RAD60, float(w)/h, 2, ZFAR)
        peasy.feed()
    
        happened = resized[0] = False
        pg_render = DwUtils.changeTextureSize(this, pg_render, w, h, 8, resized)
        happened |= resized[0]
    
        resized[0] = False
        pg_dof = DwUtils.changeTextureSize(this, pg_dof, w, h, 0, resized)
        happened |= resized[0]
    
        resized[0] = False
        pg_tmp = DwUtils.changeTextureSize(this, pg_tmp, w, h, 0, resized,
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    
        # geombuffer.update(pg_render)
    
        happened |= geombuffer.resize(pg_render.width, pg_render.height)
        geombuffer.pg_geom.beginDraw()
    
        # geombuffer.updateMatrices(pg_render)
        DwUtils.copyMatrices(pg_render, geombuffer.pg_geom)
    
        geombuffer.pg_geom.blendMode(REPLACE)
        geombuffer.pg_geom.clear()
        geombuffer.pg_geom.shader(geombuffer.shader)
        geombuffer.pg_geom.noStroke()
        geombuffer.scene_display.display(geombuffer.pg_geom)
        geombuffer.pg_geom.endDraw()
    
        return happened | resized[0]
    
    
    def displaySceneWrap(canvas):
        DwUtils.copyMatrices(canv, canvas)
        canvas.beginDraw()
        canvas.background(2)
        displayScene(canvas)
        canvas.endDraw()
    
    
    def displayScene(canvas):
        canvas.directionalLight(255, 255, 255, 200, 600, 400)
        canvas.directionalLight(255, 255, 255, -200, -600, -400)
        canvas.ambientLight(64, 64, 64)
    
        if canvas is geombuffer.pg_geom:
            canvas.background(-1)
            canvas.pgl.clearColor(1, 1, 1, ZFAR)
            canvas.pgl.clear(PGL.COLOR_BUFFER_BIT)
    
        global shp_scene
        if not shp_scene: shp_scene = makeShape()
        canvas.shape(shp_scene)
    
    
    def makeShape():
        scene = createShape(GROUP)
        FIXED_SEED and randomSeed(SEED)
    
        with pushStyle():
            colorMode(HSB, 360, 1, 1); noStroke()
    
            for i in BOX_RANGE:
                px = random(XMIN, XMAX); py = random(YMIN, YMAX)
                sx = random(BOX_DIAM, BOX_DIAM); sy = random(BOX_DIAM, BOX_DIAM)
                sz = random(ZMIN, ZMAX)
    
                fill(random(-45, 45), 1, random(.1, 1))
                shp_box = createShape(BOX, sx, sy, sz)
                shp_box.translate(px, py, sz*.5)
                scene.addChild(shp_box)
    
            for i in SPH_RANGE:
                px = random(XMIN, XMAX); py = random(YMIN, YMAX)
                pz = random(ZMIN, ZMAX); rr = random(SPH_MIN_D, SPH_MAX_D)
    
                fill(random(205, 245), 1, random(.1, 1))
                shp_sphere = createShape(PShape.GEOMETRY)
                shp_sphere.scale(rr); shp_sphere.translate(px, py, pz)
                scene.addChild(shp_sphere)
    
                DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, True)\
                if i&1 else\
                DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, False)
    
            fill(BASE_COL)
            scene.addChild(createShape(RECT, BB_COORD, BB_COORD, BB_DIAM, BB_DIAM))
    
        return scene
    
    
    def clearFormatter(f): f.out().setLength(0)
    
    
    def setTitle():
        clearFormatter(formatter)
        surf.title = formatter.format(TITLE, frameRate).toString()
    
    
    def printCam():
        pos = peasy.position; rot = peasy.rotations
        lat = peasy.getLookAt(); dis = peasy.distance
    
        clearFormatter(formatter)
    
        print formatter.\
        format(POSITION, *pos).format(ROTATION, *rot).\
        format(LOOK__AT, *lat).format(DISTANCE, dis)
    
  • edited May 2018

    This statement crashes the sketch: geombuffer.update(pg_render) within resizeScreen(). Even when following exactly what it does, it doesn't seem to render anything.

    This is the exact problem I was facing/mentionning.

    So I'm at loss about it! Sorry.

    I should be the one apologizing for bringing you down in this mess. Once again thank you for all the effort and time you've spent to help me, I'm truly grateful to you.

    For now I'm giving up on this sketch and going to try to find another way to create a DoF effect.

  • edited May 2018

    Just something I've just found out (v1.4.1+): L-)
    If we hit the SHIFT key, we switch for the alt_render PGraphics3D geombuffer.pg_geom.
    It kinda "works". At least it's visible rather than the pitch-black pg_render 1. :-\"

Sign In or Register to comment.