Hi,
I’m trying to genererate an opengl texturedirecly from a GpuMat.
I do something like this:
struct GPUTexture
{
std::shared_ptr<cv::ogl::Texture2D> m_pTexture;
std::shared_ptr<cv::ogl::Buffer> m_pGpuBuffer;
unsigned int m_uiTexture = 0;
bool m_bDirty = true;
int texWidth = 0;
int texHeight = 0;
int texType = -1;
};
GPUTexture m_gpuTexture;
void bindTexture(const cv::cuda::GpuMat& mat)
{
if (!mat.empty())
{
if (m_gpuTexture.m_bDirty)
{
const bool bCreationTime = (m_gpuTexture.m_uiTexture == 0) || (m_gpuTexture.texHeight < mat.rows) || (m_gpuTexture.texWidth < mat.cols) || (m_gpuTexture.texType != mat.type());
if (!m_gpuTexture.m_pGpuBuffer)
{
m_gpuTexture.m_pGpuBuffer = std::make_shared<cv::ogl::Buffer>();
}
else if (m_gpuTexture.m_pGpuBuffer->type() != mat.type())
{
m_gpuTexture.m_pGpuBuffer = std::make_shared<cv::ogl::Buffer>();
}
m_gpuTexture.m_pGpuBuffer->copyFrom(mat(cv::Rect(0, 0, mat.cols, mat.rows)), cv::ogl::Buffer::PIXEL_UNPACK_BUFFER);
if (m_gpuTexture.m_uiTexture == 0)
{
//create texture
glGenTextures(1, &m_gpuTexture.m_uiTexture);
glBindTexture(GL_TEXTURE_2D, m_gpuTexture.m_uiTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
constexpr float borderColor[] = { 0, 0, 0, 1 };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
}
else
{
glBindTexture(GL_TEXTURE_2D, m_gpuTexture.m_uiTexture);
}
//--------------------------------------------------------------------------------------------------------------
m_gpuTexture.m_pGpuBuffer->bind(cv::ogl::Buffer::PIXEL_UNPACK_BUFFER);
if (bCreationTime)
{
m_gpuTexture.texHeight = mat.rows;
m_gpuTexture.texWidth = mat.cols;
m_gpuTexture.texType = mat.type();
switch (mat.type())
{
case CV_32FC1:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, mat.cols, mat.rows, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
break;
case CV_32FC3:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, mat.cols, mat.rows, 0, GL_BGR, GL_FLOAT, NULL);
break;
case CV_32FC4:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, mat.cols, mat.rows, 0, GL_BGRA, GL_FLOAT, NULL);
break;
case CV_8UC1:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, mat.cols, mat.rows, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
break;
case CV_8UC3:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, mat.cols, mat.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
break;
case CV_8UC4:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mat.cols, mat.rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
break;
default:
break;
}
}
else
{
// update texture
switch (mat.type())
{
case CV_32FC1:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mat.cols, mat.rows, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
break;
case CV_32FC3:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mat.cols, mat.rows, GL_BGR, GL_FLOAT, NULL);
break;
case CV_32FC4:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mat.cols, mat.rows, GL_BGRA, GL_FLOAT, NULL);
break;
case CV_8UC1:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mat.cols, mat.rows, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
break;
case CV_8UC3:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mat.cols, mat.rows, GL_BGR, GL_UNSIGNED_BYTE, NULL);
break;
case CV_8UC4:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mat.cols, mat.rows, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
break;
default:
break;
}
}
cv::ogl::Buffer::unbind(cv::ogl::Buffer::PIXEL_UNPACK_BUFFER);
m_gpuTexture.m_bDirty = false;
}
else
{
glBindTexture(GL_TEXTURE_2D, m_gpuTexture.m_uiTexture);
}
}
}
For a particular Gpu mat with:
cols = 1936
rows = 1066
type = CV_UC1
step = 2048
I have this results:
I think the problem come from the step.
Do you have an idea to solve this problem ?
Thanks,
sorry for my english