conflicts between ofxFenster and OpenCv?

Hi , im using ofxFenster addon for having a secondary window. Basically i have a main window and i just need to duplicate it. I was ofxFenster and it works fine but when i duplicate a window that has camera input(with opencv) it just doesnt work. It duplicates the window but the windows are empty.
I been trying different options and the library works ok, only when i use opencv and camera input it doesnt work. I dont get any error when i compile it, it compiles and i get both window empty and i then i get a message in the ofTypes.h file in the following line:
virtual ~ofStyle(){}

the message i get is this:

Thread 1: program receive signl " EXC_BAD_ACCESS

Here i uploaded i image so you can see what i get.

Any idea what is happening and how can i solve this?

thanks!

hi

that’s rather strange. Expecially the location the EXEC_BAD_ACCESS is happening in.

Did you double check that your functions won’t get called twice? For example if you have an ofxFensterListener and you register it to the manager twice, update and draw will both be called twice. (not update once and draw twice, the way it should actually be)

Can you maybe post some more code? I guess it happens in setup()?

Did you also rebuild the whole project? I sometimes get really strange bad access on linux at the weirdest places. but after a rebuild they are always gone.

Hi underdog , here is the code.

if you have the variable “number_of_windows” set to 0 the program works fine. But when i try to have more windows the app crashes or i get empty screens.

please try the “number_of_windows = 0 ;” and then “number_of_windows = 1;” and you will notice the problem

any idea why is not working ofxFenster with camera input?

  
#include "ofMain.h"  
#include "testApp.h"  
#include "ofxFensterManager.h"  
#include "ofAppGlutWindow.h"  
  
//========================================================================  
int main( ){  
	ofSetupOpenGL(ofxFensterManager::get(), 1024,768, OF_WINDOW);			// <-------- setup the GL context  
  
	// this kicks off the running of my app  
	// can be OF_WINDOW or OF_FULLSCREEN  
	// pass in width and height too:  
	ofRunFensterApp(new testApp());  
}  
  
  

  
  
#include "testApp.h"  
  
  
ofColor	aColor;  
ofColor c;  
  
  
// for demonstrating adding any drawable object (that extends ofBaseDraw);  
ofVideoGrabber		vidGrabber;  
unsigned char * 	videoInverted;  
ofTexture			videoTexture;  
  
  
  
  
int number_of_windows = 2;  
  
bool	randomizeButton = true;  
  
ofPoint *points;  
ofPoint	v[300];  
  
  
  
int movieIndex = 0;   
  
//--------------------------------------------------------------  
void testApp::setup()  
{		  
	ofSetFrameRate(60);  
  
      
    videoIn.setDeviceID(2);  
      
      
    switch_gui = 0;  
    switch_track_color = 0;  
    switch_fondo  = 0;  
    ofBackground(0, 0, 0);  
	ofSetVerticalSync(true);  
      
  
      
    ////////  
      
    //ofEnableAlphaBlending();  
	camWidth = 1024;  
	camHeight = 768;  
      
    humbral = 165;  
	hCycle = 50;  
	  
	vFlip = false;  
	hFlip = true;  
      
      
    red = 250;  
    green = 0;  
    blue = 0;  
	  
	counter = 0;  
	  
	ofSetWindowShape(camWidth, camHeight);  
	  
	videoIn.setVerbose(true);  
	videoIn.initGrabber(camWidth,camHeight, GL_RGB);  
	entrada.allocate(camWidth,camHeight);  
	filtro.allocate(camWidth,camHeight);  
	film.allocate(camWidth, camHeight);  
    temporal.allocate(camWidth, camHeight);  
      
      
    bDrawDiagnostic = false;  
      
  
    //colorImg.allocate(camWidth,camHeight);  
    grayImage.allocate(1024,768);  
	grayBg.allocate(1024,768);  
	grayDiff.allocate(1024,768);  
      
	bLearnBakground = true;  
	threshold = 80;  
      
      
    graba  = 0;  
    switcher = 0;  
  
  
      
	int winW=1024;  
	for(int i=0; i<number_of_windows; i++) {  
		ofxFenster* win=ofxFensterManager::get()->createFenster(800+(i*winW), 0, winW, 768, OF_WINDOW);  
		win->addListener(new testApp());  
		win->setBackgroundColor(ofRandom(255), ofRandom(0), ofRandom(255));  
	}  
      
	//setup of fensterListener does not get called automatically yet  
	imgWin.setup();  
      
  
}  
  
  
//--------------------------------------------------------------  
void testApp::update()  
{  
      
    videoIn.grabFrame();  
	  
	if (videoIn.isFrameNew()){  
		entrada.setFromPixels(videoIn.getPixels(),camWidth,camHeight);  
		filtro = entrada;  
        updateFilm(filtro.getPixels());  
          
          
    }  
      
  
      
    bool bNewFrame = false;  
      
#ifdef _USE_LIVE_VIDEO  
      
    //cambiar videoIn por vidGrabber  
    //  videoIn.grabFrame();  
    bNewFrame = videoIn.isFrameNew();  
    //#else  
    //   vidPlayer.idleMovie();  
    // bNewFrame = vidPlayer.isFrameNew();  
#endif  
    if (bNewFrame){  
#ifdef _USE_LIVE_VIDEO  
        //entrada  
        entrada.setFromPixels(videoIn.getPixels(), 1024,768);  
  
#endif  
          
        grayImage = entrada;  
		if (bLearnBakground == true){  
			grayBg = grayImage;		// the = sign copys the pixels from grayImage into grayBg (operator overloading)  
			bLearnBakground = false;  
		}  
  
	}  
      
}  
  
  
  
void testApp::cleanFilm(){  
	unsigned char * filmPixels = temporal.getPixels();  
    int lenght = camWidth * camHeight * 3;  
      
    for( int i=0; i < lenght; i++ ) filmPixels[i] = 0;  
    temporal.setFromPixels( filmPixels, camWidth, camHeight );  
}  
  
  
  
  
void testApp::updateFilm(unsigned char *mskPixels){  
	unsigned char * filmPixels = temporal.getPixels();  
      
    int lenght = camWidth * camHeight * 3;  
	temporal.setFromPixels( filmPixels, camWidth, camHeight );  
  
}  
  
  
//--------------------------------------------------------------  
void testApp::draw()  
{  
  
    entrada.draw(0,0,ofGetWidth(),ofGetHeight());  
  
      
  
}  
  
  
  
  
  
  
  
//--------------------------------------------------------------  
void testApp::keyPressed(int key)  
{  
	if(key == 'c')  
		cout << "CLIPBOARD DATA: " << ofxFensterManager::get()->getClipboard() << endl;  
}  
  
//--------------------------------------------------------------  
void testApp::keyReleased(int key, ofxFenster* win)  
{  
	//cout << (0x0400) << endl;  
	//cout << (101 | OF_KEY_MODIFIER) << " " << key << endl;  
	if(key=='f')  
		win->toggleFullscreen();  
	if(key==' ')  
		ofxFensterManager::get()->createFenster(0, 0, 400, 300, OF_WINDOW)->addListener(&imgWin);  
  
  
  
    //Esto de abajo lo uso para cambiar entre camaras.  
    //funciona bien pero porque no lo puedo hacer con el gui en vez de con key?  
  
      
    if (key=='o') switcher = switcher + 1;  
      
    //este if le he agregado para poder grabar un archivo nuevo en vez de sobreescribir. funciona bien  
  
    switcher = switcher % 2;  
      
      
    if (key=='g') switch_gui = switch_gui + 1;  
    switch_gui = switch_gui % 2;  
  
  
  
}  
  
//this only works if testApp is extending ofxFensterListener and not ofBaseApp  
void testApp::mouseMoved(int x, int y, ofxFenster* win)  
{  
	  
}  
  
//--------------------------------------------------------------  
void testApp::mouseMoved(int x, int y)  
{  
	mousePos.set(x, y);  
}  
  
//--------------------------------------------------------------  
void testApp::mouseDragged(int x, int y, int button)  
{  
  
}  
  
//--------------------------------------------------------------  
void testApp::mousePressed(int x, int y, int button)  
{  
  
}  
  
//--------------------------------------------------------------  
void testApp::mouseReleased(int x, int y, int button)  
{  
  
}  
  
//--------------------------------------------------------------  
void testApp::windowResized(int w, int h)  
{  
  
}  
  
//--------------------------------------------------------------  
void testApp::gotMessage(ofMessage msg)  
{  
  
}  
  
//--------------------------------------------------------------  
void testApp::dragEvent(ofDragInfo dragInfo)  
{  
	cout << "GOT SOME FILES: "<<endl;  
	std::vector<string>::iterator it = dragInfo.files.begin();  
	while(it != dragInfo.files.end()){  
		cout << *it << endl;  
		++it;  
	}  
}  
  
void testApp::mouseMovedEvent(ofMouseEventArgs &args)  
{  
	//cout << "MOUSE WAS MOVED" << endl;  
}  
  
  
  

  
  
#pragma once  
  
#include "ofMain.h"  
#include "ofxFensterManager.h"  
  
  
#include "ofxOpenCv.h"  
  
  
  
  
class imageWindow: public ofxFensterListener {  
public:  
	~imageWindow() {  
		cout << "Image Listener destroyed" << endl;  
	}  
	void setup() {  
		cout << "LOADING IMAGE" << endl;  
		img.loadImage("someImage.JPG");  
	}  
	void draw() {  
		img.draw(0,0);  
	}  
  
	void keyReleased(int key, ofxFenster* window) {  
		if(key==' ')  
			ofxFensterManager::get()->deleteFenster(window);  
	}  
  
	ofImage img;  
};  
  
class boxWindow: public ofxFensterListener {  
public:  
	boxWindow() {  
		rotX = ofRandom(-20, 20);  
		rotY = ofRandom(-10, 10);  
	}  
  
	void draw() {  
		ofNoFill();  
		ofTranslate(ofGetWidth()*.5, ofGetHeight()*.5, 0);  
		ofRotateX(rotX);  
		ofRotateY(rotY);  
		ofBox(0, 0, 0, 100);  
	}  
  
	void mouseMoved(int x, int y) {  
		rotY = ofMap(x, 0, ofGetWidth(), -20, 20);  
		rotX = ofMap(y, 0, ofGetHeight(), 60, -60);  
	}  
  
	void dragEvent(ofDragInfo dragInfo) {  
		cout << "GOT SOME FILES: "<<endl;  
		std::vector<string>::iterator it = dragInfo.files.begin();  
		while(it != dragInfo.files.end()) {  
			cout << *it << endl;  
			++it;  
		}  
	}  
  
  
	float rotX;  
	float rotY;  
};  
  
class testApp : public ofxFensterListener {  
  
public:  
	void setup();  
	void update();  
	void draw();  
  
	void keyPressed  (int key);  
	void keyReleased(int key, ofxFenster* win);  
	void mouseMoved(int x, int y );  
	void mouseMoved(int x, int y, ofxFenster* win);  
	void mouseDragged(int x, int y, int button);  
	void mousePressed(int x, int y, int button);  
	void mouseReleased(int x, int y, int button);  
	void windowResized(int w, int h);  
	void dragEvent(ofDragInfo dragInfo);  
	void gotMessage(ofMessage msg);  
	void mouseMovedEvent(ofMouseEventArgs &args);  
  
	ofVec2f mousePos;  
	imageWindow imgWin;  
  
	ofxFenster* test;  
  
	int iconCount;  
      
      
      
      
      
      
      
      
      
    ofVideoGrabber			videoIn;  
	ofxCvColorImage			entrada;  
	ofxCvGrayscaleImage 	filtro;  
      
    ofxCvColorImage			temporal;  
	ofxCvColorImage			film;  
	  
	int		camWidth, camHeight;  
	int		humbral;  
	  
	bool	vFlip, hFlip;  
	int		counter;  
      
    int red;  
    int green;  
    int blue ;   
	  
	float	hCycle;  
	ofColor color;  
    // ofColor c;  
      
      
      
    ofImage img;  
    ofPoint firstpoint;  
	//ofxQtVideoSaver saver;  
    int graba ;  
    int switcher;   
      
      
    bool bDrawDiagnostic;  
      
    //#ifdef _USE_LIVE_VIDEO  
    //  ofVideoGrabber 		vidGrabber;  
    //#else  
    //  ofVideoPlayer 		vidPlayer;  
    //#endif  
      
      
    ofxCvColorImage		colorImg;  
    ofxCvGrayscaleImage 	grayImage;  
    ofxCvGrayscaleImage 	grayBg;  
    ofxCvGrayscaleImage 	grayDiff;  
      
    ofxCvContourFinder 	contourFinder;  
      
    int 				threshold;  
    bool				bLearnBakground;  
	int switch_gui ;   // esto es para hacer aparecer y desaparecer el gui  
	int switch_track_color ;   // esto es para hacer rastree el color y lo aplique al trail o no  
    int switch_fondo ; // esto es para prender y apagar el findo   
      
      
      
	void cleanFilm();  
	void updateFilm(unsigned char *pixels);  
	void superFastBlur(unsigned char *pix, int w, int h, int radius);  
	  
  
      
    void changeCamera  (int key);  
  
      
      
};  
  
  

Hi

adam

I think you error is here (line 93):

  
  
win->addListener(new testApp());    
  

You shouldn’t create a new testApp, but pass your existing one, if you want to draw the same content in different windows.

  
  
win->addListener(this);    
  

But keep in mind, that not only draw, but update will also be called multiple times.

Cool, It worked with :

win->addListener(this);

, but why creating a new testApp is not working here?

and when you say that draw and update is gonna be called multiple times, what do you mean?
each window is going to call that draw function as a individual entitiy? and what the problem with that? speed?
Which alternatives do i have?

thanks for you help

A.

Glad it worked

It would work with new testApp, but then you have to think about that you created a new testApp. So you’d have to call setup() again and entrada for example would not contain the same image as your original testApp does. It is not a copy but a completely new app that has nothing to do with the other testApp instances.

What I mean with calling update multiple times is that each time you register a fenster listener, draw and update will get called for each window.

You register a listener on window1, window2 and window3. That means draw will get called for each window once, because you want to draw it 3 times. But not only draw will get called for each window once, update will be called three times as well.

That’s actually a behavior I want to change, so it is guaranteed that update will only get called once per cycle. For now you can do something like defining a boolean like isUpdated.

  
  
class testApp: public ofxFensterListener{  
...  
bool isUpdated;  
}  
  
testApp::setup(){  
   isUpdated = false;  
}  
  
testApp::update(){  
   if(isUpdated)  
      return;  
   ....  
   isUpdated = true;  
}  
  
testApp::draw(){  
   ....  
   isUpdated = false;  
}  
  

hope that helps

Ph

Hi underdog , i ve tried what you said but it seems there still an error.
It seems the second window is calling the draw functions 2 times, because in my program i can notice a color difference between the second window and the first window.

For example if i add gl_blend in my draw function the second window appears with much more blending than the first window.

For example if i do:

  
  
  
class testApp: public ofxFensterListener{    
...    
bool isUpdated;    
}    
    
testApp::setup(){    
   isUpdated = false;    
}    
    
testApp::update(){    
   if(isUpdated)    
      return;    
   ....    
   isUpdated = true;    
}    
    
testApp::draw(){    
  
 glEnable(GL_BLEND);  
glBlendFunc (GL_SRC_ALPHA,GL_ONE);  
   film.draw(0,0,ofGetWidth(),ofGetHeight());  
  
   ....    
   isUpdated = false;    
}   
  
  
  
  

you are gonna get the second window with much blending that the first, it seems the secon window i calling the draw functions 2 times.
any idea why is this and how can i solve this?

thanks

A.

Hmm not sure what might be the reason for this. Are you 100% sure that draw gets called twice or could it just be that the opengl context was somehow not cleared correctly between the draws.

You could use cout to debug this.

  
  
update(){  
...      
cout << "UPDATE" << endl;  
}  
draw(){  
cout << "DRAW" << endl;  
}  
  

if you get something like

UPDATE
DRAW
DRAW
DRAW

then it should be behaving correctly and it is probably a bug within ofxFenster and OpenGL?

It seems im calling the draw function 2 times, because im getting this :

UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW …

but when i close my duplicated window i get this:

UPDATE
DRAW
UPDATE
DRAW
UPDATE
DRAW
UPDATE
DRAW
UPDATE
DRAW
UPDATE
DRAW
UPDATE
DRAW
UPDATE
DRAW
UPDATE
DRAW …

any idea?

Hmm. This means all your draws and updates get called correctly. So it might be that there really is something wonky going on in ofxFenster and openGL. Can you maybe post your draw? Then I can test it on my machine as well…

Underdoeg, theres something i dont understand , why do you say the draws and updates are called correctly?

when i have 2 windows im getting this:

UPDATE
DRAW
DRAW
UPDATE
DRAW
DRAW…

doesnt that means that each window is calling a draw function? It is not suppose that draw is just called one time from the first window?

my draw is just :

  
  
void testApp::draw()  
{  
  
    glEnable(GL_BLEND);    
    glBlendFunc (GL_SRC_ALPHA,GL_ONE);    
      
    entrada.draw(0,0,ofGetWidth(),ofGetHeight());  
  
      
  
}  
  
  
  

You are gonna see that the second window is different color than the first one. It seems its applying 2 times the blending function in the second window.

Adam

the update / draw sequence is correct. because to draw in two windows, you will have to call draw twice. Once for every window or it would be black…

I have tried to add your blending function to the ofxFensterExample

  
  
void draw() {  
		glEnable(GL_BLEND);      
		glBlendFunc (GL_SRC_ALPHA,GL_ONE);    
		img.draw(0,0);  
		img.draw(20, 20);  
}  
  

And they all blend correctly in each window. (attached image) Are you sure there is nothing else in your code that might alter the output?

ohhh, the problem was that your code have this:

win->setBackgroundColor(ofRandom(255), ofRandom(0), ofRandom(255));

deleting that line works everything ok.

thanks!

ah I see. that makes sense. glad it all worked out :slight_smile: