【发布时间】:2019-06-27 11:32:48
【问题描述】:
我正在尝试在单独的线程中从处理草图中渲染帧。
处理有一个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 和其他论坛上看过类似的帖子:
- How to call glReadPixels on different thread?
- How can i run GLES20.glReadPixels on separate thread in android?
- calling glReadPixels from another thread
据我了解,我需要在我的渲染器线程中创建一个单独的 OpenGL 上下文,并将 Processing 的 OpenGL 线程中的纹理/缓冲区共享给我。我目前不确定语法。
这可能是 RTFM 的情况,但请您指出 Java OpenGL 在单独线程中读取像素的方向(可以是纯 Java,不一定使用处理)?
【问题讨论】:
-
OpenGL Context 是线程本地的。上下文必须在线程中设置为“当前”。问题是如何在处理中做到这一点。
-
@Rabbid76 如果我错了请纠正我,我理解的方式是:我会在我的线程中创建单独的 OpenGL 上下文,并且对于每一帧首先暂停处理的动画线程,然后使渲染器线程的OpenGL 上下文当前,以某种方式将缓冲区从处理上下文复制到渲染器上下文中,恢复动画线程,而渲染器线程从渲染器线程中复制的缓冲区“下载”/读取像素并保存帧?
-
您应该在 JogAmp 官方论坛上提出这个问题。你想达到什么目的?
-
@gouessej 我正在尝试保存使用处理生成的动画的 png 序列。我已经分析了我的代码,并且 1080p 帧速率从 ~25 下降到 ~15fps。这还不错,但是在分析 CPU 使用情况后,我看到
loadPixels()需要花费好几毫秒才能完成。我想将该操作移到一个单独的线程中,但是看起来我需要跳过一些 GL 箍 :) Gernot 的建议听起来不错。你有我应该尝试的想法吗? :D -
使用 com.jogamp.opengl.util.GLReadBufferUtil:jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/…
标签: java multithreading opengl processing jogl