glPixelStorei(GL_UNPACK_ALIGNMENT,1)缺点?

问题描述 投票:27回答:3

总是使用1的对齐有什么缺点?

glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glPixelStorei(GL_PACK_ALIGNMENT, 1)

它会影响现代gpus的性能吗?

c++ opengl alignment textures pbo
3个回答
43
投票

数据如何不是1字节对齐的?

这强烈表明缺乏对row alignment in pixel transfer operations means的理解。

传递给OpenGL的图像数据应该按行分组。每行包含width像素数,每个像素的大小由格式和类型参数定义。因此,具有GL_RGB类型的GL_UNSIGNED_BYTE格式将导致像素大小为24位。否则期望像素被打包,因此这些像素中的16行将占用48个字节。

期望每行按照GL_PACK/UNPACK_ALIGNMENT定义的特定值对齐。这意味着您添加到指针以获取到下一行的值为:align(pixel_size * width, GL_*_ALIGNMENT)。如果像素大小为3字节,宽度为2,对齐为1,则行字节大小为6.如果对齐为4,则行字节大小为8。

看到问题了吗?

图像数据可能来自某些图像文件格式,如某些图像加载器所加载的,具有行对齐。有时这是1字节对齐,有时不是。 DDS图像具有指定为格式一部分的对齐。在许多情况下,图像具有4字节行对齐;因此,小于32位的像素大小将在具有特定宽度的行的末尾处具有填充。如果你给OpenGL的对齐方式不匹配,那么你会得到格式错误的纹理。

您将对齐设置为与图像格式的对齐方式匹配。如果您知道或以其他方式可以确保行对齐始终为1(除非您编写自己的图像格式或DDS编写器,否则这种情况不太可能),您需要将行对齐设置为图像格式使用的行对齐方式。


11
投票

它会影响现代gpus的性能吗?

不,因为像素存储设置仅与从GPU传输数据或与GPU传输数据相关,即数据的对齐。一旦进入GPU内存,它就会以GPU和驱动程序所需的任何方式对齐。


0
投票

对性能没有影响。设置更高的对齐(在openGL中)不会改善任何东西,也不会加快速度。

所有对齐都是告诉openGL预期下一行像素的位置。如果图像像素紧密堆积,即一行字节结束的位置和新行开始的位置之间没有间隙,则应始终使用1的对齐方式。

默认对齐方式是4(即openGL期望下一行像素在内存中跳转后可被4整除),这可能会导致加载R,RG或RGB纹理而非4字节浮点数的问题,或宽度不能被4整除。如果您的图像像素紧凑,您必须将对齐更改为1才能使解包工作。

你可以(我个人没有遇到它们)有一个图像,例如3x3 RGB ubyte,其行是第4对齐的,最后用3个额外字节作为填充。哪些行可能如下所示:

R - G - B - R - G - B - R - G - B - X - X - X(总共16个字节)

原因是对齐的数据改善了处理器的性能(不确定它在当今处理器上的真实/合理程度)。如果您可以控制原始图像的组成方式,那么可能采用某种方式对齐它将改善对图像的处理。但这是在openGL之前完成的。 OpenGL无法改变这一点,它只关心在哪里找到像素。

因此,回到上面的3x3图像行 - 将对齐设置为4将是好的(并且必要)跳过最后一个填充。如果你把它设置为1然后,它会弄乱你的结果,所以你需要保持/恢复它4.(注意你也可以使用ROW_LENGTH跳过它,因为这是处理子集时使用的参数图像,在这种情况下,你有时必须跳过3或7个字节(这是8的对齐参数可以给你的最大值)。在我们的例子中,如果你提供行长度为4,对齐为1也将工作)。

包装也一样。您可以告诉openGL将像素行对齐为1,2,4和8.如果要保存3x3 RGB ubyte,则应将对齐设置为1.从技术上讲,如果要将生成的行紧密打包,应该总是给1.如果你想(无论出于何种原因)创建一些填充,你可以给出另一个值。给(在我们的示例中)PACK_ALIGNMENT为4将导致创建看起来像上面的行的行(最后有3个额外的填充)。请注意,在这种情况下,您的包含对象(openCV mat,bitmap等)应该能够接收额外的填充。

© www.soinside.com 2019 - 2024. All rights reserved.