且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用OpenGL阵列纹理?

更新时间:2023-11-10 13:14:58

我不认为问题与数组纹理直接相关.真正的问题在于您如何尝试将部分输入图像加载到纹理中:

I don't believe the problem is directly related to array textures. The real issue is in how you are trying to load part of your input image into a texture:

glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA, twidth / 3, theight / 4, 12);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, twidth / 3, theight / 4, 12,
                GL_BGRA, GL_UNSIGNED_BYTE, data);

glTexSubImage3D()调用不知道您输入的图像有多大.它将简单地根据您作为参数传入的大小顺序读取图像数据.如果将其宽度设置为原始图像宽度的1/3,它将从输入图像的第一行读取3个纹理行,然后从图像的第二行读取另外3个纹理行,等等.

The glTexSubImage3D() call does not know how large your input image is. it will simply read your image data sequentially based on the sizes you pass in as parameters. If you give it width that is 1/3 of your original image width, it will read 3 texture rows from the first row of your input image, then another 3 texture rows from the second row of your image, etc.

您可以使用GL_UNPACK_ROW_LENGTH像素存储值指定输入行的大小(以像素为单位).对于您的情况,以下调用指定了输入图像的宽度:

You can specify the size of your input rows (in pixels) with the GL_UNPACK_ROW_LENGTH pixel storage value. For your case, the following call specifies the width of your input image:

glPixelStorei(GL_UNPACK_ROW_LENGTH, twidth);

我认为没有一种合理的方法可以通过一次glTexSubImage3D()调用将整个精灵表加载到数组纹理中.如果为每个图像分别调用,这可能是最简单的.整个过程将如下所示:

I don't think there's a reasonable way of loading your whole sprite sheet into the array texture with a single glTexSubImage3D() call. It's probably easiest if you make a separate call for each image. The whole thing will then look like this:

GLuint texId = 0;
glGenTextures(1, &texId);

glBindTexture(GL_TEXTURE_2D_ARRAY, texId);

glTexParameteri(GL_TEXTURE_2D_ARRAY, ...);

int subWidth = twidth / 3;
int subHeight = theight / 4;

glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA, subWidth, subHeight, 12);

glPixelStorei(GL_UNPACK_ROW_LENGTH, twidth);

for (int iRow = 0; iRow < 4; ++iRow) {
    for (int iCol = 0; iCol < 3; ++iCol) {
        glTexSubImage3D(
            GL_TEXTURE_2D_ARRAY, 0,
            0, 0, 3 * iRow + iCol,
            subWidth, subHeight, 1,
            GL_BGRA, GL_UNSIGNED_BYTE,
            data + (iRow * subHeight * twidth + iCol * subWidth) * 4);
    }
}

您可以尝试通过使用其他解包参数(例如GL_UNPACK_IMAGE_HEIGHT)来避免单独调用,但是我不相信有适合这种情况的设置.

You could try to avoid the separate calls by using other unpack parameters like GL_UNPACK_IMAGE_HEIGHT, but I'm not convinced that there are settings that would work for this case.