如何使用 Processing 在单独的线程中读取 OpenGL 像素?

How to read OpenGL pixels in a separate thread using Processing?

我正在尝试在单独的线程中渲染来自 Processing 草图的帧。 正在处理 loadPixels() function. The catch is with the OpenGL renderer (P2D or P3D in Processing.): PGraphicsOpenGL loadPixels()

这是我的示例草图:

void setup(){
  size(300,300,P2D);
  noFill();
  background(255);
  rectMode(CENTER);
  stroke(0,32);
  smooth(8);
  // instantiate and start rendering thread
  new PNGRenderer(this);
}

void draw(){
  // draw moving shapes
  translate(width * 0.5, height * 0.5);
  rotate(sin(frameCount * 0.075));
  scale(sin(frameCount * 0.01));
  translate(cos(frameCount * 0.01) * width * 0.1,sin(frameCount * 0.01) * height * 0.1);
  rect(0,0,width * .9,height * .9);
}

public class PNGRenderer implements Runnable{

  PApplet parent;
  PImage  frame;
  boolean shouldSave = false;

  int savedFrameCount;

  boolean isRunning = true;

  PNGRenderer(PApplet parent){
    this.parent = parent;
    this.parent.registerMethod("draw",this);

    frame = createImage(parent.width,parent.height,ARGB);
    frame.loadPixels();

    Thread renderThread = new Thread(this);
    renderThread.setName("Renderer-Thread");
    renderThread.start();
  }

  public void draw(){
    // all is well if I sample pixels in the same OpenGL thread
    //parent.loadPixels();
    shouldSave = true;
  } 

  synchronized void sampleAndSavePixels(){
    if(shouldSave){
      // program crashes if I try to save in a separate thread
      parent.loadPixels();
      arrayCopy(parent.pixels,frame.pixels);
      frame.updatePixels();
      frame.save(dataPath("frames/frame_"+nf(savedFrameCount++,4)+".png"));
      println("saved frame",savedFrameCount);
      shouldSave = false;
    }
  }

  public void run(){
    while(isRunning){
      sampleAndSavePixels();
    }
  }

}

据我所知(到目前为止我还不是 OpenGL 向导)读取像素需要在同一个 OpenGL 线程中完成。这是我试图避免的减速。

我确实在 Whosebug 和其他论坛上看过类似的帖子:

据我所知,我需要在我的渲染器线程中创建一个单独的 OpenGL 上下文,并将来自 Processing 的 OpenGL 线程的 texture/buffer 共享给我。我现在不确定语法。

这可能是 RTFM 的情况,但你能否指出 Java OpenGL 在单独线程中读取像素的方向(可以是普通的 Java,不一定使用 Processing )?

OpenGL Context 是 thread-local。必须在线程中创建上下文 "current"。不同的线程可以使用相同的上下文,但是一个上下文不能同时在多个线程中是当前的。

您必须确保线程不会同时使用相同的上下文。当然,您可以为不同的线程创建不同的上下文,并将一个上下文共享给另一个。
参见 OPENGL MULTI-CONTEXT

但请注意,GPU 已经并行运行。在不同线程中使用 1 个 GPU 没有任何好处。 GPU一次只能处理1个线程的指令。当然 Rendering Pipeline 的每个阶段都并行处理顶点、片段等