You always need to call glViewport() before you start drawing into a framebuffer with a different size. This is necessary because the viewport is not part of the framebuffer state.
If you look, for example, the OpenGL 3.3 specification, section 6.2, called “State Tables”, starting on page 278, contains tables with the entire state, showing the area of each state:
- Table 6.23 on page 299 lists “state per frame object”. The only states indicated are drawing buffers and a read buffer. If the viewport was part of the state of the framebuffer, it will be listed here.
- The viewing window is indicated in table 6.8 "Transformation status". This is a global state and is not associated with any object.
OpenGL 4.1 presents several viewports. But they are still part of the global state of transformation.
If you're wondering why this is so, the only real answer is that it was defined in this way. Looking at the graphics pipeline makes sense. While the glViewport() call glViewport() indicate the rectangle in the framebuffer you want to display, the call actually defines a transform that is applied as part of a fixed function block between the vertex shader (or the geometry shader, if you have one) and the fragment shader . Viewport options determine how NDC (normalized device coordinates) are mapped to window coordinates.
The state of the framebuffer, on the other hand, determines how the output of the fragment shader is written to the framebuffer. Thus, he controls a completely different part of the conveyor.
Due to the fact that viewports are commonly used by applications, I think it would be more appropriate to make part of the viewport in a framebuffer state. But OpenGL is really an API designed as an abstraction of graphic equipment, and from this point of view, the viewport does not depend on the state of the framebuffer.
source share