为什么Android与PC平台按照opengl坐标贴纹理会出现颠倒
在学习libgdx中直接用gl texture的时候,用一个全屏的square, 贴上了一张人头,但是结果人头朝下(原来没有这样的对齐要求,都没仔细看)。反复核对vertices的顺序和 uv坐标确实是正确的。但是每次启动之后,依旧是上下翻过来的, 让我很崩溃。于是找各种答案,最终似乎有结果,应该如下这个原因,写出我的个人理解。欢迎交流。
vertices array如下:
float[] attribute_array = { // posX, posY, posZ, u, v -1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1, }
idx如下:
int[] verticesIdx_array = { 0, 1, 2, 0, 2, 3, }
找到了这个link: 其中作者有这样一段话, 并附上了opengl的st配图.
In most computer images, the y axis is pointing downwards.This means that the top-left most corner of the image is (0, 0), and the y values increase the lower you go.In other words, the y-axis is flipped between OpenGL’s coordinate system and most computer images, and this is something you need to take into account.
看完这段话,我就不明白了,坐标系统的上下颠倒,和绘制出来的人头颠倒有毛关系啊。我用了st(0,0),最后画出来的就是图片的左上角,st(1,1)就是右下角,和gl的manual解释不同啊,是不是opengl manual里面的st坐标应该从左上角开始啊,画错了?我可是运行后得出的结果呀。
同样, 和我一样的人是存在的, 就在这个link的下方, 有为叫'Riccardo'的朋友问道了这个问题:
Is there an error in that picture or am I missing something? Thank you
他还提出了一种他的理解,我也是这样在结果和理论不同中,扭曲出同样的理解,那就是gl与native实现之间存在这样一个接口:
image.getPixel(offsetX, offsetY)
在pixels load进gl中后,同样是'getPixel(0, 0)' 的情况,android与PC平台返回了图片的左上角,gl默认返回左下角,最终导致了人头朝下了。
作者基于这个理解,做出来坚定的否定,但鼓励'Riccardo'认为方向够上了。
Actually getPixel(0,0) will return the same pixel from a texture in both cases, but you’re on the right track.
在作者后续的解释中,我终于明白了:
If you want to think about it another way, OpenGL matches the Cartesian system that you used when drawing graphs in school, and it’s the native graphics libraries that have an inverted Y axis. If we just assigned our texture coordinates to match OpenGL’s coordinates, and our camera was not upside down, then it would be the image that appeared upside down.Why?When it finally draws the image, getPixel(x,y) will still map to the same values (well, OpenGL normalizes the range to [0,1], but 0,0 and maxX, maxY will still map to the same points) but the direction in which they will be drawn will be reversed.
不是opengl的st坐标标注错了; 也不是有那么一个 'image.getPixel(offsetx,offsety)'的存在,平台有差异。而是平台的最终image库绘制图片的时候,将图片上下颠倒了(reverse the Y)。………image库………Bingo, 明白了。
所以,作者给我们了两个解决方案。
- 颠倒图片pixel data.
- 我们颠倒st中的t.
显然,后者的代价小的多, 并且直接放进ViewMatrix,这个变化对上层的调用者来说,基本就透明了。
这个是启发我的link:http://www.learnopengles.com/android-lesson-four-introducing-basic-texturing/
Date: 2014-10-25 19:53:26 CST