Text offset in P3d

edited February 25 in JavaScript Mode

Hello,

I'm porting my sketch over with processing.js

I'm trying to create a slider with text which works great in 2d mode, but when I enable P3D the text begins to offset from the slider depending on where I position it.

Here's how it looks like when it's positioned in the lower left corner:

img1

And how it looks like in the upper right corner:

img2

I think this is caused by the camera's perspective, though I don't know why it wouldn't offset both the text and slider equally. Is there any way to fix this?

Answers

  • text("your text",x,y,z);

    Kf

  • you could use a HUD section in your code - Head-up display

    https://en.wikipedia.org/wiki/Head-up_display

    Example:

    float angle; 
    
    void setup() {
      size(800, 800, P3D);
    }
    
    void draw() {
      background(0);
      lights();
    
      // reset some stuff that was set differently by the HUD
      // maybe you need to set the camera
      hint(ENABLE_DEPTH_TEST);
      textSize(32);
    
    
      // main program
      translate(width/2, height/2 + 111);
      rotateY(angle);
      fill(255);
      box(300);
      angle+=.01;
    
      // display a text in the corner 
      fill(255, 2, 8);
      textSize(22);
      showTextInHUD("Test ");
      fill(255);
    } 
    
    // HUD funcs  ----------------------
    // Head-up-Display 
    // see http://de.wikipedia.org/wiki/Head-up-Display
    
    void showTextInHUD(String str1) {
      // A small 2D HUD for text in the
      // upper left corner. 
      // This func may only be called a the very end of draw() afaik.
      camera();
      hint(DISABLE_DEPTH_TEST);
      noLights();
      textMode(MODEL);
      if (str1!=null)
        text(str1, 22, 23);
      hint(ENABLE_DEPTH_TEST);
    } // func 
    
    void showTextInHUD(String str1, float x, float y) {
      // A small 2D HUD for text at
      // free pos.
      // This func may only be called a the very end of draw() afaik.
      camera();
      hint(DISABLE_DEPTH_TEST);
      noLights();
      textMode(MODEL);
      if (str1!=null)
        text(str1, x, y);
      hint(ENABLE_DEPTH_TEST);
    } // func 
    

    when you're using peasyCam which is very useful, there is an in-build cam.beginHUD(); and cam.endHUD();

  • @kfrajer If you're referring to use the z value both rect and text are in the same z planar. This is why I think it's the camera's perspective creating the offset.

    @Chrisir Thanks for the effort though it still suffers from the same issue. The text doesn't align with the rect if you position it differently:

    float angle; 
    
    void setup() {
      size(1200, 800, P3D);
    }
    
    void draw() {
      background(0);
      lights();
    
      // reset some stuff that was set differently by the HUD
      // maybe you need to set the camera
      hint(ENABLE_DEPTH_TEST);
      textSize(32);
    
    
      // main program
      //translate(width/2, height/2 + 111);
      //rotateY(angle);
      fill(255);
      angle+=.01;
    
        float x = 100;
        float y = 100;
    
        // Uncomment these and notice the text isn't aligned with the rect anymore.
        //float x = 1000;
        //float y = 700;
    
        rect(x, y, 200, 30);
    
      fill(255, 2, 8);
      textSize(22);
    
      showTextInHUD("Test ", x, y-20);
      fill(255);
    } 
    
    // HUD funcs  ----------------------
    // Head-up-Display 
    // see <a href="http://de.wikipedia.org/wiki/Head-up-Display" target="_blank" rel="nofollow">http://de.wikipedia.org/wiki/Head-up-Display</a>;
    
    void showTextInHUD(String str1, float x, float y) {
      // A small 2D HUD for text at
      // free pos.
      // This func may only be called a the very end of draw() afaik.
      camera();
      hint(DISABLE_DEPTH_TEST);
      noLights();
      textMode(MODEL);
      if (str1!=null)
        text(str1, x, y);
      hint(ENABLE_DEPTH_TEST);
    } // func 
    
  • that sounds bad

    afaik you could write box and text on a pgraphics and display this in a HUD section of your code.

  • I think it aligns ok though

    float angle; 
    
    void setup() {
      size(1200, 800, P3D);
    }
    
    void draw() {
      background(0);
    
      // 3D section 
      // reset some stuff that was set differently by the HUD
      // maybe you need to set the camera
      hint(ENABLE_DEPTH_TEST);
      lights();
      textSize(32);
      fill(255);
    
      // main program
      pushMatrix(); 
      translate(width/2, height/2 + 111);
      rotateY(angle);
      box(33);
      fill(255);
      angle+=.01;
      popMatrix();
    
      // HUD section 
      float x = 100;
      float y = 100;
      // Uncomment these and notice the text isn't aligned with the rect anymore.
      x = 1000;
      y = 700;
      showTextInHUD("Test ", x, y-20);
    } 
    
    //----------------------------------------------------------------------
    
    // HUD funcs  ----------------------
    // Head-up-Display 
    // see http : // de.wikipedia.org/wiki/Head-up-Display
    
    void showTextInHUD(String str1, float x, float y) {
      // A small 2D HUD for text at
      // free pos.
      // This func may only be called a the very end of draw() afaik.
      camera();
      hint(DISABLE_DEPTH_TEST);
      noLights();
      textMode(MODEL);
    
      field(str1, x, y); 
    
      hint(ENABLE_DEPTH_TEST);
    } // func 
    
    void field(String str1, float x, float y) {
    
      fill(255, 2, 8);
      textSize(22);
    
      if (str1!=null) {
        text(str1, x, y, 0);
      }
      fill(255);
      rect(x, y+4, 200, 30);
    
      noFill();  
      stroke(255);
      rect(x, y-44, 200, 60);
    }
    //
    
  • I think this is caused by the camera's perspective, though I don't know why it wouldn't offset both the text and slider equally. Is there any way to fix this?

    You need to provide a MCVE as what I am doing here is guess work. I have encountered this problem before and my solution was to make sure the item was always in front by using the z value. However, I am not sure if you are changing the camera perspective, and how you are laying out your elements. And then on top of this, you are working in p.js so this make it a bit more challenging. If you provide and MCVE, one can see your approach, duplicate your problem and provide much better feedback.

    Kf

  • edited March 25

    Another approach: you can also create a P2D sketch and embed a P3D PGraphics in it. This gives you a flat plane for drawing UI elements, with no strange 3D effects (perspective shifts, z-fighting etc). 3D content goes in the 3D layer.

  • edited February 26

    Basic example:

    void setup() {
        // Remove P3D and it will look properly aligned.
      size(1500, 1000, P3D);
    
        background(0);
    
        // Create at the top-left corner.
        // All looks good here.
        float pos1 = new PVector(50, 100);
    
        fill(255, 0, 0);
        noStroke();
        rect(pos1.x, pos1.y, 200, 30);
    
        fill(255);
        text("Hello world!", pos1.x, pos1.y-10);
    
    
        // Create at the bottom-right corner.
        // The text looks mis-aligned relative to the rect.
        float pos2 = new PVector(width-300, height-100);
    
        fill(255, 0, 0);
        noStroke();
        rect(pos2.x, pos2.y, 200, 30);
    
        fill(255);
        text("Hello world!", pos2.x, pos2.y-10);
    }
    

    @kfrajer I'm including a bare bones example. It's creating 2 groups with a rect and label, one at the top-left and another at the bottom-right. The top-left looks ok since I hard-coded the values to it. If I use the same offsets but position it in the bottom-right the text isn't aligned anymore. If you toggle off P3D they look ok. It only looks off in a P3D/WEBGL sketch. I know I'm not explicitly setting the z-axis but it's the same result even if I do. My guess would be to temporary kill perspective to make it an orthographic view but I can't get that to work.

    Top-left:

    img1

    Bottom-right:

    img2

    @Chrisir I tried out your new example but it's still not aligned. Which is weird since I'm sure it's all good in your end. I'm running on centOS right now but I'll try it again on my Windows machine at home and see if it's the same result. Update: same on Windows.

    code_test

    @jeremydouglass That sounds like it would work though I'm trying to create a generic slider that I can sort of "plug and play" in any sketch, so I don't want any extra "rules" or overhead outside of my Slider class. Good suggestion though!

  • Guess there is no solution. Thanks anyways all.

  • edited March 8

    @GreenCell I ran your sample code above and I am not seeing any issues with alignment.

    Screenshot (3123)

    I'm running on Win10 btw. I did notice lots of flickering but I solved it by introducing an empty draw() function (unrelated to your problem).

    Do you see this problem in JAVA2D or only in P3D? If you try Jeremy's approach, at least you can confirm if the problem is dues to the 3D environment (when using P2D).

    Kf

    PGraphics gr, gr3D;
    boolean update=false;
    float rx=0.25;
    
    void setup() {
      // Remove P3D and it will look properly aligned.
      size(1200, 1000, P2D);
      generateElements();
    
      background(0);
      image(gr3D, width/4, height/2);
      image(gr, 0, 0);
    }
    
    void draw() {
    
      if (!update)
        return;
    
      rx=map(mouseX, 0, width, -PI, PI);
      generateElements();
    
      background(0);
      image(gr3D, width/4, height/2);
      image(gr, 0, 0);
    }
    
    void mouseClicked() {
      update=!update;
    }
    
    void generateElements() {
      gr=createGraphics(width, height, P2D);
      gr.beginDraw();
      //gr.background(0);
    
      // Create at the top-left corner.
      // All looks good here.
      PVector pos1 = new PVector(50, 100);
    
      gr.fill(255, 0, 0);
      gr.noStroke();
      gr.rect(pos1.x, pos1.y, 200, 30);
    
      gr.fill(255);
      gr.text("Hello world!", pos1.x, pos1.y-10);
    
    
      // Create at the bottom-right corner.
      // The text looks mis-aligned relative to the rect.
      PVector pos2 = new PVector(width-300, height-100);
    
      gr.fill(255, 0, 0);
      gr.noStroke();
      gr.rect(pos2.x, pos2.y, 200, 30);
    
      gr.fill(255);
      gr.text("Hello world!", pos2.x, pos2.y-10);
      gr.endDraw();
    
    
    
      gr3D=createGraphics(int(width*3/5.0), int(height*9/20.0), P3D);
      gr3D.beginDraw();
      gr3D.background(88);
      gr3D.translate(gr3D.width/2, gr3D.height/2, 0);
      gr3D.rotateZ(0.5);
      gr3D.rotateY(rx-QUARTER_PI);
      gr3D.rotateX(rx);
      gr3D.fill(250, 150, 20);
      gr3D.box(gr3D.width/10);
      gr3D.endDraw();
    }
    

    Keyword: kf_keyword P2D_P3D P3D_P2D p3dp2d p2dp3d pgraphics

Sign In or Register to comment.