Creating a 1-plane FBO with ofFbo and ofFboSettings

I’m trying to create and initialize a 1-plane (a la GL_RED) FBO to use for GPU based recording and playback of black-and-white video frames.

With some pointers from from @bakercp , I’m using an instance of ofFboSettings to make my own settings:

In my .h:

    ofFboSettings fboSettings;

In my .cpp:

    fboSettings.internalformat = GL_RED;
    fboSettings.width = CAM_W;  // this is a constant that holds my camera pixel width
    fboSettings.height = CAM_H;  // this is a constant that holds my camera pixel height

And then I initialize my FBO with:

myFBO .allocate(fboSettings);

The code compiles and runs but seems that GL_RED is not recognized and it’s defaulting back to GL_RGBA with this error:

[ error ] ofGLUtils: ofGetGLTypeFromInternal(): unknown internal format 6403, returning GL_UNSIGNED_BYTE
[ error ] ofGLUtils: ofGetGLFormatFromInternal(): unknown internal format 6403, returning GL_RGBA

Anyone see what I’m doing wrong?

Hi, try instead any of the followings for fboSettings.internalformat

GL_LUMINANCE8 
GL_LUMINANCE16
GL_LUMINANCE32F_ARB

or if you want teh red channel use any of these

GL_R8
GL_R16
GL_R16I
GL_R16UI
GL_R16F
GL_R32F
GL_R32I
GL_R32UI

Let me know if that works

2 Likes

Yes, that works!
Thanks @roymacdonald

Where in the OF or OpenGL docs should I have been looking to learn this?

1 Like

Great.

I usually read OF’s .h files, as these all have inline documentation and it is easier to find. Most probably in your IDE, if you right clic on an OF function name or OF class you will see something like “go to definition”, which usually takes you to the .h file where that is defined and where the inline documentation is.
You might find more info
https://www.khronos.org/opengl/wiki/Image_Format#Required_formats
https://www.khronos.org/opengl/wiki/Framebuffer_Object

But in the case of your question I just looked inside the two functions that were throwing errors and figured out from there what should work for you

Thanks, that helps.

A related question:
I’m actually finding that GL_R8 is working fo rme but GL_LUMINANCE8. I think this is due to how I’m writing my ofTexture into the 1-plane FBO. I’m drawing the texture into my FBO like this:

        myFBO.begin();
        theTexture.draw(0,0);
        myFBO.end();

…but before I draw, I should probably reduce the texture smartly down to a single luminance plane, right?
or will that happen smartly already just by doing what I’m doing above?

Hi,
Not sure how to deal with such.
Why do you want to put that texture into the FBO?
what is the purpose of all this?
you might want to read the following
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glTexImage2D.xml

there it explains the difference between the gl formats

This video shows what the setup is basically like.

I’m working on a small application that records and plays back loops of video off an external camera. I’m using a vector of FBOs for the recording and playback, as I want everything to happen on the GPU, be passed thru some shaders for processing and drawn. The video is all grayscale, with transparency added in a shader. The code is here.

I’m developing for the NVidia Jetson family so I’m very memory constrained; I’m using a 1-plane FBO in order use less GPU memory for the recordings; by using a 1-plane, i’m able to record 4x the number of frames; since the whole thing is black and white, 1-plane is sufficient.

I see. what is the use of keeping everything in the GPU. That will constrain you a lot. Do you get a big performance penalty from loading from cpu memory to gpu memory ?

read that. it explains what happens when using each color format (GL_R, GL_LUMINANCE, etc), I am not sure if you need to convert from color to luminance trhough a shaders. my best guess it to isolate it and test (ie. have a simple app which reads from you camera and draws into an fbo in different formats and see which one performs best.)

btw, in you code I see that you are passing ofTextures as functions arguments, I think that you should pass as reference instead of as value

void update(ofTexture &thisTexture); 
//or
void update(const ofTexture &thisTexture);

instead of

void update(ofTexture thisTexture);

On the embedded platforms i am working with, keeping everything on the GPU from capture forward assure super snappy performance. I’m quite happy with the fidelity and responsiveness on a Jetson.

I was able to make simple changes to my shader to process everything from the red plane, and put out a grayscale and alpha masked RGBA frame and my gpu memory usage should be down 4x. I have not profiled it properly yet but will do next.

Thanks for all the help Roy, much appreciated.

Ali

I see. I have never used one of those, but seem quite awesome.

From what I was reading in the openGL document I linked before it seems like everything ends up transformed into floating point RGBA. It would definitely be much better to be able to have a single plane FBO.
Just occurs me, as a nasty hack that should work. What if you keep all these RGB fbos and somehow you store 3 video frame into a single fbo, one frame per channel?

I have never used one of those, but seem quite awesome.
I find them awesome. They allow me to put together a visual performance instrument that does it all and has an on/off switch, like a toaster. No keyboard or mouse, no interactions with a “computer” or “OS”; just a thing that does a thing and does it well. Now that I’ve got the memory usage under control, I can move off my Jeston Xavier ($1000+ piece of gear) to a Jetson Nano ($100) and still have sufficient recording/playback memory/performance. Since the Xavier has a 4" thick heat sink (it’s a beast), it was making my instrument big and bulky (but still endearing in an old-school, overhead projector sort of way (see attached picture).

Now it can be slim and fit in a backpack!

Just occurs me, as a nasty hack that should work. What if you keep all these RGB fbos and somehow you store 3 video frame into a single fbo, one frame per channel?

I was initially thinking of that hack as well, but it’s much more complicated to implement.
The single plan FBO really did the trick very nicely. Still need to profile GPU memory usage (any suggestions on how to best do that on linux?) but I’m pretty sure i’m already there; during the setup, I can see that it’s taking significantly less time to initialize my FBO arrays, so it seems to be working…

Many thanks again @roymacdonald .

glad to know that now it is working and I could be helpful.
cheers