warping FBO problems

Hey all!!

I’m trying to do some projection mapping stuff and having the problem illustrated in the attached image…

I want to project onto a plane that’s not square to the projector, so I’m drawing to an FBO then drawing the FBO texture bound to a quad that defines the mapping. It works, but there’s a distortion in the texturing, as shown in the image - it looks like openGL is turning the quad into 2 triangles so there’s a definite line running diagonally through the image.

I really need to get a more accurate mapping of the texture to the quad. Is there a way to ask openGL to use nicer stretching or something? I’m using ofxFBOTexture if that makes any difference…

I hope someone can shed some light on this!

cheers

Marek

http://www.opengl.org/resources/code/samples/mjktips/projtex/distortion.txt; but the math for the ‘real’ way looks hard. just do the first option: break the quad up into a bunch of smaller ones, i found 10x10 worked nicely last time i tried to do this.

Ah, cool. Will give the quad subdivision thing a go tomorrow morning. Weird how there’s nothing built in to openGL for that. Such is life… Thanks for the answer!

might also want to look at quad warping,

using 4 control points, you can change the shape of your quad.
on that post theres two ways of doing it, using openCV and a pure math approach.

L.

Thanks. CPU bound stuff isn’t really an option as there’s too much stuff going on on there at the moment. I’ve done the 10 x 10 approach, which is yielding pretty good results (not perfect, see the attached file).

I’ve put the code that does it below in case it helps anyone, although I think I’m doing it a bit long windedly and totally, totally inefficiently.

``````

#define WARP_GRID_X 10
#define WARP_GRID_Y 10

// 4 corners of the quad
ofPoint points[4];

// warped grid coordinates
ofPoint grid[WARP_GRID_X+1][WARP_GRID_Y+1];

void generateGrid() {
for(int i = 0; i <= WARP_GRID_X; i++) {
for(int j = 0; j <= WARP_GRID_Y; j++) {
float xAmount = (float)i/WARP_GRID_X;
float yAmount = (float)j/WARP_GRID_Y;

float x = (points[0].x*(1.f-xAmount) + points[1].x*xAmount)*(1.f-yAmount)
+ (points[3].x*(1.f-xAmount) + points[2].x*xAmount)*yAmount;

float y = (points[0].y*(1.f-yAmount) + points[3].y*yAmount)*(1.f-xAmount)
+ (points[1].y*(1.f-yAmount) + points[2].y*yAmount)*xAmount;

grid[i][j] = ofPoint(x, y);
}
}
}

void drawFBO(ofxFBOTexture *fbo) {
if(gridIsDirty) { // only recalculate if it's changed
generateGrid();
gridIsDirty = false;
}

fbo->bind();
{
{

float xStep = fbo->getWidth()/WARP_GRID_X;
float yStep = fbo->getHeight()/WARP_GRID_Y;
for(int i = 0; i < WARP_GRID_X; i++) {
for(int j = 0; j < WARP_GRID_Y; j++) {
int revJ =  WARP_GRID_Y - j;
glTexCoord2f(i*xStep, revJ*yStep);					glVertex2f(grid[i][j].x, grid[i][j].y);
glTexCoord2f(i*xStep, (revJ-1)*yStep);				glVertex2f(grid[i][j+1].x, grid[i][j+1].y);
glTexCoord2f((i+1)*xStep, (revJ-1)*yStep);			glVertex2f(grid[i+1][j+1].x, grid[i+1][j+1].y);
glTexCoord2f((i+1)*xStep, revJ*yStep);				glVertex2f(grid[i+1][j].x, grid[i+1][j].y);
}
}
}
glEnd();
}
fbo->unbind();
}

``````

the method julapy post is not calculated in cpu, there’s one part that calculates a 4x4 matrix from the correspondance of the points, the calculations are pretty fast, in the order of microseconds, and once you have that everything else is done in cpu. haven’t tried the fbo aproach but can tell that the homography works really well.