Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

OpenCV + OpenGL context resizing

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 :

image description

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.