Как читать OpenGL пикселей в отдельном потоке, используя Processing? - PullRequest
1 голос
/ 27 июня 2019

Я пытаюсь визуализировать кадры из эскиза обработки в отдельном потоке.Обработка имеет функцию loadPixels () .Улов с помощью средства визуализации OpenGL (P2D или P3D в обработке.): 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.Это замедление, которое я пытаюсь избежать.

Я выглядел похожими потоками на stackoverflow и других форумах:

Насколько я понимаю из вышесказанного, мне нужно создать отдельный контекст OpenGL в моем потоке рендерера и поделиться текстурой / буфером из потока OpenGL Обработки для моего.На данный момент я не уверен в синтаксисе.

Это может быть случай RTFM, но не могли бы вы указать мне направление с точки зрения чтения пикселей OpenGL Java в отдельном потоке (может быть простой Java,не обязательно с использованием Processing)?

1 Ответ

1 голос
/ 27 июня 2019

Контекст OpenGL является локальным для потока. Контекст должен быть сделан «текущим» в потоке. Разные потоки могут использовать один и тот же контекст, но контекст не может быть текущим в нескольких потоках одновременно.

Вы должны убедиться, что потоки не используют один и тот же контекст в одно и то же время. Конечно, вы можете создавать разные контексты для разных потоков и делиться одним контекстом с другим.
См. МУЛЬТИКОНТЕКСТ ОТКРЫТИЯ

Но обратите внимание, графический процессор уже работает параллельно. Нет смысла использовать 1 GPU в разных потоках. Графический процессор может обрабатывать только инструкции одного потока одновременно. Конечно, каждый этап конвейера рендеринга обрабатывает вершины, фрагменты и т. Д. Параллельно

...