OpenGL PixelBufferObject中的位图填充字节



我有一个大小为3750x1407的位图,它作为位图加载到内存中,填充为2字节,因此它在内存中的长度为(3752*1407)字节。当使用PixelUnpackBuffer来填充我的纹理时,我是否需要复制填充字节,或者我可以跳过它们?

            GL.BindTexture(TextureTarget.Texture2D, texId);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pboId[currentIndex]);
            GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, bitmap.Width, bitmap.Height, PixelFormat.Luminance,
               PixelType.UnsignedByte, IntPtr.Zero);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pboId[nextIndex]);
            BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
            ImageLockMode.ReadOnly, bitmap.PixelFormat);
            GL.ColorTable(ColorTableTarget.ColorTable, PixelInternalFormat.Luminance, _colorTable.Length, PixelFormat.Luminance, PixelType.Byte, new IntPtr(_colorTable[0]));
            IntPtr buf = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
            if (buf != IntPtr.Zero)
            {
              //---------------------------------------- Currently copying padding bytes--------------------------------------------- //
                memcpy(buf, bitmapData.Scan0, new UIntPtr((uint)(bitmapData.Stride * bitmap.Height)));
                GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer);
            }
            bitmap.UnlockBits(bitmapData);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);

如果正确应用,任何选项都可以工作。您可以通过GL_UNPACK_*参数集控制行填充/大小,您可以使用glPixelStorei()设置。

从问题和代码中使用的格式来看,看起来您有一个1字节/像素的格式。我的大多数答案也应该适用于其他格式,但我将使用它来计算。

此处关键的GL_UNPACK_*参数有:

  • GL_UNPACK_ALIGNMENT:以字节为单位定义数据的行对齐方式。默认值是4。这意味着不是4字节的倍数的行被填充到下一个4的倍数。
  • GL_UNPACK_ROW_LENGTH:以像素为单位定义行大小。默认为0,这是一个特殊的值,表示将使用传递给glTex(Sub)Image2D()的宽度。

填充输入数据

将填充的输入数据存储在PBO中,数据的宽度为3752字节,其中前3750是有效的。由于3752是4的倍数,因此GL_UNPACK_ALIGNMENT的默认值将适用于该数据。

然而,因为你的纹理宽度只有3750像素,而数据的宽度是3752,你必须设置行长度为数据的宽度:

glPixelStorei(GL_UNPACK_ROW_LENGTH, 3752);

对于glTexSubImage2D()中的宽度,您仍然将指定3750。之后不要忘记重置行长度。

未填充的输入数据

如果在PBO中存储数据之前/同时删除填充,PBO中的数据宽度现在为3750字节。因为这是而不是 4的倍数,所以必须设置解包对齐,以防止数据被读取为3752字节/行。1的值将避免任何对齐(2也可以在您的情况下工作,因为您的行长度是2字节的倍数):

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

另一方面,PBO中数据的宽度现在与纹理宽度相同。因此,您不必费心设置GL_UNPACK_ROW_LENGTH,因为默认值0意味着纹理宽度用于数据的宽度。

相关内容

  • 没有找到相关文章