我已经创建了像这样的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
?
答案 0 :(得分:1)
glCopyTexSubImage
从framebuffer 复制数据,而不是纹理。这就是为什么它不会带两个纹理对象来复制。
从纹理复制到另一个纹理需要glCopyImageSubData
。这是一个来自ARB_copy_image的OpenGL 4.3函数。在NV_copy_image中也可以找到类似的功能,可以更广泛地支持它。
答案 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中引入),它可能更常用。所以它可能会更加优化。但是,如果这对您的应用程序来说性能至关重要,那么您应该尝试两者并进行比较。