VIZ++ Class: OpenGLApplet

 VIZ++ Class Library  VIZ++ Samples  VIZ++ ClassTree 

Source code

/*
 * OpenGLApplet.h 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


#pragma once

#include <viz++/Object.h>
#include <viz++/Exception.h>
#include <viz++/opengl/OpenGLObject.h>
#include <viz++/opengl/OpenGLIView.h>

namespace VIZ {
  
class OpenGLApplet :public OpenGLObject {
public:
  typedef enum {
    POLL_EVENTS,
    WAIT_EVENTS
  } EVENT_MODEL;
  
private:
  
  EVENT_MODEL model;
  GLboolean doubleBuffering;
  
  OpenGLIView* view;
  bool looping;

private:
public:
  static OpenGLApplet& getApplet(OpenGLApplet* applet=NULL)
  {
    static OpenGLApplet* singleton = NULL;
    if (applet) {
      if (singleton == NULL) {
        singleton = applet;
      } else {
        //If singleton were not NULL, throw -1
        MessageBox(NULL, "Cannot create multiple instances for Application class",
             "VIZ++", MB_ICONERROR|MB_OK);
        throw -1;
      }
    }
    return *singleton;
  }


  static void errorCallback(int err, const char* description)
  {
    fprintf(stderr, "Error: %d %s\n", err, description);
  }

public:
  OpenGLApplet(EVENT_MODEL model = POLL_EVENTS)
  :model(model),
  doubleBuffering(GL_TRUE),
  view(NULL),
  looping(true)
  {
    getApplet(this);

    glfwSetErrorCallback(&OpenGLApplet::errorCallback);
    if (!glfwInit()) {
      throw IException("Failed to glfwInit");
    }
    //Set this pointer as a singleton by calling getApplet().
  }

public:
  OpenGLApplet(int argc, char** argv, EVENT_MODEL model = POLL_EVENTS)
  :model(model),
  doubleBuffering(GL_TRUE),
  view(NULL),
  looping(true)
  {
    getApplet(this);

    glfwSetErrorCallback(&OpenGLApplet::errorCallback);

    if (!glfwInit()) {
      throw IException("Failed to glfwInit");
    }
    setArg(argc, argv);
  }

  ~OpenGLApplet()
  {
    glfwTerminate();
  }

  //Please define your own setArg method in your subclass derived from this class.
  virtual void setArg(int argc, char** argv)
  {
    //Do something.
  }

  void setWindow(OpenGLIView* view)
  {
     this -> view = view;
     //view -> setCallbacks();
  }

  OpenGLIView* getView()
  {
    return this -> view;
  }
  
  void setDoubleBuffering(GLboolean flag)
  {
    //GL_TRUE or GL_FALSE 
    glfwWindowHint( GLFW_DOUBLEBUFFER, flag ); 
    this -> doubleBuffering = flag;
  }
  
  virtual void run()
  {
    if (view) {
      view -> initialize();
      
      while (looping) {
        if (view->shouldClose()) {
          break;
        }
        view -> reshape();
        view -> idle();
        view -> display();
      
        //Is double buffering?
        if (doubleBuffering == GL_TRUE) {
          view -> swapBuffers();
        } else {
          glFlush();
        }
        
        //Call pollEvents or waitEvents.
        if (model == POLL_EVENTS) {  
          pollEvents();
        } else {
          waitEvents();
        }
      } //while
    } else {
      throw IException("OpenGLMainView is NULL");
    }
  }
  
public:
  void terminate()
  {
    looping = false;
  }

public:
  //Processes all pending events. 
  void  pollEvents () 
  {
    glfwPollEvents ();
  }
  
  //Waits until events are queued and processes them.   
  void  waitEvents () 
  {
    glfwWaitEvents ();
  }
  
  //Posts an empty event to the event queue.   
  void  postEmptyEvent ()
  {
    glfwPostEmptyEvent (); 
  }
};

}


Last modified: 10 Feb 2017

Copyright (c) 2009-2017 Antillia.com ALL RIGHTS RESERVED.