osc message between update() and draw()

Hello

I’m making simple graphics which follows monome’s button.
monome is 64 button box outputting osc messages.

So I programmed simple osc receiver using ofxOsc.
The osc message gets to update() stage fine but not to draw() stage.
I checked using ‘printf’ in update() stage to make sure every osc message
received.
However, if I checked in draw() stage, it’s missing sometimes especially when
I press buttons fast.
Thus some buttons left on.

This is .h file

  
  
class testApp : public ofBaseApp{  
  
	public:  
		void setup();  
		void update();  
		void draw();  
  
		void keyPressed  (int key);  
		void keyReleased(int key);  
		void mouseMoved(int x, int y );  
		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);  
private:  
	  
	ofxOscReceiver receiver;  
	int monome[3];  
  
};  
  

and .cpp file

  
  
#include "testApp.h"  
  
#define ROW 8  
#define COLUMN 8  
  
float pos[ROW][COLUMN][3];  
float col[ROW][COLUMN][4];  
  
float grey = 0.6;  
float white = 1.0;  
  
int pointSize = 40;  
  
//--------------------------------------------------------------  
void testApp::setup(){  
	receiver.setup( PORT );  
	ofSetFrameRate(60);  
	ofBackground(0, 0, 0);  
	  
	for(int i=0; i<COLUMN; i++){  
		for(int j=0; j<ROW; j++){  
			pos[i][j][0] = i*pointSize+pointSize;  
			pos[i][j][1] = j*pointSize+pointSize;  
			pos[i][j][2] = 0;  
  
			col[i][j][0] = grey;  
			col[i][j][1] = grey;  
			col[i][j][2] = grey;  
			col[i][j][3] = 1.0;  
		}  
	}  
	monome[0] = 0;  
	monome[1] = 0;  
	monome[2] = 0;  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
	while(receiver.hasWaitingMessages())  
	{  
		ofxOscMessage m1;  
		receiver.getNextMessage(& m1);  
		  
		if(m1.getAddress() == "/osc/press")  
		{  
			if(m1.getArgAsInt32(1) != 7)  
			{  
				monome[0] = m1.getArgAsInt32(0);  
				monome[1] = m1.getArgAsInt32(1);  
				monome[2] = m1.getArgAsInt32(2);  
			}  
		}  
		printf("received osc is %d, %d, %d \n", monome[0],   
			   monome[1], monome[2]);  
	}  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	if (monome[2] == 1) {  
		col[monome[0]][monome[1]][0] = white;  
		col[monome[0]][monome[1]][1] = white;  
		col[monome[0]][monome[1]][2] = white;  
	}  
	else{  
		col[monome[0]][monome[1]][0] = grey;  
		col[monome[0]][monome[1]][1] = grey;  
		col[monome[0]][monome[1]][2] = grey;  
	}  
	  
	ofSetColor(0xFFFFFF);  
	  
	glEnable(GL_DEPTH_TEST);  
	//glEnable(GL_BLEND);  
	//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA);  
	glPointSize(pointSize);  
	glBegin(GL_POINTS);  
	for(int i=0; i<COLUMN; i++) {  
		for(int j=0; j<ROW; j++){  
		glColor4f(col[i][j][0], col[i][j][1], col[i][j][2], col[i][j][3]);  
		glVertex3f(pos[i][j][0], pos[i][j][1], pos[i][j][2]);  
		}  
	}  
	glEnd();  
	glDisable(GL_DEPTH_TEST);	  
  
}  
  

I’m not sure what exactly happening between update() and draw().
As I remember, I read somewhere that update() always does his work right
before draw().
So I think if that’s correct, the osc message should get to draw() stage correctly.

Any help will be much appreciated.

thanks
jin

when doing this in update:

  
monome[0] = m1.getArgAsInt32(0);  
monome[1] = m1.getArgAsInt32(1);  
monome[2] = m1.getArgAsInt32(2);  

you’re getting the values of 1 osc message but since you’re using a while to read through all the available messages:

  
while(receiver.hasWaitingMessages())  
   {...  

if more than 1 message arrive in an update/draw cycle, you’re overwriting and only getting the last one.

you need to store all of them in a vector or something similar and then draw all of them instead of just one:

testApp.h

  
vector<int[3]> monome_msgs;  

testApp.cpp

  
  
update(){  
monome_msgs.clear();  
while(receiver.hasWaitingMessages())  
...  
int monome[3];  
monome[0] = m1.getArgAsInt32(0);  
monome[1] = m1.getArgAsInt32(1);  
monome[2] = m1.getArgAsInt32(2);  
monome_msgs.push_back(monome);  
...  
}  
  
  
draw(){  
for(int i=0;i<monome_msgs.size();i++){  
int monome[3] = monome_msgs[i];  
//do the original draw here  
}  
}  
  

OK I see
.thank you

Just for test, I tried after removing while{
…}. It worked.
But since update() handles one osc message at a frame in this way, there is latency.
That’s ok though because I can press buttons that fast

.anyway

I tried your method.
First time I compilled, I got error in draw().
Below is one error of 7 errors

  
  
int monome[3] = monome_msg[i];  
  
error: array must be initialized with a brace-enclosed initializer  
  

So I tried this and above error removed.
But the other 6 remained.

  
  
int monome[3];  
monome[0] = monome_msg[i][0];  
monome[1] = monome_msg[i][1];  
monome[2] = monome_msg[i][2];  
  
error: ISO C++ forbids initialization in array new  
error: array must be initialized with a brace-enclosed initializer  
error: invalid array assignment  
error: invalid array assignment  
error: invalid array assignment  
error: ISO C++ forbids initialization in array new  
  
  

I get the idea but I am not 100% sure how to implement.

thanks
jin

ok, instead of an array, it will be easier if you use an struct to store each message, declare it in your .h:

  
struct monome{  
   int m_0;  
   int m_1;  
   int m_2;  
}  

then the vector:

  
  
vector<monome> monome_msgs;  

to store messages in update:

  
  
monome msg;  
  
msg.m_0=m1.getArgAsInt32(0);  
msg.m_1=m1.getArgAsInt32(1);  
msg_m_2=m1.getArgAsInt32(2);  
  
monome_msgs.push_back(msg);  

and to access them in draw:

  
for(int i=0;i<monome_msgs.size();i++){  
monome msg = monome_msgs[i];  

Cool…it works thank you so much.

What about monome_msgs.clear()?
Weren’t those messages piled up in vector array?

thank you
jin

I put monome_msgs.clear() at the very end of draw().

It works very charming.

Thanks Arturo!