Hi,
I'm using OpenGL to accelerate some texture warping using an OpenCV window for context. Now I need to do 3D rendering. So I made 2 FBO :
-The first (let's say FBO1) is to warp textures and works well. The size here is fixed and always < to size of FBO2.
-The second is to apply transformations on a 3D model. The size here change for every frame with the ROI on the image.
I saw that there is a cv::setopenglcontext, but I would like to limit the amount of windows displaying nothing.
Here is my problem : The FBO2 always have the same size as the first. I know it, because when I read the buffer (with glReadPixels) in a Mat with FBO2's size it's not ok. But when I read in a Mat with FBO1's size the image is not deformed but it's just a part of the image :
I check for OpenGL errors, but I don't have any one.
The FBO1 is 1 channel 32bit floating data (GL_R32F).
The FBO2 is 4 channel 32bit unsigned byte (GL_UNSIGNED_BYTE).
I just draw a red square to test.
Maybe it's a part of the problem, but I saw in window.cpp that OpenCV already use buffers to deal with CV_WINDOW_OPENGL. Can it be the source of my problem : I resize all "my" context, but not the OpenCV buffer. I tried to call imshow() with bigger image to force it to resize "his" buffer but it's all black then.
Some code :
void ARContext(){
resizeWindow("GL", roi.width, roi.height);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
perspectiveGL( 47.0, roi.width/roi.height, 0.01, 100.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, roi.width, roi.height);
glBindTexture(GL_TEXTURE_2D, poseTexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, roi.width, roi.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbuffer(GL_RENDERBUFFER, poseDBufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, roi.width, roi.height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, poseFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, poseTexID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, poseDBufferID);
errorCheck("AR Context");
}
void WarpContext(){
resizeWindow("GL", model->getROI().width, model->getROI().height);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, *warpFBOID);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, model->getROI().width, 0, model->getROI().height, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, model->getROI().width, model->getROI().height);
errorCheck("Warp Context");
}
void drawModel(){
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslatef(0.0f, 0.0f, -3.0f);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();
}
void ARStuff(Mat& source){
ARContext();
Mat ip(pIndex.size(), 1, CV_32FC2, Scalar::all(0.0));
for(int i = 0; i < pIndex.size(); i++){
ip.at<Vec2f>(i) = Vec2f(shape->at(2*pIndex[i]), shape->at(2*pIndex[i]+1));
}
solvePose(ip);
drawModel();
Mat image(roi.height, roi.width, CV_8UC4, Scalar::all(0));
glReadPixels(0, 0, image.cols, image.rows, GL_BGRA, GL_UNSIGNED_BYTE, image.ptr());
namedWindow("ARout");
imshow("ARout", image);
waitKey();
WarpContext();
}
One more thing : when I destroy and rebuild my context (destroywindow + destroy FBO) it works. But there is 2 call to glewInit() here and it's too long for real time application.