用PBO清除GL_TEXTURE_2D_ARRAY的颜色

时间:2013-06-27 09:44:56

标签: opengl

我有一个TEXTURE_2D的纹理2d数组。我需要在每次绘制传递之前清除纹理的内容。我正在尝试使用PBO.But我收到了INVALID_OPERATION错误。

以下是我创建图像数组的方法:

glGenTextures(1,&_texID);
glBindTexture (GL_TEXTURE_2D_ARRAY,_texID);
glTexStorage3D(GL_TEXTURE_2D_ARRAY,1,GL_RGBA32F,width,height,numTextures);      
glBindTexture (GL_TEXTURE_2D_ARRAY,0);
glBindImageTexture(0, _texID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);

以下是我清除它的方式:

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, clearBuffer);
glBindTexture(GL_TEXTURE_2D_ARRAY, itexArray->GetTexID());
for(int i =0; i <numTextures ;++i) {
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY,1,0, 0, 0, _viewportWidth, _viewportHeight, i , GL_RGBA, GL_FLOAT, NULL);
}
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);

我有numTextures = 8,所以数组中有8个纹理层。当我开始在循环中清除它们时,前4个被清除而没有错误但是从第四个上我得到了INVALID_OPERATION。

更新

我通过将PBO大小从2048x2048扩大到4096x4096来解决PBO INVALID_OPERATION问题,但结果是纹理数组的纹理仍然没有被正确清除。例如,在程序启动时仍然可以看到剩余的只有在渲染对象开始在视口周围移动。

以下是清算PBO的设置:

GLint frameSize =MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * sizeof(float);
glGenBuffers(1, &clearBuffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,clearBuffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER,frameSize,NULL,GL_STATIC_DRAW);
//fill the buffer with color:
vec4* data = (vec4*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER,GL_WRITE_ONLY);
memset(data,0x00,frameSize);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

MAX_FRAMEBUFFER_WIDTH和MAX_FRAMEBUFFER_HEIGHT均为4096

2 个答案:

答案 0 :(得分:3)

级别是详细程度,即mipmap级别,在大多数情况下它是0,深度将是你的情况下的数组索引。

答案 1 :(得分:2)

您的glTexSubImage3D来电已中断。

glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 
                0, 0, 0,                              //offset (first image)
                _viewportWidth, _viewportHeight, i,   //size (getting larger)
                GL_RGBA, GL_FLOAT, NULL);

首先,当然 Vasaka 是正确的,因为你不应该写mipmap level 1(它甚至不存在),而是0。但即使这样,这个调用也会尝试将大小为_viewportWidth * _viewportHeight * i的3D图像放在第一个数组索引处,这肯定不是你想要的。相反,您希望在位置_viewportWidth * _viewportHeight清除尺寸为i 的2D图像。所以你的电话实际上应该是这样的:

glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 
                0, 0, i,                               //offset (ith image)
                _viewportWidth, _viewportHeight, 1,    //size (proper 2D image)
                GL_RGBA, GL_FLOAT, NULL);

通过在4的计算中加入frameSize,可以轻松解决需要比必要条件更大的PBO的问题。您的PBO被处理(并由您解释)为包含float s的4个向量,但您计算它的大小(以字节为单位)就好像它只包含单个float s一样。这就是为什么它神奇地适用于双倍维度,因为这将适当地增加PBO的大小4次,这是必要的,但它只隐藏了在大小计算中忘记组件计数的实际问题。

编辑顺便说一句,您还可以尝试将相应的图片图层附加到FBO,而不是维护一个只包含0 s的巨大PBO。每次循环迭代中glClear。不知道哪一个更有效(但我猜glClear比整个图像副本更优化),但它至少使这个大型PBO过时了。