Skip to content


Repository files navigation

#Most-Pixels-Ever for Cinder

A Cinder block client for Most Pixels Ever, supporting Mac, Windows and iOS.

Most Pixels Ever is a framework that synchronizes frame-based applications across multiple screens. Read more about the project:

A video of the sample desktop application:
A video of the sample iOS application running on 2 iPads:

###Example Usage:

For step-by-step instructions on creating a MPE app with XCode, read the tutorial:

#####The Server

A basic MPE 2.0 server is included with the block. Run like so:

$ python mpe-python-server/

#####Your Cinder App

Here's the basic setup required to integrate an MPE Client with your Cinder app.
You can generate your project from this template using TinderBox.

// Subclass your Cinder app from MPEApp

class MyCinderApp : public App, public MPEApp
    void        setup();    
    void        update();
    void        draw();
    // Override functions found in MPEApp
    void        mpeReset();
    void        mpeFrameUpdate(long serverFrameNumber);
    void        mpeFrameRender(bool isNewFrame);
    void        mpeMessageReceived(const std::string & message, const int fromClientID);
    MPEClientRef    mClient;      
    Rand            mRand;
    BouncyBall      mBall;

void MyCinderApp::setup()
    // By default, the client is be configured using assets/settings.xml.
    // The settings filename is changed by overriding MPEApp::mpeSettingsFile(). 
    // Each client needs a unique settings file.
    // Pass a pointer to an MPEApp (e.g. MyCinderApp) into the client constructor.
    mClient = MPEClient::create(this);

void MyCinderApp::update()
    // Connect the client if we're not already.
    // Nothing else needs to happen in update().
    // Updating the App state happens in mpeFrameUpdate().
    if (!mClient->isConnected() && getElapsedFrames() % 60 == 0)
        // Attempt to reconnect every 60 frames.

void MyCinderApp::draw()
    // App drawing should happen in mpeFrameRender(). 

// functions overridden from MPEApp

void MyCinderApp::mpeReset()
    // This is called whenever a new client joins the loop.
    // All state and history should be cleared as if the app 
    // was just launched. This will be called by the client
    // after it connects to the server.
    // This will create the same "random" position each reset because the 
    // seed is hardcoded to 1.
    ivec2 sizeMaster = mClient->getMasterSize();
    mBall.position = vec2(mRand.nextFloat(sizeMaster.x), mRand.nextFloat(sizeMaster.y))
    mBall.velocity = vec2(mRand.nextFloat(-5,5), mRand.nextFloat(-5,5));

void MyCinderApp::mpeFrameUpdate(long serverFrameNumber)
    // This is where the app state should be modified. 
    // The FrameUpdateCallback is called whenever we get a message from the server,
    // which may be less frequently than update() or draw() is called.    

void MyCinderApp::mpeFrameRender(bool isNewFrame)
    // The viewport is automatically translated by the client so each
    // machine is only drawing a segment of the scene.

void MyCinderApp::mpeMessageReceived(const std::string & message, const int fromClientID)
    // Apps can broadcast data to the other clients. E.g.:
    // mClient->sendMessage("mouse_pos: 100,200");

    ci::app::console() << "Client " << fromClientID 
                       << " sent broadcast message: " << message << std::endl;

CINDER_APP( MyCinderApp, RendererGl )


Cinder block for Most Pixels Ever big-screens framework