Should I vertically flip the lines of an image loaded with stb_image to use in OpenGL?

Started by
4 comments, last by Nana111 10 years, 5 months ago

Hi everybody,

I'm working on an OpenGL-powered 2d engine.

I'm using stb_image to load image data so I can create OpenGL textures. I know that the UV origin for OpenGL is bottom-left and I also intend to work in that space for my screen-space 2d vertices i.e. I'm using glm::ortho( 0, width, 0, height, -1, 1 ), not inverting 0 and height.

You probably guessed it, my texturing is vertically flipped but I'm 100% sure that my UV are specified correctly.

So: is this caused by stbi_load's storage of pixel data? I'm currently loading PNG files only so I don't know if it would cause this problem if I was using another file format. Would it? (I can't test right now, I'm not at home).

I really want to keep the screen coords in the "standard" OpenGL space... I know I could just invert the orthogonal projection to fix it but I would really rather not.

I can see two sane options:

1- If this is caused by stbi_load storage of pixel data, I could invert it at loading time. I'm a little worried about that for performance reason and because I'm using texture arrays (glTexture3d) for sprite animations meaning I would need to invert texture tiles individually which seems painful and not a general solution.

2- I could use a texture coordinate transformation to vertically flip the UVs on the GPU (in my GLSL shaders).

A possible 3rd option would be to use glPixelStore to specify the input data... but I can't find a way to tell it that the incoming pixels are vertically flipped.

What are your recommendations for handling my problem? I figured I can't be the only one using stbi_load + OpenGL and having that problem.

Just to be extra clear: I know that (0,0) is the bottom-left of the texture map. My problem is precisely that when I specify (0,0) I get the top-left corner texel... not what I expect on OpenGL That's why I'm asking if stbi_load pixel storage and OpenGL pixel storage differ and what I can do about it if that's the case.

Finally, my target platforms are PC, Android and iOS smile.png Thanks!

Advertisement

flip the UV on the CPU

Ok, I will answer my own question... I went thru the documentation for both libs (stb_image and OpenGL).

Here are the appropriate bits with reference:

glTexImage2D says the following about the data pointer parameter: "The first element corresponds to the lower left corner of the texture image. Subsequent elements progress left-to-right through the remaining texels in the lowest row of the texture image, and then in successively higher rows of the texture image. The final element corresponds to the upper right corner of the texture image." From http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml

The stb_image lib says this about the loaded image pixel: "The return value from an image loader is an 'unsigned char *' which points to the pixel data. The pixel data consists of *y scanlines of *x pixels, with each pixel consisting of N interleaved 8-bit components; the first pixel pointed to is top-left-most in the image." From http://nothings.org/stb_image.c?

So, the issue is related the pixel storage difference between the image loading lib and OpenGL. It wouldn't matter if I loaded other file formats than PNG because stb_image returns the same data pointer for all formats it loads.

So I decided I'll just swap in place the pixel data returned by stb_image in my OglTextureFactory. This way, I keep my approach platform-independent. If load time becomes an issue down the road, I'll remove the flipping at load time and do something on the GPU instead.

Hope this helps someone else in the future.

This topic was originally a StackOverflow question that I couldn't get a good answer for: http://stackoverflow.com/questions/19770296/should-i-vertically-flip-the-lines-of-an-image-loaded-with-stb-image-to-use-in-o

the first answer is somewhat correct but slightly wrong, he said (S,-T), but it should be (S,1-T)

This is really the most appropriate way to do it. much faster than flipping the pixels, and it won't effect runtime performance (only load time, and very slightly)

Yeah, (S,-T) would only work for wrapping texture mode I think. Like I said in my answer, I'll be flipping vertically the image at load time and see if it's a problem down the road. If it is, I'll probably just do (S, 1.0 - T) in my GLSL vertex shader. I want to keep my common code as portable as possible. Thanks 3TATUK2 for your replies!

HI there

I am new here ,and i want to flip the image using an image program.I know there are many image program which supports to do that.

is there any image program which supports to work offline?Thanks a lot.

This topic is closed to new replies.

Advertisement