如何将GL_纹理_2D_ARRAY与STB_IMAGE一起使用

frebpwbc  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(185)

我正在尝试用纹理数组创建精灵动画。现在我有以下代码:

int width, height, depth;
stbi_set_flip_vertically_on_load(true);
byte_t* buffer = stbi_load(R"(.fire.jpg)",
                                   &width, &height, &depth, STBI_rgb_alpha);
if (buffer == nullptr) {
    std::cerr << "Could not read texture" << std::endl;
    return EXIT_FAILURE;
}
GLuint texture_id;
const GLenum target = GL_TEXTURE_2D_ARRAY;
SAFE_CALL(glGenTextures(1, &texture_id));
SAFE_CALL(glBindTexture(target, texture_id));
SAFE_CALL(glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0));
SAFE_CALL(glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 1));
SAFE_CALL(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
SAFE_CALL(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
SAFE_CALL(glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
SAFE_CALL(glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

const GLsizei tile_w_count = 6, tile_h_count = 6;
const GLsizei total_tiles = tile_w_count * tile_h_count;
const GLsizei tile_w = width / tile_w_count,
              tile_h = height / tile_h_count;
std::cout << "Texture WxH: " << width << "x" << height;
std::cout << ", Tile WxH: " << tile_w << "x" << tile_h << std::endl;
SAFE_CALL(glTexStorage3D(target, 1, GL_RGBA8, tile_w, tile_h,
                         total_tiles));

SAFE_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, width));
SAFE_CALL(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, height));
for (GLsizei i = 0; i < total_tiles; ++i) {
    SAFE_CALL(glTexSubImage3D(
        GL_TEXTURE_2D_ARRAY,
        0,
        0, 0, i,
        tile_w, tile_h, 1,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        buffer + (i * tile_w * tile_h * depth)
    ));
}

片段着色器:


# version 460 core

in vec2 tex_coords;
out vec4 frag_color;

uniform sampler2DArray texture_0;

uniform int current_frame;
uniform int total_frames;

float actual_layer() {
    return max(0, min(total_frames - 1,
                      floor(current_frame + 0.5)));
}

void main() {
    frag_color = texture(texture_0, vec3(tex_coords, actual_layer()));
}

似乎我错误地裁剪了源代码纹理,因为当我在NSight调试器中运行我的程序时,我看到以下内容:

纹理数组:

原图:

是剪裁源图像有问题,还是碎片着色器有问题?如何正确制作精灵动画?

lymgl2op

lymgl2op1#

您计算的数据偏移量错误。正确的方式应该是:

i转换为平铺的二维索引:

int ix = i % tile_w_count;
int iy = i / tile_w_count;

其左上角像素的xy坐标为

int x = ix*tile_w;
int y = iy*tile_h;

然后,可以通过以下方式计算偏移量:

buffer + 4*(y*width + x)

请注意,您应该使用4而不是depth,因为STB返回的是在文件中找到的频道数,而不是返回的频道数。

相关问题