I have a OpenCV mat that I want to render to with OpenGL. So I try to load the openCV mat as a texture via a code that I found online and render to that texture:
void BindCVMat2GLTexture(cv::Mat& image, GLuint& imageTexture)
{
if (image.empty()) {
std::cout << "image empty" << std::endl;
}
else {
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glGenTextures(1, &imageTexture);
glBindTexture(GL_TEXTURE_2D, imageTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Set texture clamping method
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
cv::cvtColor(image, image, CV_RGB2BGR);
glTexImage2D(GL_TEXTURE_2D, // Type of texture
0, // Pyramid level (for mip-mapping) - 0 is the top level
GL_RGB, // Internal colour format to convert to
image.cols, // Image width i.e. 640 for Kinect in standard mode
image.rows, // Image height i.e. 480 for Kinect in standard mode
0, // Border width in pixels (can either be 1 or 0)
GL_RGB, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
GL_UNSIGNED_BYTE, // Image data type
image.ptr()); // The actual image data itself
//NULL);
}
}
Then I create a FBO:
//init the texture
GLuint imageTexture;
BindCVMat2GLTexture(target, imageTexture);
//init the frame buffer
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// Set "renderedTexture" as our colour attachement #0
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, imageTexture, 0);
Then I'm calling:
glViewport(0, 0, target.cols, target.rows);
MyDraw();
After this calls I use another function I found to copy the texture data back to an openCV mat:
cv::Mat GetOcvImgFromOglImg(GLuint ogl_texture_id)
{
glBindTexture(GL_TEXTURE_2D, ogl_texture_id);
GLenum gl_texture_width, gl_texture_height;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint*)&gl_texture_width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&gl_texture_height);
unsigned char* gl_texture_bytes = (unsigned char*)malloc(sizeof(unsigned char)*gl_texture_width*gl_texture_height * 3);
glGetTexImage(GL_TEXTURE_2D, 0 /* mipmap level */, GL_BGR, GL_UNSIGNED_BYTE, gl_texture_bytes);
return cv::Mat(gl_texture_height, gl_texture_width, CV_8UC3, gl_texture_bytes);
}
and call this by:
target = GetOcvImgFromOglImg(imageTexture);
Also I create triangle vertices and a vertex shader that simply leaves them untouched and a fragment shader that just puts out the color red. In theory I just want a red triangle drawn over this texture as a first step. However it is not working since I get no rendered image at all. I'm a very beginner with openGL and I can't find any solution by myself right now. Any ideas what I'm doing wrong?