0

我有一个 TEXTURE_2D 的纹理 2d 数组。我需要在每次绘制之前清除纹理的内容。我正在尝试使用 PBO 来完成它。但是我收到了 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

4

2 回答 2

3

级别是细节级别,即mipmap级别,在大多数情况下为0,在您的情况下深度将是数组索引。

于 2013-06-27T12:53:43.433 回答
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 级别1(甚至不存在),但是0. 但即便如此,此调用仍会尝试_viewportWidth * _viewportHeight * i在第一个数组索引处放置一个大小为 3D 的图像,这肯定不是您想要的。相反,您想清除position处大小_viewportWidth * _viewportHeight i2D 图像。所以你的电话实际上应该是这样的:

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

通过4frameSize. 您的 PBO 被视为(并由您解释)包含floats 的 4 个向量,但您以字节为单位计算它的大小,就好像它只包含单个floats。这就是为什么它神奇地适用于双维的原因,因为这会根据需要适当地将 PBO 的大小增加 4 倍,但它只会隐藏在大小计算中忘记组件计数的实际问题。

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

于 2013-07-03T15:32:17.583 回答