Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do you have to call glViewport every time you bind a frame buffer with a different resolution?

I have a program with about 3 framebuffers of varying sizes. I initialise them at the start, give them the appropriate render target and change the viewport size for each one.

I originally thought that you only had to call glViewport only when you initialise the framebuffer, however this creates problems in my program so I assume that's wrong? Because they all differ in resolution, right now when I render in each frame I bind the first framebuffer, change the viewport size to fit that framebuffer, bind the second framebuffer, change the viewport size to fit the resolution of the second framebuffer, bind the third framebuffer, change the viewport size to fit it, then bind the window frame buffer and change the viewport size to the resolution of the window.

Is this necessary, or is something else in the program to blame? This is done every frame, so I'm worried it would have a slight unnecessary overhead if I don't have to do it.

like image 999
Goldboa Avatar asked Nov 15 '15 09:11

Goldboa


People also ask

When should I use Renderbuffer?

Renderbuffer Objects are OpenGL Objects that contain images. They are created and used specifically with Framebuffer Objects. They are optimized for use as render targets, while Textures may not be, and are the logical choice when you do not need to sample (i.e. in a post-pass shader) from the produced image.

What is frame buffer how it is different from the display buffer?

Likewise, framebuffers differ from the technology used in early text mode displays, where a buffer holds codes for characters, not individual pixels. The video display device performs the same raster scan as with a framebuffer, but generates the pixels of each character in the buffer as it directs the beam.

What is glViewport?

The glViewport function specifies the affine transformation of x and y from normalized device coordinates to window coordinates.

What is a framebuffer attachment?

Framebuffers represent a collection of memory attachments that are used by a render pass instance. Examples of these memory attachments include the color image buffers and depth buffer that we created in previous samples. A framebuffer provides the attachments that a render pass needs while rendering.


2 Answers

You always need to call glViewport() before starting to draw to a framebuffer with a different size. This is necessary because the viewport is not part of the framebuffer state.

If you look at for example the OpenGL 3.3 spec, section 6.2, titled "State Tables", starting on page 278, contains tables with the entire state, showing the scope of each piece of state:

  • Table 6.23 on page 299 lists "state per framebuffer object". The only state listed are the draw buffers and the read buffer. If the viewport were part of the framebuffer state, it would be listed here.
  • The viewport is listed in table 6.8 "transformation state". This is global state, and not associated with any object.

OpenGL 4.1 introduces multiple viewports. But they are still part of the global transformation state.

If you wonder why it is like this, the only real answer is that it was defined this way. Looking at the graphics pipeline, it does make sense. While the glViewport() call makes it look like you're specifying a rectangle within the framebuffer that you want to render to, the call does in fact define a transformation that is applied as part of the fixed function block between vertex shader (or geometry shader, if you have one) and fragment shader. The viewport settings determine how NDC (Normalized Device Coordinates) are mapped to Window Coordinates.

The framebuffer state, on the other hand, determines how the fragment shader output is written to the framebuffer. So it controls an entirely different part of the pipeline.

From the way viewports are normally used by applications, I think it would have made more sense to make the viewport part of the framebuffer state. But OpenGL is really an API intended as an abstraction of the graphics hardware, and from that point of view, the viewport is independent of the framebuffer state.

like image 167
Reto Koradi Avatar answered Sep 21 '22 10:09

Reto Koradi


I originally thought that you only had to call glViewPort only when you initialise the framebuffer, however this creates problems in my program so I assume that's wrong?

Yes it is a wrong assumption (probably fed by countless of bad tutorials which misplace glViewport).

glViewport always belongs into the drawing code. You always call glViewport with the right parameters just before you're about to draw something into a framebuffer. The parameters set by glViewport are used in the transformation pipeline, so you should think of glViewport of a command similar to glTransform (in the fixed function pipeline) or glUniform.

like image 37
datenwolf Avatar answered Sep 18 '22 10:09

datenwolf