OpenGL嵌套模具

cla*_*l3r 7 java opengl processing

我想要嵌套的模具在OpenGL中工作。从现在起,我称它们为面具。

因此,模板缓冲区被清除为全0。我做我的第一个面具,灰色区域。

在此处输入图片说明

现在必须在模板缓冲区中全为1,并且不允许在该蒙版之外进行正常绘制。

现在,我创建第二个遮罩,该遮罩是第一个遮罩的子代:如果该区域在上一个遮罩的区域内,则只会更新模板缓冲区:

在此处输入图片说明

如果我们要制作另一个子蒙版,则相同,仅当它在父蒙版中时才增加。

在此处输入图片说明

现在,如果我们要结束最后一个蒙版(绿色蒙版),则可以将值减小到等于蒙版深度的位置。

好的,那是个主意,但是我一直坚持让它工作数周(不是全职...)。

屏蔽不起作用,或者它无法按预期方式工作。在这里,我提供了对我来说最有意义的代码。

我使用处理,可以在这里https://processing.org/下载(下载并运行,就这么简单)。

PGL pgl;


Rect current_rect;


void setup() {
  size(600, 600, P3D);
  noStroke();

  // will have a depth of 0, equal to the stencil buffer after a clear
  current_rect = make_rect(null, 0, 0, width, height);
}

class Rect {
  float x;
  float y;
  float w;
  float h;
  ArrayList<Rect> children = new ArrayList<Rect>();
  Rect parent;
  int mask_depth;
}

Rect make_rect(Rect parent, float x, float y, float w, float h) {
  Rect r = new Rect();
  r.x = x;
  r.y = y;
  r.w = w;
  r.h = h;
  if (parent != null) {
    r.parent = parent;
    r.mask_depth = parent.mask_depth + 1;
    parent.children.add(r);
  }
  return r;
}



void draw() {

  if (frameCount == 2) noLoop();

  println();

  pgl = beginPGL();

  pgl.enable(PGL.STENCIL_TEST);
  pgl.clear(PGL.STENCIL_BUFFER_BIT);

  background(150, 80, 70);

  begin_mask(100, 100, 400, 400);

  fill(150);
  rect(100, 100, 400, 400);
  // SHOULD NOT FALL OUTSIDE OF THE MASK!
  debug_text(" A ");

  // disabled for now cause the above begin_mask
  // goes already wrong
  if (false) {
    begin_mask(50, 150, 500, 100); // B
    fill(100);
    rect(50, 150, 500, 100);
    debug_text(" B ");

    if (true) {
      begin_mask(200, 50, 100, 500); // C
      fill(50);
      rect(200, 50, 100, 500);
      debug_text(" C ");
      end_mask(); // C
    }


    end_mask(); // B

    // why is the one from above (C) on this one?
    // disable this one to see what I mean
    if (true) {
      begin_mask(50, 350, 500, 100); // D
      fill(75);
      rect(50, 350, 500, 100);
      fill(255);
      debug_text(" D ");
      end_mask(); // D
    }
  }

  end_mask(); // A


  flush();

  endPGL();
}




void begin_mask(float x, float y, float w, float h) {
  current_rect = make_rect(current_rect, x, y, w, h);

  flush();
  pgl.colorMask(false, false, false, false);
  pgl.depthMask(false);
  pgl.stencilOp(PGL.KEEP, PGL.KEEP, PGL.INCR);
  println("increment stencil when stencil is equal to: "+current_rect.parent.mask_depth);
  pgl.stencilFunc(PGL.EQUAL, current_rect.parent.mask_depth, 0xFF);

  // write to stencil buffer
  noStroke();
  fill(0);
  rect(x, y, w, h);
  flush();

  enable_normal_draw_mode();
}



void enable_normal_draw_mode() {
  pgl.stencilMask(0x00);
  println("normal write when stencil depth is: "+(current_rect.mask_depth));
  pgl.stencilFunc(PGL.GEQUAL, current_rect.mask_depth, 0xff);
  pgl.stencilOp(PGL.KEEP, PGL.KEEP, PGL.KEEP);
  pgl.colorMask(true, true, true, true);
  pgl.depthMask(true);
  flush();

  println("enable_normal_draw_mode "+current_rect.mask_depth);
}



void end_mask() {
  // decrement stencil mask as if we never existed
  pgl.stencilMask(0xff);
  pgl.stencilFunc(PGL.GEQUAL, current_rect.mask_depth, 0xff);
  pgl.stencilOp(PGL.KEEP, PGL.KEEP, PGL.DECR);
  pgl.colorMask(false, false, false, false);
  pgl.depthMask(false);
  noStroke();
  fill(0);
  rect(current_rect.x, current_rect.y, current_rect.w, current_rect.h);
  flush();

  current_rect = current_rect.parent;

  enable_normal_draw_mode();
}






void debug_text(String s) {
  fill(255);
  text(xxx(s), 0, 0);
}

String xxx(String to_repeat) {
  String result = "";
  String line = "";
  for (int x = 0; x < 50; x++) {
    line += to_repeat;
  }
  for (int y = 0; y < 50; y++) {
    result += line + "\n";
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)