如何将由CUDA生成的PBO拷贝到带有Mipmapping的纹理中

3

我想将一个启用自动mipmapping的PBO复制到一个纹理中,但似乎只生成了顶层纹理(换句话说,没有进行mipmapping)。

我正在使用以下方法构建PBO:

//Generate a buffer ID called a PBO (Pixel Buffer Object)
glGenBuffers(1, pbo);
//Make this the current UNPACK buffer
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *pbo);
//Allocate data for the buffer. 4-channel 8-bit image
glBufferData(GL_PIXEL_UNPACK_BUFFER, size_tex_data, NULL, GL_DYNAMIC_COPY);
cudaGLRegisterBufferObject(*pbo);

我正在使用某种方法构建纹理

// Enable Texturing
glEnable(GL_TEXTURE_2D);

// Generate a texture identifier
glGenTextures(1,textureID);

// Make this the current texture (remember that GL is state-based)
glBindTexture( GL_TEXTURE_2D, *textureID);

// Allocate the texture memory. The last parameter is NULL since we only
// want to allocate memory, not initialize it
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA_FLOAT32_ATI, size_x, size_y, 0,
GL_RGBA, GL_FLOAT, NULL);

// Must set the filter mode, GL_LINEAR enables interpolation when scaling
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

稍后在内核中,我会使用类似以下的方式修改PBO:

float4* aryPtr = NULL;
cudaGLMapBufferObject((void**)&aryPtr, *pbo);

//Pixel* gpuPixelsRawPtr = thrust::raw_pointer_cast(&gpuPixels[0]);
//... do some cuda stuff to aryPtr ...

//If we don't unmap the PBO then OpenGL won't be able to use it:
cudaGLUnmapBufferObject(*pbo);

现在,在使用上述生成的纹理将图像绘制到屏幕之前,我会调用以下函数:(请注意,rtMipmapTex = *textureID,rtResultPBO = *pbo)

glEnable(GL_DEPTH);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, rtMipmapTex);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, rtResultPBO);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, canvasSize.x, canvasSize.y, GL_RGBA, GL_FLOAT, NULL);

这一切都运行正常,并正确显示纹理。但是,如果我将最后一行更改为

glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, canvasSize.x, canvasSize.y, GL_RGBA, GL_FLOAT, NULL);

据我所知,以下代码应该显示纹理金字塔中第一个级别而不是零级纹理,但实际上我只得到了一张空白的白色纹理。

我该如何将纹理从PBO复制,以便能够触发自动mipmapping?

谢谢。

1个回答

3
我太傻了。上面的代码完美地运行了,问题是...
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, canvasSize.x, canvasSize.y, GL_RGBA, GL_FLOAT, NULL);

不是从纹理中选择mipmap级别,而是从未经mipmap处理的pbo中选择。您可以使用以下方法显示特定的mipmap级别:

glTexEnvi(GL_TEXTURE_FILTER_CONTROL,GL_TEXTURE_LOD_BIAS, 4);

你的代码中还有一个小错误:glEnable(GL_DEPTH); 应该会产生无效的枚举 GL 错误。请使用 GL_DEPTH_TEST 作为参数。 - euphrat
实际上,它将PBO复制到第二级,但然后使用第一层(未修改的层)来生成mip金字塔。 - Stefan Dragnev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接