openframeworks / openframeworks/openFrameworks
ofFbo: FrameBuffer captures ofEasyCam incorrectly
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 10.4k
- Forks
- 2.6k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 9
Description
I wrote a post about this issue on the forum but didn't receive any feedback from other users that would suggest this is a common issue or something that I've coded incorrectly.
I'm using a FrameBufferObject to capture some graphics drawn by openframeworks and an ofEasyCam and then piping them into an image in ImGui. In the process, I've discovered an interesting feature.
I have two rectangles: drawArea (green), which represents the area the frame buffer captures, and camArea (blue), which represents the area the easyCam draws to and uses as its viewport. The image below shows how this looks drawn normally to the screen (no buffers). The blue box bounds the camera output, as one would expect.

Once I wrap those drawing routines in buffer.begin() and buffer.end(), things get a little weird. I have the buffer draw itself a little ways away from the top-left corner. We see that the green and blue rectangles still have the same relative positions, but the camera view is no longer contained within the blue box (see below). More specifically, the x-coordinates of the blue box still bound the camera view, but the y-coordinates do not.

To recreate this demo and test it yourself, create a blank project with no addons and add the following objects to ofApp.h:
ofEasyCam cam;
ofFbo buffer;
GLuint bufferID;
ofFbo::Settings settings;
In ofApp.cpp, setup():
cam.setDistance(50);
cam.setNearClip(1.f);
draw():
ofRectangle drawArea(0,0,405,405);
ofRectangle camArea(20,20,380,380);
settings.width = drawArea.width;
settings.height = drawArea.height;
settings.textureTarget = GL_TEXTURE_2D;
settings.internalformat = GL_RGBA;
buffer.allocate(settings);
bufferID = buffer.getTexture().texData.textureID;
// Comment / Uncomment lines below
buffer.begin();
ofClear(255, 255, 255, 0);
//-----------------------
cam.begin(camArea);
ofSpherePrimitive s1, s2, s3, s4;
s1.setPosition(0,0,0);
s1.setRadius(2);
s2 = s3 = s4 = s1;
s2.setPosition(6,0,0);
s3.setPosition(0,6,0);
s4.setPosition(0,0,6);
ofSetColor(ofColor::red);
s1.draw();
s2.draw();
s3.draw();
s4.draw();
cam.end();
ofSetColor(ofColor::green);
ofFill();
ofDrawRectangle(ofRectangle(drawArea.x,drawArea.y,15,15));
ofDrawRectangle(ofRectangle(drawArea.x+drawArea.width-15, drawArea.y+drawArea.height-15, 15, 15));
ofSetColor(ofColor::blue);
ofDrawRectangle(ofRectangle(camArea.x+camArea.width-15,camArea.y,15,15));
ofDrawRectangle(ofRectangle(camArea.x, camArea.y+camArea.height-15, 15, 15));
ofNoFill();
ofSetColor(ofColor::green);
ofSetLineWidth(2);
ofDrawRectangle(drawArea);
ofSetColor(ofColor::blue);
ofDrawRectangle(camArea);
// Comment / Uncomment lines below
buffer.end();
buffer.draw(100, 100);
You get the same behavior if you make the camArea rectangle shorter than the frame buffer area:
ofRectangle drawArea(0,0,405,405);
ofRectangle camArea(0,0,405,380);

Here the shift is again in the opposite direction as the translation of camArea; seems to be an inverse relationship on the y-translation somewhere...
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Recreate the issue in a blank project using the ofApp.h members and the setup() and draw() code shown. Start by comparing rendering with and without buffer.begin()/buffer.end(), then inspect how ofFbo and ofEasyCam handle their viewports and coordinate origins. Done means the camera view remains within camArea when rendered into the framebuffer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100