PGraphics rendering strangely ? (transparency issue)

I am not sure, is there any tricky procedure I am forgetting here? Using masks seems to result on same results. I am not sure if PGraphics was designed for this, but later I wanted to draw other things inside the plane, not just the plane itself.

PGraphics plane;

void setup() {
  size(300, 300, P3D);
  plane = createGraphics(100, 100, P2D); // also tried P3D, JAVA2D and none
}

void draw() {
  background(200);
  pushMatrix();
  translate(width/2, height/2, -100);
  rotateX( radians(15) );
  rotateY( radians( frameCount ) );
  drawCross();
  drawPlane();
  translate(-20,20,-20);
  drawPlane();
  popMatrix();
}

void drawPlane() {
  plane.beginDraw();
  //plane.clear();
  //plane.background(0,0);
  plane.fill(255);
  plane.beginShape();
  plane.vertex(20, 0);
  plane.vertex(100, 0);
  plane.vertex(100, 100);
  plane.vertex(0, 100);
  plane.endShape();
  plane.endDraw();
  image(plane, -50, -50);
}

void drawCross() {
  stroke(0);
  strokeWeight(1);
  int r = 20;
  line(0, 0, r, 0);
  line(0, 0, 0, r);
  rotateY(HALF_PI);
  line(0, 0, r, 0);
}
Tagged:

Answers

  • You haven't actually told us what the problem is. What exactly does this code do? What exactly do you expect it to do? How exactly are those two things different?

  • Sorry. The plane I am drawing at drawPlane is not a rectangle. One side is a slope. But instead of recognizing this shape, PGraphics is rendering the actual shape It intended to inside a rectangle and filling the area where it should be transparent with the background color. It is visible if rendered over other elements.

    This is processing 3.0.1

    I have seen there are some commits on github regarding PGraphics but I can't compile it.

  • edited October 2016

    Ah, I see what you are talking about now. When your non-rectangle rotates, the back is occluded -- there is a wedge, where the rectangle would be (but isn't), that clips out what is behind it.

    I'm seeing this on Processing 3.2.1 -- so I don't think your issue relates to recent version changes.

    PGraphicsPlane

  • Using PShape should fix this, allows for real non-rectangular shapes.

  • edited October 2016

    I'm seeing this on Processing 3.2.1 -- so I don't think your issue relates to recent version changes.

    Thanks for the feedback. Could it be an OpenGL issue?

    Using PShape should fix this, allows for real non-rectangular shapes.

    thanks for the idea, but I am using PGraphics as a container to draw other things inside of it. Isn't it a PShape inside my PGraphics in between the lines plane.beginShape() and plane.endShape()? If so, PGraphics is failing to be used as a container, right?

  • i worry that the createGraphics(100, 100) is giving you a rectangle. and regardless of what you do to that rectangle, filling it with transparent, it's still a rectangle. (it's filling it with background rather than transparency, by the look of things)

    iirc there is a hint() that you can apply to get it to treat transparent parts better, if slower. hint() is under documented though and i'm not sure what the hint is

    DISABLE_DEPTH_MASK
    DISABLE_DEPTH_TEST
    ENABLE_DEPTH_SORT

    you have a shape on a PGraphics which is different, in some way i'm not sure i can explain, from a shape inside a PShape. (the latter is a collection of polygons, the former is a drawing of polygons on a rectangular image?)

  • there's a createImage() call as well, which lets you specify ARGB as the 3rd argument which might treat transparency better.

    PImage img = createImage(66, 66, ARGB);
    

    tbh i get confused with all this create*() stuff.

  • Thanks for the suggestions Koogs, but for my purpose, I really needed to find a way to use a container and I was avoiding Image, even if I kind of understand Graphics derives from it. In my head, manipulating elements such as shapes, rectangles, etc inside PGraphics is different if I try to do same thing with PImage, right?

    I came to a very ridiculous solution in terms of what? too many lines to do something that supposed to be simple (set a transparency) on a irregular shape inside PGraphics. I think the code is working perfectly but, again, I am pretty sure this is NOT going to be in best practices manual.

    apparently works if camera moves too, but didn't have time to test now. maybe "center" must be updated, and implement the rot() as right now works only on rotations around Y axis.

    Screen Shot 2016-10-18 at 4.48.17 PM

    /*
      PGraphics as containers in 2.5D space
      Bontempos 2016-10-18
    */
    
    PGraphics plane;
    PVector planeCenter = new PVector(-50, -50);
    PVector [] planePoints ;
    PVector center;
    
    void setup() {
      size(300, 300, P3D);
      textureMode(IMAGE);
      planePoints = new PVector[4];
      planePoints[0] = new PVector(20, 0);
      planePoints[1] = new PVector(100, 0);
      planePoints[2] = new PVector(100, 100);
      planePoints[3] = new PVector(0, 100);
      plane = createGraphics(100, 100, P2D);
    }
    
    void draw() {
      background(200);
      center = new PVector (width/2, height/2, -100);
      makePlane();
      image(plane, 0, 0);
      fill(-1);
      text("plane reference", 10, 120);
      pushMatrix();
      translate(center.x, center.y, center.z);
      rotateY( radians( frameCount ) );
      drawCross();  
      popMatrix();
    
      noStroke();
      //plane 1
      beginShape();
      texture(plane);
      for (int i = 0; i < 4; i++) {
        PVector pointAbsPos = getAbsPos(planePoints[i]);
        PVector pointCameraSpace = getProjectedCoord ( pointAbsPos );
        vertex(pointCameraSpace.x, pointCameraSpace.y, planePoints[i].x, planePoints[i].y);
      }
      endShape();
    
      //plane2
      center = new PVector (width/2 - 20, height/2 + 20, -120);
      beginShape();
      texture(plane);
      for (int i = 0; i < 4; i++) {
        PVector pointAbsPos = getAbsPos(planePoints[i]);
        PVector pointCameraSpace = getProjectedCoord ( pointAbsPos );
        vertex(pointCameraSpace.x, pointCameraSpace.y, planePoints[i].x, planePoints[i].y);
      }
      endShape();
    }
    
    void makePlane() {
      PGraphics mask = createGraphics(100, 100, P2D);
      mask.beginDraw();
      mask.clear();
      mask.fill(255);
      mask.beginShape();
      for (int i = 0; i < 4; i++) {
        mask.vertex (planePoints[i].x, planePoints[i].y);
      }
      mask.endShape();
      mask.endDraw();
    
      PGraphics mouse = createGraphics(100, 100,P2D);
      mouse.beginDraw();  
      mouse.clear();
      //base.background(-1);
      mouse.fill(#ff0000);
      mouse.rectMode(CENTER);
      mouse.rect(mouseX, mouseY, 30, 30);
      mouse.endDraw();
    
      plane.beginDraw();
      plane.clear();
      plane.strokeWeight(3);
      plane.beginShape(QUAD);
      for (int i = 0; i < 4; i++) {
       plane.vertex (planePoints[i].x, planePoints[i].y);
      }
      plane.endShape();
      plane.image(mouse, 0, 0);
      plane.mask(mask);
      plane.endDraw();
    }
    
    void drawCross() {
      stroke(0);
      strokeWeight(1);
      int r = 20;
      line(0, 0, r, 0);
      line(0, 0, 0, r);
      rotateY(HALF_PI);
      line(0, 0, r, 0);
    }
    
    PVector getAbsPos(PVector point) {
      PVector abspoint = point.copy();
      abspoint.add(planeCenter);
      return rot(abspoint, frameCount ).add(center);
    }
    
    PVector rot(PVector v1, float angle) {
      float a = radians(angle + 90);
      PVector result = new PVector();
      PVector [] ry = {
        new PVector(cos(a), 0, sin(a)), 
        new PVector(0, 1, 0), 
        new PVector(-sin(a), 0, cos(a))
      };
      result.x = v1.dot(ry[0]);
      result.y = v1.dot(ry[1]);
      result.z = v1.dot(ry[2]);
      return result;
    }
    PVector getProjectedCoord(PVector point3D) {
      PMatrix3D mat = getMatrixLocalToWindow(); 
      float[] in = {point3D.x, point3D.y, point3D.z, 1.0f};
      float[] out = new float[4];
      mat.mult(in, out);  
      return new PVector( out[0]/out[3], out[1]/out[3] );
    }
    
    PMatrix3D getMatrixLocalToWindow() {
      PMatrix3D projection = ((PGraphics3D)g).projection; 
      PMatrix3D modelview = ((PGraphics3D)g).modelview;   
      PMatrix3D viewport = new PMatrix3D();
      viewport.m00 = viewport.m03 = width/2;
      viewport.m11 = -height/2;
      viewport.m13 =  height/2;
      viewport.apply(projection);
      viewport.apply(modelview);
      return viewport;
    }
    
Sign In or Register to comment.