as we all know, openGL uses a pixel data orientation that has 0/0 left / bottom, while the rest of the world (including almost all image formats) uses left / top. this has been a source of endless worries (at least for me) for many years, and so far I have not been able to find a good solution.
in my application I want to support the following texture image data:
- image data from various image sources (including still images, video files and live video)
- image data obtained by copying the framebuffer into main memory (
glReadPixels ) - image data obtained by capturing a framebuffer texture (
glCopyTexImage )
(case # 1 supplies images with a top-down orientation (in about 98% of cases, for simplicity, suppose that all “external images” have a top-down orientation), No. 2 and No. 3 have a lower -up)
I want to be able to apply all these textures to various arbitrarily complex objects (for example, 3D models read from a disk that have saved information about the coordinates of the texture).
so I want one representation of the texture_code of the object. when rendering an object, I don’t want to worry about the orientation of the image source. (Until now, I always wore topdown -flag along with the texture identifier, which is used when the actual texture settings are set. I want to get rid of this awkward hack!
Basically, I see three ways to solve the problem.
- make sure that all image data is “correct” (in openGL terms it is upside down) by converting all “incorrect” data before transferring them to openGL
- provide different texture coordinates depending on the orientation of the image (0..1 for images from bottom to top, 1..0 for images from top to bottom)
- flip images on gfx card
in the old days, I did # 1, but it turned out to be too slow. we want to avoid copying the pixel buffer at all costs.
so I switched to # 2 a couple of years ago, but this is a difficult way to maintain. I really don’t understand why I should carry the metadata of the original image as soon as I transferred the image to the gfx card and got a beautiful abstract abstract “texture” object. I am in the process of finally converting my code to VBOs and would like to avoid updating my texcoord arrays, simply because I use an image of the same size but with a different orientation!
which leaves # 3, which I never managed to work for me (but I believe it should be pretty simple ). intuitively, though about using something like glPixelZoom() . this works fine with glDrawPixels() (but who uses this in real life?), and afaik should work with glReadPixels() . the latter is wonderful, as it allows me to at least force a uniform orientation of pixels (from top to bottom) for all images in the main memory.
however, it seems that glPixelZoom() does not affect the data transmitted through glTexImage2D , not to mention glCopyTex2D() , therefore the textures created from the pixels of the main memory will all be turned upside down (which I could live with, which means that I should convert all incoming texcoords to a downstream when loading them). now the remaining problem is that I have not yet found a way to copy the framebuffer into the texture (using glCopyTex(Sub)Image ) that can be used with these drop-down tex codes ( glCopyTexImage() .: how to flip the image when using glCopyTexImage() )
Is there a solution to this simple problem? what is fast, easy to maintain and runs on openGL-1.1 up to 4.x?
ah, and ideally it will work with both a force-two texture and a force-free texture (or a rectangle). (as much as possible...)