Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

multiple windows with glfw

Using GLFW
imran
2012-07-29
2012-11-08
  • imran
    imran
    2012-07-29

    I have a problem related to client server programming . I want to create
    multiple windows created by glfw These windows have the same 3D environment
    but different views (Virtual reality).

    I want to clear things before posting the code.

    1. I have an application running where i have one window by glfw and I want
    to create 4 camera views (4 clients)

    2. My client is supposed to be on the same computer on which I have the
    server. i will give server Ip as
    127.0.0.1 meaning a local server on the same computer on which i will have 4
    camera views (4 clients).

    3. I create a client and I can see the camera view in that client. For
    example right, left or forward.

    My main.cpp looks like this

    #include "stdafx.h"
    #include "DemoApp.h"
    #include "GLFW/glfw.h"
    #include <iostream>
    #ifdef MEMORYCHECK
    #include <vld.h>
    #endif
    static int width = 1024;
    static int height = 768;
    static DemoApp* app = 0x0;
    static bool running = false;
    static bool fullScreen = false;
    const char* sceneFile = 0; 
    bool setupWindow( int, int, bool );
    // GLFW Callback functions
    int windowCloseListener()
    {
        running = false;
        return 0;
    }
    void  mouseMoveListener( int x, int y )
    {
        if( !running )  return;
        app->mouseMoved(x, y);
    }
    void  resizeCb(int w, int h)
    {
        if( !running ) return;
        app->resize(w, h);
        width=w; height=h;
    }
    void  mouseButtonListener(int button, int action)
    {
        if( !running )  return;
        app->mouseClick(button, action);
    }
    void  keyPressListener( int key, int action )
    {
        if( !running ) return;
        if( key == GLFW_KEY_ESC )
        {
            running = false;
            return;
        }
        switch( action )
        {
        case GLFW_PRESS:
            app->keyPressed( key, true);
            break;
        case GLFW_RELEASE:
            app->keyPressed( key, false);
            break;
        }
    }
    bool setupWindow( int width, int height, bool fullscreen )
    {
        // Create OpenGL window
        if( !glfwOpenWindow( width, height, 8, 8, 8, 8, 24, 8, fullscreen ? GLFW_FULLSCREEN : GLFW_WINDOW ) )
        {
            glfwTerminate();
            return false;
        }
        if (!fullscreen)
            glfwSetWindowTitle("Cave");
    
        // Disable vertical synchronization
        glfwSwapInterval(0);
    
        return true;
    }
    int main(int argc, char ** argv)
    {
        if (argc < 2)
        {
            glfwOpenWindow( 800, 16, 8, 8, 8, 8, 24, 8, GLFW_WINDOW );
            glfwSetWindowTitle( "You have to specify a GameEngine file as argument" );
            double startTime = glfwGetTime();
            while( glfwGetTime() - startTime < 5.0 ) {}  // Sleep
    
            std::cout << "You have to specify a GameEngine file as argument" << std::endl;
            glfwTerminate();
            return -1;
        }
        //- Initialize GLFW
        glfwInit();
        if( fullScreen )
        {
            GLFWvidmode mode;
            glfwGetDesktopMode( &mode );
    
            // Use desktop resolution
            width = mode.Width; height = mode.Height;
        }
        if( !setupWindow( width, height, fullScreen ) ) return -1;  
        sceneFile = argv[1];
        //- Initalize application and engine
        app = new DemoApp();
        if ( !app || !app->init(argv[1]) )
        {
            // Fake message box
            glfwCloseWindow();
            glfwOpenWindow( 800, 16, 8, 8, 8, 8, 24, 8, GLFW_WINDOW );
            glfwSetWindowTitle( "Unable to initalize engine - Make sure you have an OpenGL 2.0 compatible graphics card" );
            double startTime = glfwGetTime();
            while( glfwGetTime() - startTime < 5.0 ) {}  // Sleep
    
            std::cout << "Unable to initalize engine" << std::endl;
            std::cout << "Make sure you have an OpenGL 2.0 compatible graphics card";
            delete app;
            glfwTerminate();
            return -1;
        }
        // Set listeners
        glfwSetWindowCloseCallback(windowCloseListener);
        glfwSetKeyCallback(keyPressListener);
        glfwSetMousePosCallback(mouseMoveListener);
        glfwSetWindowSizeCallback(resizeCb); 
        glfwSetMouseButtonCallback(mouseButtonListener);
        running = true;
        resizeCb(width, height);
        //glfwDisable( GLFW_MOUSE_CURSOR );
        // Game loop
        while( running )
        {
            // Render
            app->render();
            glfwSwapBuffers();
        }
        //glfwEnable( GLFW_MOUSE_CURSOR );
        // Quit
        delete app;
        glfwTerminate();
        return 0;
    }
    

    My DemoApp.cpp looks like this

    #include "stdafx.h"
    #include "DemoApp.h"
    #include <GLFW/glfw.h>
    #include <gl/gl.h>
    using namespace Horde3D;
    DemoApp::DemoApp() : m_running(true)
    {
        memset(m_keys, 0, sizeof(m_keys));
        memset(m_stepHistory, 0, sizeof(m_stepHistory));
        m_character = UINT_MAX;
        m_networkState = "Not connected.";
        m_spectator = false;
        m_spectatorNum = 0;
        m_networkStarted = false;
        waypoints[0] = Vec3f(-8.0f, 0, -8.0f);
        waypoints[1] = Vec3f(-8.0f, 0, 8.0f);
        waypoints[2] = Vec3f(8.0f, 0, 8.0f);
        waypoints[3] = Vec3f(8.0f, 0, -8.0f);
        m_frameCount = 0;
        m_historyCounter = 0;
        m_currentWaypoint = -1;
        sensorON = false; 
    }
    DemoApp::~DemoApp()
    {
        GameEngine::release();
    }
    void DemoApp::startServer()
    {
        // only once
        if (m_networkStarted)
            return;
        m_networkStarted = true;
        GameEngine::registerCallbackOnClientConnect(NetworkApp::clientConnectCb);
        GameEngine::registerCallbackOnClientDisconnect(NetworkApp::clientDisconnectCb);
        /*
        GameEngine::registerComponentOnServer("Player1", "Horde3D");
        //GameEngine::registerComponentOnServer("Player1", "KeyframeAnimComponent");
        //GameEngine::registerComponentOnServer("Player1", "Sound3D");
        GameEngine::registerComponentOnServer("Player2", "Horde3D");
        GameEngine::registerComponentOnServer("Player2", "KeyframeAnimComponent");*/
        //GameEngine::registerComponentOnServer("Player2", "Sound3D");
        //GameEngine::registerComponentOnServer("Player3", "Horde3D");
        //GameEngine::registerComponentOnServer("Player3", "KeyframeAnimComponent");
        //GameEngine::registerComponentOnServer("Player3", "Sound3D");
        //GameEngine::registerComponentOnServer("Player4", "Horde3D");
        //GameEngine::registerComponentOnServer("Player4", "KeyframeAnimComponent");
        //GameEngine::registerComponentOnServer("Player4", "Sound3D");
        //GameEngine::registerComponentOnServer("Player5", "Horde3D");
        //GameEngine::registerComponentOnServer("Player5", "KeyframeAnimComponent");
        //GameEngine::registerComponentOnServer("Player5", "Sound3D");
        //GameEngine::registerComponentOnServer("Player6", "Horde3D");
        //GameEngine::registerComponentOnServer("Player6", "KeyframeAnimComponent");
        //GameEngine::registerComponentOnServer("Player6", "Sound3D");
        //GameEngine::registerComponentOnServer("Player7", "Horde3D");
        //GameEngine::registerComponentOnServer("Player7", "KeyframeAnimComponent");
        //GameEngine::registerComponentOnServer("Player7", "Sound3D");
        GameEngine::disconnect();
        GameEngine::startServer();
        m_networkState = "Server running.";
    }
    void DemoApp::startClient(const char* character, int spectator)
    {
        // only once
        if (m_networkStarted){
        cout<<"Zulqarnain imran";
    
        if(spectator > 0)
        {
            cout<<"Zulqarnain";
            m_spectator = true;
            m_character = GameEngine::entityWorldID("Hans");
            m_spectatorNum = spectator;
            h3dSetupCameraView(GameEngine::entitySceneGraphID(m_camID),73.7f,4.0f / 3.0f, 0.1f, 1000.0f);
        }
        else
        {   
            cout<<"Zulqarnain Elseeeeeeeeeeeee";
            m_character = GameEngine::entityWorldID(character);
            m_NPC = GameEngine::entityWorldID("Marie");
        }
        const char* serverip = "127.0.0.1";
        m_networkStarted = true;
        if(!m_spectator)
        {
            //typedef _W64 unsigned int cameraAbduallah_ID;
    
            m_camID = GameEngine::entityWorldID("camera");
    
            GameEngine::registerCallbackOnClientConnect(NetworkApp::clientConnectCb);
            string entityID = "Hans";
            setupStepper();
        }
        GameEngine::disconnect();
        GameEngine::connectToServer(serverip);
        m_networkState = new char[50];
        sprintf(m_networkState, "Client running. Server IP = %s", serverip);
        }
        else
        {return;}
    }
    bool DemoApp::init(const char *fileName)
    {
        if (!GameEngine::init()) return false;
    
        if (GameEngine::loadScene(fileName))
        {
            m_camID = GameEngine::entityWorldID("camera");
            m_camRX =0;
            m_camRY =0;
    
            _fontMatRes = h3dAddResource( H3DResTypes::Material, "overlays/font.material.xml", 0 );
            _logoHordeMatRes = h3dAddResource( H3DResTypes::Material, "overlays/logo.material.xml", 0 );
            //_logoSesamMatRes = h3dAddResource( H3DResTypes::Material, "overlays/logo2.material.xml", 0 );
            h3dutLoadResourcesFromDisk( "." );
            return true;
        }
        else
            return false;   
    }
    void DemoApp::keyHandler()
    {       
        m_running = m_keys[27] == 0; // quit application on ESC
        if( m_keys[GLFW_KEY_F7] )  // F7
        {
            h3dSetOption( H3DOptions::DebugViewMode, h3dGetOption(H3DOptions::DebugViewMode) != 0.0f ? 0.0f : 1.0f );   
            m_keys[GLFW_KEY_F7] = 0;
        }
        if ( m_keys['1'] ) {
            startClient("Hans", 0);
        }
    
        if ( m_keys['2'] ) {
            startClient("ObserverFront", 1);
    
            //cout<<"You Pressed 2 I m in this section of observing Front";
        }
    
        if ( m_keys['3'] ) {
            startClient("ObserverRight", 2);
            //cout<<"You Pressed 3 I m in this section of observing Right";
        }
    
        if ( m_keys['4'] ) {
            startClient("ObserverBack", 3);
            //cout<<"You Pressed 4 I m in this section of observing Back";
        }
    
        if ( m_keys['5'] ) {
            startClient("OberverLeft", 4);
            //cout<<"You Pressed 5 I m in this section of observing Left";
        }
    
        if ( m_keys['6'] ) {
            startClient("Marie", 0);
        }
        if ( m_keys['7'] ) {
            startClient("Hans", 0);
        }
        if( m_keys['X'] ){
            startServer();
        cout<<"Now i am in X Server";
        }
        if( m_keys[' '] ){
            sensorON = !sensorON;
            m_keys[' '] = 0;
        }
        if (m_keys[27])
        {   // Esc
            GameEngine::disconnect();
            m_running = false;
        }
        if (m_character == UINT_MAX)
            return;
        if (m_spectator)
            return;
        if( m_keys['U'] )
        {
            m_currentWaypoint = 0;
        }
    
        if( m_keys['J'] ) {
            if (!GameEngine::isPlaying(m_NPC, "wave")) {
                GameEngine::playAnim(m_NPC, "wave", 0 , 1.0, 3.0, 30.0, 0);
                GameEngine::setSoundGain(m_NPC, 1.0f);
            }
        }
        if( m_keys['K'] )
        {
            Matrix4f trans(GameEngine::getEntityTransformation(m_character));
            if( !GameEngine::isPlaying( m_character, "walk") )  {
            GameEngine::playAnim( m_character, "walk", 0, 1.0f, -1.0f, 30.0f, 0.0f );  }
            Vec3f t, r, s;
            trans.decompose(t, r, s);
    
            printf("%f, %f\n", t.x, t.z);
        }
    }
    void DemoApp::mouseClick(int button, int action)
    {
    }
    void DemoApp::updateNPC()
    {
    
    }
    bool DemoApp::waypointReached()
    {
    
    }
    //Function to  be removed
    void DemoApp::turnToWaypoint()
    {
    
    }
    //Function to  be removed 
    void DemoApp::walkToWaypoint()
    {
    
    }
    void DemoApp::updateCamera()
    {
        if (m_character == UINT_MAX)
            return;
        Matrix4f trans(GameEngine::getEntityTransformation(m_character));
        Vec3f t, r, s;
        trans.decompose(t, r, s);
        if(m_spectator)
        {
            t.y += 2;
            float rotYOffset = 0.0f;
            if(m_spectatorNum == 1)
                rotYOffset =  - 270.0f;
            else if(m_spectatorNum == 2)
                rotYOffset =  0.0f;
            else if(m_spectatorNum == 3)
                rotYOffset =  - 90.0f;
            else if(m_spectatorNum == 4)
                rotYOffset =  - 180.0f;
            GameEngine::setEntityTranslation(m_camID, t.x, t.y, t.z);
            //GameEngine::setEntityRotation(m_camID, 0,r.y / Math::Pi * 180.0f - rotYOffset , 0);
            GameEngine::setEntityRotation(m_camID, 0, rotYOffset , 0);
        }
        else
        {
            t.y += 2;
            t.x -= 2 * sin(r.y);
            t.z -= 2 * cos(r.y);
            GameEngine::setEntityTranslation(m_camID, t.x, t.y, t.z);
            GameEngine::setEntityRotation(m_camID, -10, r.y / Math::Pi * 180.0f - 180.0f, 0);
        }
    
    }
    void DemoApp::mouseMoved(float x, float y)
    {
    }
    void DemoApp::render()
    {
        keyHandler();
    
        //m_frameCount++;
        //if(m_frameCount / GameEngine::FPS() > 1.0f)
        //{
        if(m_character != UINT_MAX && sensorON == true) 
            {
                //int angle = hismodgametrak_getAngle();
                //printf("Steering angle: %d\n",angle);
                //GameEngine::setEntityRotation(m_character,0,angle - 90,0);
                readFromStepper(); //a good idea is to use a key to start reading from sensor
    
                if(checkStepHistory())
                    GameEngine::translateEntityLocal(m_character, 0, 0, 0.8f);
    
                //m_frameCount = 0;
            }
        //}
    
        updateCamera();
        updateNPC();
    
        h3dutShowText( m_networkState, 0.01f, 0.02f, 0.03f, 1, 1, 1, _fontMatRes );
    
        GameEngine::update();
        glDisable(GL_DEPTH_TEST);
        drawReticle();
        glEnable(GL_DEPTH_TEST);
    
        h3dutDumpMessages();
    }
    void DemoApp::keyPressed(unsigned int param, bool pressed)
    {   
        m_keys[param] = pressed ? 1 : 0 ;
    }
    void DemoApp::resize(int width, int height)
    {
    
    }
    void DemoApp::keyboardCb(unsigned int param, bool pressed, void *userData)
    {
    
    }
    void DemoApp::mouseCb(float x, float y, void *userData)
    {
    
    }
    void DemoApp::renderCb(void *userData)
    {
    
    }
    void DemoApp::resizeCb(void *userData, int width, int height)
    {   
        DemoApp* app = static_cast<DemoApp*>(userData);
        H3DNode camID = GameEngine::entitySceneGraphID( app->m_camID );
        h3dSetNodeParamI( camID, H3DCamera::ViewportXI, 0 );
        h3dSetNodeParamI( camID, H3DCamera::ViewportYI, 0 );
        h3dSetNodeParamI( camID, H3DCamera::ViewportWidthI, width );
        h3dSetNodeParamI( camID, H3DCamera::ViewportHeightI, height );  
        h3dResizePipelineBuffers( h3dGetNodeParamI( camID, H3DCamera::PipeResI ), width, height );
    }
    void DemoApp::drawSquare(float xMid, float yMid, float zMid, float yRot, float sideLength, bool fill)
    {
        float sinY = sin(yRot);
        float cosY = cos(yRot);
    
        xMid += 2 * sinY;
        zMid += 2 * cosY;
    
        float halfLength = sideLength * 0.5f;
        if (fill)
        {
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            glBegin(GL_POLYGON);
        }
        else
        {
            glBegin(GL_LINE_STRIP);         
        }
    
        glVertex3f(xMid - halfLength * cosY, yMid-halfLength, zMid + halfLength * sinY);
        glVertex3f(xMid - halfLength * cosY, yMid+halfLength, zMid + halfLength * sinY);
        glVertex3f(xMid + halfLength * cosY, yMid+halfLength, zMid - halfLength * sinY);
        glVertex3f(xMid + halfLength * cosY, yMid-halfLength, zMid - halfLength * sinY);
    
        glEnd();
    }
    void DemoApp::drawReticle()
    {
        if (m_character == UINT_MAX || !m_spectator)
            return;
        Matrix4f trans(GameEngine::getEntityTransformation(m_character));
        Vec3f t, r, s;
        trans.decompose(t, r, s);
        t.y += 2;
        //t.x += 2 * sin(r.y);
        //t.z += 2 * cos(r.y);
    
        glLineWidth(1.5f);
        glColor3f(1.0f, 0.5f, 0.0f);
    
        drawSquare(t.x,t.y,t.z,r.y,0.05f,true);
    }
    void DemoApp::setupStepper()
    {
    }
    void DemoApp::readFromStepper()
    {
    
    }
    bool DemoApp::checkStepHistory()
    {
    
    }
    

    Demoapp.h

    //Whre i have all headers
    

    Now problem, according to this application whn i am pressing a key for example
    2 then my client starts but it starts in the same while the previous view is
    not there .I want that as soon as i start my client it should start in new
    window . I want this camera view to be viewed in a separate window so this is
    how i will have all my four clients connected to the server. If I will create
    4 windows then i can see four different views in 4 different windows. In
    simple terms according to vitrtual reality we see on front camera view
    whatever is infront of virtual agent. on the right of the camera view i would
    see wht is on the right side of the virtual agent similarly all four views
    will have thier respective views.

    I saw in this code that as in main it is creating a window i can create the
    window as soon as i connect a client but if I am doing this, it doesn't allow
    me to create a window it gives an error on run time of Assertion failed at the
    time of connection of the client that I want to connect (for example On
    pressing key 2).

    So what possibly can be stopping me from creating a new window?

     
  • Camilla Löwy
    Camilla Löwy
    2012-07-29

    GLFW 2.7.x only supports one window.