Zebrafish
Zebrafish

Reputation: 13886

OpenGL texture coordinates are opposite when reading from a framebuffer object

If I load a texture from a file image into OpenGL and I create a plane placed vertically, if I set the top left vertex the texture coordinates (0, 0) then the texture at that point is sampled at the top left of the image that you open in an application.

However when I render to a framebuffer, and I bind its colour attachment as the texture, the top left vertex with coordinates (0, 0) will be sample from the bottomleft, as would be seen if this framebuffer was displayed to the screen. In other words when sampling from a framebuffer texture the Y seems to be inverted.

Whether I've set the glClipControl to GL_UPPER_LEFT or GL_LOWER_LEFT this texture sampling behaviour is the same, ie., it considers bottom left of the sampled framebuffer texture as (0, 0). I've noticed this because I render my GUI to a framebuffer, then render to the default framebuffer, and whereas normal image textures loaded from files sample (0, 0) at the top left of the image, it seems opposite when sampling from a framebuffer texture:

enter image description here

Is this normal and can I make it so that sampling (0, 0) from a framebuffer texture is the topleft? glClipControl(GL_UPPER_LEFT) doesn't have any effect on this particular thing? I'm confused.

Upvotes: 1

Views: 2537

Answers (1)

sterin
sterin

Reputation: 1958

I think that looking at it a bit differently might resolve the problem.

The texture coordinate (0, 0) does not refer to the top-left or bottom-left pixel of a texture, it refers to the first pixel of a texture. Similarly (1, 1) does not refer to the bottom-right or top-right pixel but rather to the last pixel.

In OpenGL, the first pixel of the texture is considered to be the bottom-left pixel.

However, in most image formats, by convention, the first pixel in the file is considered to be the top-left pixel.

In other words, from OpenGL's perspective, when an image is loaded into a texture, the texture is actually upside-down.

This explains why there is a difference between sampling from a render target and from an image loaded from an image file.

Now what about glClipControl(GL_UPPER_LEFT, ...)?

Calling glClipControl(GL_UPPER_LEFT, ...) has no effect on sampling from textures. It does not affect how the image is sampled, the first pixel remains the first pixel.

What it does is to render the framebuffer upside down. So when the render target is sampled at (0, 0), it still samples the first pixel, but now it is reversed from what it was before glClipControl(GL_UPPER_LEFT, ...) was called.

Upvotes: 3

Related Questions