【问题标题】:Is it possible to bind a OpenCV GpuMat as an OpenGL texture?是否可以将 OpenCV GpuMat 绑定为 OpenGL 纹理?
【发布时间】:2013-08-07 20:00:55
【问题描述】:
【问题讨论】:
标签:
opengl
opencv
cuda
textures
gpgpu
【解决方案1】:
OpenCV 支持 OpenGL。请参阅opencv2/core/opengl_interop.hpp 头文件。您可以将 GpuMat 的内容复制到 Texture:
cv::gpu::GpuMat d_mat(768, 1024, CV_8UC3);
cv::ogl::Texture2D tex;
tex.copyFrom(d_mat);
tex.bind();
// draw something
您也可以使用cv::ogl::Buffer 类。它是 OpenGL 缓冲存储器的包装器。此内存可以映射到 CUDA 内存,无需内存复制:
cv::ogl::Buffer ogl_buf(1, 1000, CV_32FC3);
cv::gpu::GpuMat d_mat = ogl_buf.mapDevice();
// fill d_mat with CUDA
ogl_buf.unmapDevice();
// use ogl_buf in OpenGL
ogl_buf.bind(cv::ogl::Buffer::ARRAY_BUFFER);
glDrawArray(...);
【解决方案2】:
这是我的理解,也许不是 100% 正确,并为我的非母语英语道歉。
GpuMat 使用全局内存。然而 OpenGL 纹理驻留在 Texture Memory 中,这是专为 GPU 的纹理硬件(不是 CUDA 核心)设计的。纹理内存没有像通常的线性 2D/3D 数组那样组织,它可能使用某些 Space Filling Curve 来组织其内容以优化纹理缓存速率。因此,您无法获得指向 Texture 的设备指针。您只能通过 Texture Fetch(Read Only) 或 Surface R/W 直接在 CUDA 中访问 Texture Mem。
目前的 OpenCV 实现似乎没有使用 cuda 纹理/表面特征。您必须从纹理复制到全局内存才能将它们绑定为GpuMats。好吧,这不是一个“绑定”解决方案。
This thread 描述了一种写入 OpenGL 纹理的 CUDA 方法。
要么等待 OpenCV 实现新功能,要么等待 NVIDIA 新的 GPU 架构统一 Texture Mem 和 Global Mem,要么等待有人发明一种特殊的 EMP 设备来破解这些记忆...... XD