ofFBO in iOS - readToPixels issue

I have an issue with readToPixels() on iOS that works as expected when compiled for OSX. Hoping someone can point me in the right direction.

I initialize an FBO:

  
  
    ofFbo::Settings settings;  
    settings.width = 1024;  
    settings.height = 1024;  
    settings.internalformat = GL_RGB;  
    settings.numSamples = 0;  
    settings.useDepth = false;  
    settings.useStencil = false;  
    screenFBO.allocate(settings);  
  

then draw into the FBO and attempt to retrieve the pixels:

  
  
    ofPixels pixels;  
    screenFBO.readToPixels(pixels);  
  

This gives me the ofPixels I’m expecting in OSX, in iOS the pixels aren’t populated. I can draw the FBO and see it on screen, I just can’t get the pixels out of the GL texture in iOS.

The issue is in this portion of readToPixels() from ofFbo.cpp, around line 607:

  
  
void ofFbo::readToPixels(ofPixels & pixels, int attachmentPoint){  
#ifndef TARGET_OPENGLES  
	getTextureReference(attachmentPoint).readToPixels(pixels);  
#else  
	bind();  
	int format,type;  
	ofGetGlFormatAndType(settings.internalformat,format,type);  
	glReadPixels(0,0,settings.width, settings.height, format, GL_UNSIGNED_BYTE, pixels.getPixels());  
	unbind();  
#endif  
}  
  

Does anyone know of a way to modify above, or a different means of getting pixel values out of a FBO in iOS?

Thanks in advance,
Steve

hi steve,
did you have any luck in solving this issue?

best,
rainer.

this-document states that type

Must be either GL_RGBA or the value of GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES.

As soon as I set my FBO to GL_RGBA

  
  
settings.internalformat = GL_RGBA;  
  

the program crashes with an EXEC_BAD_ACCESS (after calling readToPixels; stops at glReadPixels).

could that be related to the core problem?

Hi Rainer,

I haven’t solved this problem, and instead came up with a less than ideal idea solution for my needs. If anyone has figured this out, please let me know…

Thanks,
Steve

Running into this same issue now. No fix yet that I’ve found :frowning:

I just ran into this problem myself, and although it’s a pretty old thread OP’s code will still result in an access violation with the latest build of oF so I thought that I’d point out how to fix this.

Unlike the implementation of ofFbo::readToPixels for regular OpenGL, the one for ES does not allocate memory for the ofPixel object internally, so you have to make sure that you do that yourself before calling readToPixels.

Worth noting is that pulling something like a million RGBA pixels from video memory in this way on an iPhone 4 is terribly slow compared to doing it on a Mac/PC with even very modest hardware, so unless you don’t mind it taking a bit (haven’t measured it but would estimate it to almost half a second for that many on the iPhone 4) I would suggest looking for another solution, or grabbing a smaller number of pixels if possible, by binding the FBO and calling glReadPixels.

Hi, just ran into this issue myself on iOS. Eventually got it to work like so (a bit of a hack, and not fast, but works):

ofFbo sourceFbo; // we want to copy the texture from this fbo texture
ofTexture targetTex; // we want to copy the fbo data into this texture
ofPixels p; // a pixel object to transfer the data

/*
Draw something into the Fbo here …
*/

// allocate empty pixels of the right type (OF does not do this for us like in OSX)
p.allocate(sourceFbo.getTextureReference().getWidth(),sourceFbo.getTextureReference().getHeight(), OF_PIXELS_RGBA);
// Prepare our target texture with these pixels (although they are still empty, they are of the proper size and type)
targetTex.allocate§;
// Copy the fbo data into our pixels.
sourceFbo.readToPixels§;
// paste the pixels into the texture …
targetTex.loadData§;