如何增长GL_TEXTURE_2D_ARRAY?

时间:2015-12-12 10:59:57

标签: c++ opengl textures

我已经创建了像这样的2d纹理数组

glTexImage3D(GL_TEXTURE_2D_ARRAY,
             0,                // No mipmaps
             GL_RGBA8,         // Internal format
             width, height, 100, // width,height,layer count
             0,                // border?
             GL_RGBA,         // format
             GL_UNSIGNED_BYTE, // type
             0);               // pointer to data

例如,如何将其大小从100增加到200?我想我必须创建一个大小为200的新二维数组并用glCopyTexSubImage3D复制图像?

glBindTexture(GL_TEXTURE_2D_ARRAY, texture_id);
glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY,
                         0,
                         0, 0, 0,
                         0, 0,
                         width, height
                         );
glDeleteTextures(1, &texture_id);

GLuint new_tex_id;
glGenTextures(1, &new_tex_id);
glBindTexture(GL_TEXTURE_2D_ARRAY, new_tex_id);

glTexImage3D(GL_TEXTURE_2D_ARRAY,
             0,                
             GL_RGBA8,         
             width, height, 200, 
             0,                
             GL_RGBA,         
             GL_UNSIGNED_BYTE, 
             0);               

//How do I get the data in `GL_READ_BUFFER` into my newly bound texture? 

texture_id = new_tex_id;

但我如何从GL_READ_BUFFER

中获取数据

2 个答案:

答案 0 :(得分:1)

glCopyTexSubImage从framebuffer 复制数据,而不是纹理。这就是为什么它不会带两个纹理对象来复制。

从纹理复制到另一个纹理需要glCopyImageSubData。这是一个来自ARB_copy_image的OpenGL 4.3函数。在NV_copy_image中也可以找到类似的功能,可以更广泛地支持它。

顺便说一下,你通常应该避免做这个操作。如果你需要一个200元素的数组纹理,你应该第一次分配它。

答案 1 :(得分:1)

@NicolBolas指出的glCopyImageSubData()函数是最简单的解决方案,如果你可以要求OpenGL 4.3或更高版本。

您可以将glCopyTexSubImage3D()用于此目的。但由于此函数的源是当前读取的帧缓冲区,因此需要将原始纹理绑定为帧缓冲附件。代码可能大致如下:

GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);

glBindTexture(GL_TEXTURE_2D_ARRAY, new_tex_id);

for (int layer = 0; layer < 100; ++layer) {
    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0, tex_id, 0, layer);
    glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY,
        0, 0, 0, layer, 0, 0, width, height);
}

您也可以使用glBlitFramebuffer()代替:

GLuint fbos[2] = {0, 0};
glGenFramebuffers(2, fbos);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);

for (int layer = 0; layer < 100; ++layer) {
    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0, tex_id, 0, layer);
    glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0, new_tex_id, 0, layer);
    glBlitFramebuffer(
        0, 0, width, height, 0, 0, width, height,
        GL_COLOR_BUFFER_BIT, GL_NEAREST);
}

这两个选项应该或多或少相同。我可能会使用glBlitFramebuffer(),因为它是一个较新的功能(在3.0中引入),它可能更常用。所以它可能会更加优化。但是,如果这对您的应用程序来说性能至关重要,那么您应该尝试两者并进行比较。