简体   繁体   English

如何将 GL_TEXTURE_2D_ARRAY 与 stb_image 一起使用

[英]How to use GL_TEXTURE_2D_ARRAY with stb_image

I'm trying to create sprite animation with texture array.我正在尝试使用纹理数组创建精灵 animation 。 Right now I have follow code:现在我有以下代码:

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)
    ));
}

Fragment shader:片段着色器:

#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()));
}

And seems like I incorrectly crop source texture, because when I run my program in Nsight debugger I saw follow:似乎我错误地裁剪了源纹理,因为当我在 Nsight 调试器中运行我的程序时,我看到如下:

Texture array:纹理数组:

纹理数组

Original image:原图:

原始图像

Is it issue with cropping source image, or issue with fragment shader?是裁剪源图像的问题,还是片段着色器的问题? How to make sprite animation correctly?如何正确制作精灵 animation?

You calculate the data offset incorrectly.您计算的数据偏移量不正确。 The correct way would be:正确的方法是:

Convert i to a 2-d index of the tile:i转换为图块的二维索引:

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

The x and y coordinates of its top-left pixel would be at其左上角像素的xy坐标将位于

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

The offset can be calculated then by:然后可以通过以下方式计算偏移量:

buffer + 4*(y*width + x)

Note that you shall use 4 instead of depth because stb returns the number of channels that was found in the file rather the number of the channels returned.请注意,您应该使用4而不是depth ,因为 stb 返回在文件中找到的通道数,而不是返回的通道数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM