我应该垂直翻转加载了stb_image的图像的行以在OpenGL中使用吗?

问题描述 投票:4回答:4

我正在研究一款支持OpenGL的2d引擎。

我正在使用stb_image加载图像数据,因此我可以创建OpenGL纹理。我知道OpenGL的UV原点是左下角,我也打算在那个空间中为我的屏幕空间2d顶点工作,即我使用的是glm :: ortho(0,width,0,height,-1,1) ),不反转0和高度。

你可能已经猜到了,我的纹理垂直翻转,但我100%确定我的UV指定正确。

那么:这是由stbi_load存储像素数据引起的吗?我目前只加载PNG文件,所以如果我使用其他文件格式,我不知道是否会导致此问题。是吗? (我现在不能测试,我不在家)。

我真的想把屏幕坐标保持在“标准”OpenGL空间......我知道我可以反转正交投影来修复它,但我真的不愿意。

我可以看到两个理智的选择:

1-如果这是由像素数据的stbi_load存储引起的,我可以在加载时将其反转。出于性能原因我有点担心,因为我使用纹理数组(glTexture3d)进行精灵动画,这意味着我需要单独反转纹理贴片,这看起来很痛苦,而不是一般的解决方案。

2-我可以使用纹理坐标转换来垂直翻转GPU上的UV(在我的GLSL着色器中)。

可能的第三个选项是使用glPixelStore来指定输入数据......但我找不到告诉它输入像素是垂直翻转的方法。

您对处理我的问题有什么建议?我想我不能是唯一一个使用stbi_load + OpenGL并且遇到这个问题的人。

最后,我的目标平台是PC,Android和iOS :)

编辑:我回答了我自己的问题......见下文。

c++ opengl textures
4个回答
14
投票

我知道这个问题很老了,但这是谷歌在尝试解决这个问题时的第一个结果之一,所以我想我会提供一个更新的解决方案。

在最初问这个问题之后的某个时候stb_image.h添加了一个名为“stbi_set_flip_vertically_on_load”的函数,简单地将true传递给这个函数将导致它以OpenGL期望的方式输出图像 - 从而无需手动翻转/纹理坐标翻转。

此外,对于那些不知道从哪里获得最新版本的人,无论出于何种原因,你都可以在github上找到它并积极参与:https://github.com/nothings/stb

值得注意的是,在stb_image的当前实现中,它们逐像素地翻转图像,这并不完全符合要求。这可能会在以后发生变化,因为他们已经将其标记为受害者。但是,如果您正在处理非常大的图像和/或大量图像,那么自己翻转它可能会更有效(并且可能会提示它提示)。


9
投票

好的,我将回答我自己的问题......我通过两个库(stb_image和OpenGL)的文档。

以下是适当的位参考:

glTexImage2D对数据指针参数说:“第一个元素对应于纹理图像的左下角。后续元素从左到右穿过纹理图像最下面的剩余纹素,然后依次进行纹理图像的较高行。最后一个元素对应于纹理图像的右上角。“来自http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml

stb_image lib说明了加载的图像像素:“图像加载器的返回值是'unsigned char *',它指向像素数据。像素数据由* x像素的* y扫描线组成,每个像素由N个交错的8位分量;指向的第一个像素位于图像的左上角。“来自http://nothings.org/stb_image.c

因此,问题与图像加载lib和OpenGL之间的像素存储差异有关。如果我加载其他文件格式而不是PNG并不重要,因为stb_image为它加载的所有格式返回相同的数据指针。

所以我决定在我的OglTextureFactory中交换stb_image返回的像素数据。这样,我保持我的方法独立于平台。如果加载时间成为问题,我会在加载时删除翻转并在GPU上执行某些操作。

希望这有助于将来的其他人。


0
投票

由于这是一般图像库和OpenGL之间相反的假设,Id说最好的方法是操纵垂直UV-coord。这需要很少的工作量,并且在使用任何图像库加载图像并将其传递给OpenGL时始终是相关的。

在着色器中使用顶点人口中的1.0f-uv.y或者着色器反转tex-coords。

 fcol = texture2D( tex, vec2(uv.x,1.-uv.y) );

-1
投票

是的你应该。只需在加载图像之前调用此STBI函数即可轻松完成此操作:

stbi_set_flip_vertically_on_load(true);  
© www.soinside.com 2019 - 2024. All rights reserved.