second window with PApplet and OscP5?

edited November 2017 in Library Questions

Hello, I'm trying to control a sketch using OSC from Max using the oscP5 library. I want two screens that have identical "players", differentiated by an argument in their constructor. I'm using the "extends PApplet" function to create the second window.

Each Player needs to see global variables that are updated from Max (as sometimes they need to refer to each other's sensor data). I can't seem to figure out where to put the OSC.plug code to make sure each of them gets updated – only the main window updates right now when I put that code within the main setup(), and it doesn't work if I duplicate that code within the second setup(). Do I need to be duplicating the data I'm sending from Max on a separate port, or is there something else I'm not getting? I'm not sure where I should be initializing the Player classes or OSC assignments.

Example of code below (main project has many more functions within the Player class, ie, more roles).

PWindow win;

import oscP5.*;
import netP5.*;

OscP5 osc0;

NetAddress FromMax;    

float sensor0, sensor1; //receive sensor values from Max

int role0, role1; //change modes

Player Player0, Player1;

public void settings(){
  size(800,600);
}

void setup(){
  win = new PWindow();
  Player0 = new Player(0);
  //set up OSC receives
  osc0 = new OscP5(this, 12000);
  FromMax = new NetAddress("127.0.0.1", 12000);
  osc0.plug(this, "oscrole0", "/role0");
  osc0.plug(this, "oscrole1", "/role1");
  osc0.plug(this, "oscsensor0", "/sensor0");
  osc0.plug(this, "oscsensor1", "/sensor1");
}

////First Window
void draw(){
  Player0.update(role0);
}

///Second Window
class PWindow extends PApplet {

  PWindow() {
    super();
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);

  }

  void settings() {
    size(800,600);
  }

  void setup() {
    Player1 = new Player(1);

  }

  void draw() {
  Player1.update(1);
  }
}
/////Player class - one on each screen.
class Player {

  int role;
  int playerNumber;
  float sensor;

  Player (int tempplayerNumber){
    playerNumber = tempplayerNumber;
  }

//  
  void update(int temprole){

  //update sensor
    if (playerNumber == 0){
      role = role0;
      sensor = sensor0; 
       }
    if (playerNumber == 1){
      role = role1;
      sensor = sensor1;
    }

    if (temprole == -1){
      background(0);
      fill(255);
      text(sensor,width/2,height/2);
    }
    if (temprole == 0){
      background(255);
      fill(0);
      text(sensor,width/2,height/2);
    }

    }
}

//reassign OSC plugs
void oscrole0(int oscrole0) {
  role0 = oscrole0;
}

void oscrole1(int oscrole1) {
  role1 = oscrole1;
}

void oscsensor0(float oscsensor0) {
  sensor0 = oscsensor0;
}

void oscsensor1(float oscsensor1) {
  sensor1 = oscsensor1;
}

Answers

  • edited November 2017

    Thanks for the references...they are helping but I'm still pretty confused. I'm at least getting OSC data into the second PApplet window, I think (which I can tell by where the NullPointerException OR "missing a pushMatrix()..." is thrown). It's like it doesn't recognize "width" or "height" designations for the second window even when I only call size() within settings(). I've tried a lot of different places to initialize the second version of the class.

    Help me understand accessing variables here...

    1 - the "osc0.plug()" method can only be run in setup(), so I would have to run it twice? One in each window's setup? Since they're both referencing global variables.

    2 - "global" variables before the first setup are accessible by both PApplets, but if I want "sub-global" variables available to the functions within the second applet I would declare them right after the open bracket for the PWindow class, but before the PWindow() function, right?

    3 - I want to declare the Player classes globally, but initialize within each "setup()"? Do I even want a setup() for the second window?

    I think it might have something to do with the fields updated by OSC being null on loading as you advise in the second thread you posted, so I gave them both an initial value in the global setup. That throws "missing a pushMatrix()..." error. Which I intuit is something along the lines of one instance of the class accessing the other?

    Here's kind of where I'm at now after going through your threads. Tried a lot of different things...

    SecondApplet sa = new SecondApplet();
    
        import oscP5.*;
        import netP5.*;
    
        OscP5 osc0 = new OscP5(this,12000);
    
        NetAddress FromMax = new NetAddress("127.0.0.1",12000);
    
        float sensor0, sensor1; //receive sensor values from Max
    
        int role0 = -1;
        int role1 = -1; //change modes
    
        Player Player0;
        Player Player1;
    
        void settings(){
          size(800,600);
          String[] switches = { "--sketch-path=" + sketchPath(), ""};
          runSketch(switches, sa);
        }
    
        void setup(){
          Player0 = new Player(0);
          //set up OSC receives
          osc0.plug(this, "oscrole0", "/role0");
          osc0.plug(this, "oscrole1", "/role1");
          osc0.plug(this, "oscsensor0", "/sensor0");
          osc0.plug(this, "oscsensor1", "/sensor1");
    
    
        }
    
        void draw(){
          Player0.update(role0);
        }
    
        class SecondApplet extends PApplet {
    
          void settings() {
            size(800,600);
          }
    
          void setup(){
          Player1 = new Player(1);
          }
          void draw() {
          Player1.update(role1);
          }
        }
    
        //reassign OSC plugs
        void oscrole0(int oscrole0) {
          role0 = oscrole0;
        }
    
        void oscrole1(int oscrole1) {
          role1 = oscrole1;
        }
    
        void oscsensor0(float oscsensor0) {
          sensor0 = oscsensor0;
        }
    
        void oscsensor1(float oscsensor1) {
          sensor1 = oscsensor1;
        }
    
        class Player {
    
          int role;
          int playerNumber;
          float sensor;
    
          Player (int tempplayerNumber){
            playerNumber = tempplayerNumber;
          }
    
        //  
          void update(int temprole){
    
          //update sensor
            if (playerNumber == 0){
              role = role0;
              sensor = sensor0; 
               }
            if (playerNumber == 1){
              role = role1;
              sensor = sensor1;
            }
    
            if (temprole == -1){
              background(0);
              fill(255);
              text(sensor,width/2,height/2);
            }
            if (temprole == 0){
              background(255);
              fill(0);
              text(sensor,width/2,height/2);
            }
    
            }
        }
    
  • Since you are creating a Java desktop application then you could try the G4P library as it provides support for multiple windows. This website provides info on using this library

  • Answer ✓

    Try this version. I have not tested the oscP5/net business. I just modified the handle to your windows.

    Kf

    SecondApplet sa = new SecondApplet();
    
    import oscP5.*;
    
    OscP5 osc0 = new OscP5(this, 12000);
    
    //NetAddress FromMax = new NetAddress("127.0.0.1",12000);
    
    float sensor0, sensor1; //receive sensor values from Max
    
    int role0 = -1;
    int role1 = -1; //change modes
    
    Player Player0;
    Player Player1;
    
    void settings() {
      size(800, 600);
      String[] switches = { "--sketch-path=" + sketchPath(), ""};
      runSketch(switches, sa);
    }
    
    void setup() {
      Player0 = new Player(this,0);
      //set up OSC receives
      osc0.plug(this, "oscrole0", "/role0");
      osc0.plug(this, "oscrole1", "/role1");
      osc0.plug(this, "oscsensor0", "/sensor0");
      osc0.plug(this, "oscsensor1", "/sensor1");
    }
    
    void draw() {
      Player0.update(role0);
    }
    
    class SecondApplet extends PApplet {
    
      void settings() {
        size(800, 600);
      }
    
      void setup() {
        Player1 = new Player(this,1);
      }
      void draw() {
        Player1.update(role1);
      }
    }
    
    //reassign OSC plugs
    void oscrole0(int oscrole0) {
      role0 = oscrole0;
    }
    
    void oscrole1(int oscrole1) {
      role1 = oscrole1;
    }
    
    void oscsensor0(float oscsensor0) {
      sensor0 = oscsensor0;
    }
    
    void oscsensor1(float oscsensor1) {
      sensor1 = oscsensor1;
    }
    
    class Player {
    
      int role;
      int playerNumber;
      float sensor;
      PApplet pa;
    
      Player (PApplet p,int tempplayerNumber) {
        pa=p;
        playerNumber = tempplayerNumber;
      }
    
      //  
      void update(int temprole) {
    
        //update sensor
        if (playerNumber == 0) {
          role = role0;
          sensor = sensor0;
        }
        if (playerNumber == 1) {
          role = role1;
          sensor = sensor1;
        }
    
        if (temprole == -1) {
          pa.background(0);
          pa.fill(255);
          pa.text(sensor, width/2, height/2);
        }
        if (temprole == 0) {
          pa.background(255);
          pa.fill(0);
          pa.text(sensor, width/2, height/2);
        }
      }
    }
    
Sign In or Register to comment.