FBO / Context resize

Hi,

I use 2 FBO to realize AR with OpenCV. So I do my rendering stuff, and call glReadPixels to load in my cv::Mat.
-The first is to warp some textures and work well. The size here is fixed depending on my statistic training model.
-The second is to apply transformations on a model. The size here change for every frame depending on my ROI on the image.

Here is my problem : The 2nd FBO always have the same size as the first. I know it because when i read the buffer… Well it’s not good. But when I read the buffer in a matrix of the size of the first FBO it’s OK.

I use win7x64 with VS2010, an OpenCV window
Here is the code to switch the fbo :



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");
}


I don’t have any opengl error… Is there some trick to resize a context ?

EDIT ::
Oh ok. It’s noted.

The FBO1 always have a smaller size, but it’s also 32bit floating point data on 1 channel (GL_R32F).
FBO2 is 4Channels usigned bytes (GL_RGBA). I don’t copy from one to another FBO.

here is a screenshot :
[ATTACH=CONFIG]420[/ATTACH]

For the moment I only draw a red rectangle and not my 3D model.
Here is the code to draw and read :



void AAMFitter::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 AAMFitter::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();
}


If I read the buffer in a matrix of the FBO1’s size I have a square.

[ATTACH=CONFIG]421[/ATTACH]

The square is red, and I don’t have any data type error. So the FBO is changed or I would have some weird things.
The GL_BGRA is because of OpenCV storing data in BGRA.

Is there some trick to resize a context ?

First of all, you don’t resize a context. When talking FBOs, you resize the their attachments - which you do for the second FBO. Cann you post some screenshots of the incorrect outcomes? Also, can you show the code to read the second FBO? Do you need to copy anything from FBO1 (fixed-size) to FBO2? Is the size of FBO2 always <= size of FBO1?

BTW, statements like this are completely wasted:

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, poseFBO);

If you call glBindFrameBuffer(), any previous binding will be replaced if the call succeeds, which it does in your case all the time (given your FBO is complete), so calling glBindFramebuffer(GL_FRAMEBUFFER, 0) right before the second call is simply wasted. It doesn’t really impact your performance if you do that a few times per frame but it’s simply not useful at all. Generally, unbinding something is done to prevent mistakenly altering the state of a currently bound object. So if you want to be sure you don’t screw the state of something up at an inappropriate place, do something like:



void someFunction() // doesn't matter if free function or member function
{
  // possibly some stuff here

  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  // do stuff with the fbo
  glBindFramebuffer(GL_FRAMEBUFFER, 0);

  // possibly some stuff here
}

The same goes for everything else you need to bind to modify.