ofxBezierWarp second warp object - GL Problem?

Hi List,

for all of you who don’t know it: ofxBezierWarp is a most incredible Addon helping you to warp and map videos. Thank you blainer_s and gameover for this incredible work!

In my new project I want to use a second ofxBezierWarp object. As soon as I allocate it (even when not updating/drawing), the first one is disturbed. See an example here:

This is simplified code from the example, only sizes has been adjusted and added a second object.
ofApp.h:

#pragma once

#include "ofMain.h"
#include "ofxBezierWarp.h"

class ofApp : public ofBaseApp {

public:
	void setup();
	void update();
	void draw();

	ofVideoPlayer vid;

	ofxBezierWarp warp;
	ofxBezierWarp warp2;

};

ofApp.cpp:

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup() {
	vid.loadMovie("videos/Timecoded_Big_bunny_2.mov");
	vid.play();

	warp.allocate(800, 600, 5, 4, 80);
	warp.setShowWarpGrid(true);
	warp2.allocate(400,700, 5, 4, 80); // without this line, everything is fine!
	ofBackground(0, 0, 0);
}

//--------------------------------------------------------------
void ofApp::update() {
	vid.update();
	warp.begin();
	vid.draw(0, 0, ofGetWidth(), ofGetHeight());
	warp.end();
}

//--------------------------------------------------------------
void ofApp::draw() {
	warp.draw(40,40);
}

Seems to be some GL Problem to me, so I’m lost.
Is there a way to adapt the code to be able to use multiple warp objects?

thanks for every hint!
oe

I found a solution. When (re-)setting warp grid resolution before drawing all will be good:

Not that I really understand what’s happening, I am not so deep into GL. But for every warp object I seem to need to call glMapGrid2f() (which is happening in setWarpGridResolution()) before going to call glMap2f(); to create the surface I will map to (which is happening in draw()). Does that make sense? I don’t know, but it works.

have a good day!
oe


In case you want to follow (or even explain?): the following things are happening regarding GL:

in allocate():

setWarpGrid(_numXPoints, _numYPoints);

//set up texture map for bezier surface
glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, &texpts[0][0][0]);
glEnable(GL_MAP2_TEXTURE_COORD_2);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);

setWarpGridResolution(pixelsPerGridDivision);

Here following two functions are called
in setWarpGrid():

glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, numXPoints, 0, 1, numXPoints * 3, numYPoints, &(cntrlPoints[0]));

in setWarpGridResolution():

glMapGrid2f(gridDivX, 0, 1, gridDivY, 0, 1);

in begin():

fbo.begin();
ofPushMatrix();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);

in end():

ofPopMatrix();
fbo.end();

in draw():

    ofTexture & fboTex = fbo.getTextureReference();
    
    // upload the bezier control points to the map surface
    // this can be done just once (or when control points change)
    // if there is only one bezier surface - but with multiple
    // it needs to be done every frame
    glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, numXPoints, 0, 1, numXPoints * 3, numYPoints, &(cntrlPoints[0]));
    
    fboTex.bind();
    
    glMatrixMode(GL_TEXTURE);
    glPushMatrix();
    glLoadIdentity();
    glScalef(fboTex.getWidth(), fboTex.getHeight(), 1.0f);
    glMatrixMode(GL_MODELVIEW);
    
    fboTex.unbind();
    
    glMatrixMode(GL_TEXTURE);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);