1

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.

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

This makes sense. So you're saying that let's you have a bitmap whose top left pixel is 0, 0 and you load it in with glTexImage2D it will read the image buffer in such a way that that 0, 1 on the bitmap is the first byte? This is just a little inconvenient as then I have to treat bitmap image textures as different from render buffers, for example, for example if I have a cube with top vertices 0, 0 and 1, 0 I then have to make I have invert all the vertices so that the top is 0, 1 and 1,1. Oh well. Thank you.
I can of three possibilities, (1) flip the texture coordinates only (uv.x, 1-uv.y) when sampling an image versus a render target, (2) use glClipControl(GL_UPPER_LEFT,...), so that both textures and render targets are stored top-left first, (3) flip the image when you import it into your project, and (4) flip the image when loading it - as part of any processing done on the image. I personally use (4), as I need to apply several transformation to the image before using it.
The interesting thing about GL_UPPER_LEFT, which I assume was added to more resemble other APIs like Vulkan and Direct3D, is that it flips the entire scene upside. To negate this I can multiply one of the Y values in the projection matrix by -1 and all works out. Thing is by doing this triangles once winding CW are now winding CCW. That's no problem either as you can control this with GL call. I also thought that rendering it again onto another renderbuffer, and then again onto my destination one (twice) make the Y opposite. I like your solutions, what do you mean my option (4)? When you
render to a buffer you can't flip it while loading, because you're not loading it, or are you talking about loading image files with options (3) and (4)? I like the idea of simply using a separate shader to sample the Y upside down.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.