Is it possible to bind a OpenCV GpuMat as an OpenGL texture?

◇◆丶佛笑我妖孽 提交于 2019-12-02 21:06:10

OpenCV has OpenGL support. See opencv2/core/opengl_interop.hpp header file. You can copy the content of GpuMat to Texture:

cv::gpu::GpuMat d_mat(768, 1024, CV_8UC3);
cv::ogl::Texture2D tex;
tex.copyFrom(d_mat);
tex.bind();
// draw something

You can also use cv::ogl::Buffer class. It is a wrapper for OpenGL buffer memory. This memory can be mapped to CUDA memory without memory copy:

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(...);

Well here's my understanding, maybe not 100% correct, and apologize for my non-mother-lang-English.

GpuMat uses Global Memory. However OpenGL textures resides in Texture Memory, which is specially designed for GPU's texture hardware(not CUDA cores). Texture mem are't organized as usual linear 2D/3D arrays, it may use certain Space Filling Curve to organize its content as to optimize texture cache rate. Thus you cannot get a device pointer to Texture. You can only access Texture Mem directly in CUDA via Texture Fetch(Read Only) or Surface R/W.

Present OpenCV implementation don't seem to use cuda texture/surface feature. You have to copy from textures to Global memory to bind them as GpuMats. Well, not quite a "bind" solution.

This thread describes a CUDA approach writing to OpenGL textures.

Either wait for OpenCV to implement the new feature, or wait NVIDIA's new GPU architecture unifying Texture Mem and Global Mem, or wait someone invent a special EMP device to hack these memories ... XD

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!