Drawing to different size FBO

1.9k views Asked by At

I'm having an issue while using FBO.

My window size is 1200x300.

When I create a FBO that's 1200x300, everything is fine.

However, when I create FBO with 2400x600 size (effectively, two times bigger on both axes) and try to render the exact same primitives, I get used only one quarter of the FBO's actual area.

FBO same size as window:

Same size

FBO twice bigger (triangle clipping can be noticed):

Different size

I render these two triangles into FBO, then render a fullscreen quad with a FBO's texture over it. I clear FBO with this pine green color, so I know for sure that all that empty space on the second picture actually comes from the FBO.

// init() of the program
albedo = new RenderTarget(2400, 600, 24 /*depth*/);  // in first case, params are 1200, 300, 24

// draw()
RenderTarget::set(albedo);   // render to fbo
RenderTarget::clearColor(0.0f, 0.3f, 0.3f, 1.0f);
RenderTarget::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// render triangles ...
glDrawArrays(GL_TRIANGLES, 0, 6);

// now it's time to render a fullscreen quad
RenderTarget::set();   // render to back-buffer
RenderTarget::clearColor(0.3f, 0.0f, 0.0f, 1.0f);
RenderTarget::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, albedo->texture());
glUniform1i(albedoUnifLoc, 0);
RenderTarget::drawFSQ();   // draw fullscreen quad

I have no cameras of any kind, I don't use glViewport anywhere, I always send coordiantes of the primitives to be drawn in the unit-square space (both x and y coord are in [-1,1] range).

Question is, what am I doing wrong and how do I fix it?

Aside question is, is glViewport in any kind related to currently bound framebuffer? As far as I could understand, that function is just used to set the rectangle area on the window in which the drawing will occur.

Any suggestion would be greatly appreciated. I tried searching for the problem online, the only similar thing was in this SO question, but it hasn't helped me.

1

There are 1 answers

1
Reto Koradi On BEST ANSWER

You need to call glViewport() with the size of your render target. The only time you can get away without calling it is when you render to the window, and the window is never resized. That's because the default viewport matches the initial window size. From the spec:

In the initial state, w and h are set to the width and height, respectively, of the window into which the GL is to do its rendering.

If you want to render to an FBO with a size different from your window, you have to call glViewport() with the size of the FBO. And when you go back to rendering to the window, you need to call glViewport() with the window size again.

The viewport dimensions are not per framebuffer state. I always thought that would have made sense, but it is not defined that way. So whenever you call glViewport(), you are changing global (i.e. per context) state, independent of the currently bound framebuffer.