Does OpenGL invert texture orientation during pixel transfer?

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...)

+7
source share
2 answers

Is there a solution to this simple problem? what is fast, easy to maintain and runs on openGL-1.1 up to 4.x?

Not.

There is no way to change the orientation of the pixel data during pixel loading. There is no way to change the texture orientation in place. The only way to change the orientation of the texture (in addition to loading, flipping, and reloading) is to use the inverted blut framebuffer from the framebuffer containing the source texture to the framebuffer containing the destination texture. And glFramebufferBlit not available on any hardware that is so outdated that it does not support GL 2.x.

So, you have to do what everyone else does: flip through your textures before loading them. Or better yet, flip the textures on the disk, and then load them without turning them over.

However, if you really want to not flip the data, you can simply force all your shaders to take a form that tells them whether they need to invert Y of their texture coordinate data. Inversion should not be anything more than a multiply / add operation. This can be done in the vertex shader to minimize processing time.

Or, if you are coding a fixed function in the dark, you can apply a texture matrix that inverts Y.

+7
source

why arent you changing the way the texture is displayed on the polygon? I use this coordinate map {0, 1, 1, 1, 0, 0, 1, 0} to start at the top left and this coordinate map {0, 0, 1, 0, 0, 0, 1, 1, 1}, to start at the bottom left. Then you do not need to manually switch your photos.

more information about mapping textures to a polygon can be found here: http://iphonedevelopment.blogspot.de/2009/05/opengl-es-from-ground-up-part-6_25.html

+2
source

All Articles