2

注意:我也在处理论坛上问过这个问题

我有这个示例代码:

PGraphics pg;

void setup() {
  size(400, 500);
  pg = createGraphics(width, height);

  pg.noSmooth();
  pg.beginDraw();
  pg.background(0, 0, 255);
  pg.endDraw();
}

void draw() {

  if (mousePressed) {
    pg.beginDraw();
    pg.stroke(255, 254);
    pg.point(mouseX, mouseY);
    pg.endDraw();
  }

  image(pg, 0, 0, width, height);
}

我希望这段代码在用户按下鼠标的任何地方都显示一个点。相反,我只能看到几个矩形区域中的点:

车窗

如果我删除调用pg.noSmooth()或删除调用中的 alpha 值pg.stroke(),那么它可以正常工作:

工作窗口

如果我用or替换pg.point()呼叫,那么它也可以正常工作。pg.ellipse()pg.rect()

似乎使用 a PGraphicsnoSmooth()函数、point()函数和 alpha 值的组合会导致这种错误行为。我在 Processing 3.3 和 Processing 3.5.2 中尝试过,我看到两者的行为相同。

我错过了一些明显的东西吗?

4

1 回答 1

3

经过一点点挖掘后,JAVA2D渲染器将一个点绘制为对角线line(x, y, x + EPSILON, y + EPSILON);),间距非常 ()。我的猜测是这种特殊配置,缺少锯齿可能意味着这条对角线的两个点都落在同一个像素上,最终不会在右上角区域渲染。我不知道为什么会出现那个区域以及为什么会出现这么短的距离,但这听起来有点像Jakub Valtar 和 Andres Colubri 不得不处理的头痛问题。static final float EPSILON = 0.0001f;

FWIW 这是一个 hacky 解决方法:使用更大的距离,以透明且没有锯齿的方式渲染:

PGraphics pg;

void setup() {
  size(400, 500);
  noSmooth();

  pg = createGraphics(width/20, height/20);
  pg.beginDraw();
  // just for debug purposes: rectangle with edge
  pg.fill(0, 0, 255);
  pg.rect(0,0,pg.width-1,pg.height-1);
  pg.stroke(255,255,255, 128);
  pg.endDraw();

}

void pointNoSmooth(PGraphics pg, float x,float y){
  pg.beginShape();
  pg.vertex(x,y);
  pg.vertex(x + 0.75,y);//any less than 0.75 distance between vertices and there's nothing to render with aliasing
  pg.endShape();
}

void draw() {
  background(255);
  if (mousePressed) {
    pg.beginDraw();
    pointNoSmooth(pg,mouseX,mouseY);
    pg.endDraw();
  }
  // render upscaled
  image(pg, 0, 0, width, height);
  // render small preview in TL corner
  image(pg,0,0);
}

请注意,我已将 PGraphics 分辨率设置为小 20 倍,然后将其放大,以便更容易看到像素在 PGraphics 上的位置。我没有缩放mouseX,mouseY坐标,所以你需要在测试时在左上角的小预览中绘制。这个0.75距离可以解决问题:根据我的测试,任何小于它的东西都会0.7499995再次开始出现故障。

于 2019-01-29T11:36:06.250 回答