In the past I have used the version of glReadPixels(...) that takes a Buffer to fill as input in an attempt to capture image sequences from Processing sketches in real-time without slowing down the interaction. I had also read about the other version of glReadPixels(...) that takes an offset instead of a buffer and is supposed to transfer pixels to a PBO (pixel buffer object) in video memory. It is apparently supposed to return immediately after starting the memory transfer.
Now I'm trying to implement a system to read back pixels using two PBOs which should have very little impact on the running sketch. (The buffer version takes about 10ms for 1280x720 which slows down a sketch that pushes 60fps to 45.) There is a nice article outlining what I am trying to do here under asynchronous read-back: http://www.songho.ca/opengl/gl_pbo.html
I'm using gl.glBufferData(pboIds[0], width*height*4, null, GL.GL_STREAM_READ); to allocate memory for the PBO. This line produces an invalid enumerant error (on GL.GL_STREAM_READ I guess). I've also tried this line with an empty buffer instead of null with the same results. When I try to map the read-back buffer I get this GLExcpetion: "Error: buffer size returned by glGetBufferParameterivARB was zero;"
Here is all the GL stuff that I'm having trouble with now:
void setup() {
...
pboIds = new int[2];
gl.glGenBuffers(2, pboIds, 0);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[0]);
gl.glBufferData(
pboIds[0], width*height*4, null, GL.GL_STREAM_READ);
// gl.glGetError();
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[1]);
gl.glBufferData(
pboIds[1], width*height*4, null, GL.GL_STREAM_READ);
// gl.glGetError();
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, 0);
}
void draw() {
...
int vpboInd = frameCount%2;
int cpboInd = (frameCount+1)%2;
gl.glReadBuffer(GL.GL_FRONT);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[vpboInd]);
gl.glReadPixels(
0,0,width,height,GL.GL_BGRA,GL.GL_UNSIGNED_BYTE,0L);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[cpboInd]);
try {
gl.glMapBuffer(GL.GL_PIXEL_PACK_BUFFER, GL.GL_READ_ONLY);
} catch(Throwable ex) {ex.printStackTrace();}
gl.glUnmapBuffer(GL.GL_PIXEL_PACK_BUFFER);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, 0);
}
Has anyone worked with PBOs, tried this before, or see any problems with this code?
Now I'm trying to implement a system to read back pixels using two PBOs which should have very little impact on the running sketch. (The buffer version takes about 10ms for 1280x720 which slows down a sketch that pushes 60fps to 45.) There is a nice article outlining what I am trying to do here under asynchronous read-back: http://www.songho.ca/opengl/gl_pbo.html
I'm using gl.glBufferData(pboIds[0], width*height*4, null, GL.GL_STREAM_READ); to allocate memory for the PBO. This line produces an invalid enumerant error (on GL.GL_STREAM_READ I guess). I've also tried this line with an empty buffer instead of null with the same results. When I try to map the read-back buffer I get this GLExcpetion: "Error: buffer size returned by glGetBufferParameterivARB was zero;"
Here is all the GL stuff that I'm having trouble with now:
void setup() {
...
pboIds = new int[2];
gl.glGenBuffers(2, pboIds, 0);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[0]);
gl.glBufferData(
pboIds[0], width*height*4, null, GL.GL_STREAM_READ);
// gl.glGetError();
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[1]);
gl.glBufferData(
pboIds[1], width*height*4, null, GL.GL_STREAM_READ);
// gl.glGetError();
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, 0);
}
void draw() {
...
int vpboInd = frameCount%2;
int cpboInd = (frameCount+1)%2;
gl.glReadBuffer(GL.GL_FRONT);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[vpboInd]);
gl.glReadPixels(
0,0,width,height,GL.GL_BGRA,GL.GL_UNSIGNED_BYTE,0L);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, pboIds[cpboInd]);
try {
gl.glMapBuffer(GL.GL_PIXEL_PACK_BUFFER, GL.GL_READ_ONLY);
} catch(Throwable ex) {ex.printStackTrace();}
gl.glUnmapBuffer(GL.GL_PIXEL_PACK_BUFFER);
gl.glBindBuffer(GL.GL_PIXEL_PACK_BUFFER, 0);
}
Has anyone worked with PBOs, tried this before, or see any problems with this code?