Difference between revisions of "Using PyCEGUI with glfw3 and PyOpenGL (0.8)"

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search
(Mouse/KeyBoard Mappings)
(Main Loop)
Line 244: Line 244:
 
         elapsed = self.current_time - self.previous_time
 
         elapsed = self.current_time - self.previous_time
 
         self.previous_time = self.current_time
 
         self.previous_time = self.current_time
 
 
         # update GL/CEGUI
 
         # update GL/CEGUI
 
         self.updateGL()
 
         self.updateGL()
 
         self.updateCEGUI(elapsed)
 
         self.updateCEGUI(elapsed)
 
 
         # Swap front and back buffers
 
         # Swap front and back buffers
 
         glfw.glfwSwapBuffers(self.glfw_window)
 
         glfw.glfwSwapBuffers(self.glfw_window)
 
 
         # Handle glfw events
 
         # Handle glfw events
 
         glfw.glfwPollEvents()
 
         glfw.glfwPollEvents()

Revision as of 13:07, 27 March 2015

Written for CEGUI 0.8


Works with versions 0.8.x (stable)

Works with latest CEGUI stable!

Getting Started

For this example it is assumed that glfw3 and OpenGL are already installed. We will be using the bindings for python glfw3 from Nicolas P. Rougier. Download from git clone https://github.com/rougier/pyglfw.git and copy the file glfw.py to the directory you are running the demo from.

Importing Modules

If you have trouble importing the PyCEGUI libraries you can update your python path to point to the location of the modules. For Linux you can simply point to your CEGUI build_dir/lib.

   for _path in [os.path.join(s,'cegui-0.8') for s in site.getsitepackages()]:
       print _path
       sys.path.insert(0, _path)
   #sys.path.insert(0, "/media/sdb5/python-ogre-cegui/cegui-0.8/lib")

Setting Data Path

Set your path to the CEGUI media dir.

   CEGUI_PATH = "/media/sdb5/Libraries/OGRE/sdk/v1-9/share/cegui-0/"

Mouse/KeyBoard Mappings

   def ConvertMouseButton(button):
       ##Convert Mouse Buttons to CEGUI
       if (button == glfw.GLFW_MOUSE_BUTTON_RIGHT):
           return PyCEGUI.RightButton
       elif (button == glfw.GLFW_MOUSE_BUTTON_LEFT):
           return PyCEGUI.LeftButton
       elif (button == glfw.GLFW_MOUSE_BUTTON_MIDDLE):
           return PyCEGUI.MiddleButton
       else:
           return PyCEGUI.LeftButton

Copy the following keyboard mappings to keymappings_glfw3.py in same directory as the demo.

   import sys
   import glfw
   import PyCEGUI
   KEYMAPPINGS = {
       glfw.GLFW_KEY_UNKNOWN       : PyCEGUI.Key.Unknown, 
       glfw.GLFW_KEY_SPACE         : PyCEGUI.Key.Space,
       glfw.GLFW_KEY_APOSTROPHE    : PyCEGUI.Key.Apostrophe,
       glfw.GLFW_KEY_COMMA         : PyCEGUI.Key.Comma,
       glfw.GLFW_KEY_MINUS         : PyCEGUI.Key.Minus,
       glfw.GLFW_KEY_PERIOD        : PyCEGUI.Key.Period,
       glfw.GLFW_KEY_SLASH         : PyCEGUI.Key.Slash,
       glfw.GLFW_KEY_0             : PyCEGUI.Key.Zero,
       glfw.GLFW_KEY_1             : PyCEGUI.Key.One,
       glfw.GLFW_KEY_2             : PyCEGUI.Key.Two,
       glfw.GLFW_KEY_3             : PyCEGUI.Key.Three,
       glfw.GLFW_KEY_4             : PyCEGUI.Key.Four,
       glfw.GLFW_KEY_5             : PyCEGUI.Key.Five,
       glfw.GLFW_KEY_6             : PyCEGUI.Key.Six,
       glfw.GLFW_KEY_7             : PyCEGUI.Key.Seven,
       glfw.GLFW_KEY_8             : PyCEGUI.Key.Eight,
       glfw.GLFW_KEY_9             : PyCEGUI.Key.Nine,
       glfw.GLFW_KEY_SEMICOLON     : PyCEGUI.Key.Semicolon,
       glfw.GLFW_KEY_EQUAL         : PyCEGUI.Key.Equals,
       glfw.GLFW_KEY_A             : PyCEGUI.Key.A,
       glfw.GLFW_KEY_B             : PyCEGUI.Key.B,
       glfw.GLFW_KEY_C             : PyCEGUI.Key.C,
       glfw.GLFW_KEY_D             : PyCEGUI.Key.D,
       glfw.GLFW_KEY_E             : PyCEGUI.Key.E,
       glfw.GLFW_KEY_F             : PyCEGUI.Key.F,
       glfw.GLFW_KEY_G             : PyCEGUI.Key.G,
       glfw.GLFW_KEY_H             : PyCEGUI.Key.H,
       glfw.GLFW_KEY_I             : PyCEGUI.Key.I,
       glfw.GLFW_KEY_J             : PyCEGUI.Key.J,
       glfw.GLFW_KEY_K             : PyCEGUI.Key.K,
       glfw.GLFW_KEY_L             : PyCEGUI.Key.L,
       glfw.GLFW_KEY_M             : PyCEGUI.Key.M,
       glfw.GLFW_KEY_N             : PyCEGUI.Key.N,
       glfw.GLFW_KEY_O             : PyCEGUI.Key.O,
       glfw.GLFW_KEY_P             : PyCEGUI.Key.P,
       glfw.GLFW_KEY_Q             : PyCEGUI.Key.Q,
       glfw.GLFW_KEY_R             : PyCEGUI.Key.R,
       glfw.GLFW_KEY_S             : PyCEGUI.Key.S,
       glfw.GLFW_KEY_T             : PyCEGUI.Key.T,
       glfw.GLFW_KEY_U             : PyCEGUI.Key.U,
       glfw.GLFW_KEY_V             : PyCEGUI.Key.V,
       glfw.GLFW_KEY_W             : PyCEGUI.Key.W,
       glfw.GLFW_KEY_X             : PyCEGUI.Key.X,
       glfw.GLFW_KEY_Y             : PyCEGUI.Key.Y,
       glfw.GLFW_KEY_Z             : PyCEGUI.Key.Z,
       glfw.GLFW_KEY_LEFT_BRACKET  : PyCEGUI.Key.LeftBracket,
       glfw.GLFW_KEY_BACKSLASH     : PyCEGUI.Key.Backslash,
       glfw.GLFW_KEY_RIGHT_BRACKET : PyCEGUI.Key.RightBracket,
       glfw.GLFW_KEY_GRAVE_ACCENT  : PyCEGUI.Key.Grave,
       glfw.GLFW_KEY_WORLD_1       : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_WORLD_2       : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_ESCAPE        : PyCEGUI.Key.Escape,
       glfw.GLFW_KEY_ENTER         : PyCEGUI.Key.Return,
       glfw.GLFW_KEY_TAB           : PyCEGUI.Key.Tab,
       glfw.GLFW_KEY_BACKSPACE     : PyCEGUI.Key.Backspace,
       glfw.GLFW_KEY_INSERT        : PyCEGUI.Key.Insert,
       glfw.GLFW_KEY_DELETE        : PyCEGUI.Key.Delete,
       glfw.GLFW_KEY_RIGHT         : PyCEGUI.Key.ArrowRight,
       glfw.GLFW_KEY_LEFT          : PyCEGUI.Key.ArrowLeft,
       glfw.GLFW_KEY_DOWN          : PyCEGUI.Key.ArrowDown,
       glfw.GLFW_KEY_UP            : PyCEGUI.Key.ArrowUp,
       glfw.GLFW_KEY_PAGE_UP       : PyCEGUI.Key.PageUp,
       glfw.GLFW_KEY_PAGE_DOWN     : PyCEGUI.Key.PageDown,
       glfw.GLFW_KEY_HOME          : PyCEGUI.Key.Home,
       glfw.GLFW_KEY_END           : PyCEGUI.Key.End,
       glfw.GLFW_KEY_CAPS_LOCK     : PyCEGUI.Key.Capital,
       glfw.GLFW_KEY_SCROLL_LOCK   : PyCEGUI.Key.ScrollLock,
       glfw.GLFW_KEY_NUM_LOCK      : PyCEGUI.Key.NumLock,
       glfw.GLFW_KEY_PRINT_SCREEN  : PyCEGUI.Key.SysRq,
       glfw.GLFW_KEY_PAUSE         : PyCEGUI.Key.Pause,
       glfw.GLFW_KEY_F1            : PyCEGUI.Key.F1,
       glfw.GLFW_KEY_F2            : PyCEGUI.Key.F2,
       glfw.GLFW_KEY_F3            : PyCEGUI.Key.F3,
       glfw.GLFW_KEY_F4            : PyCEGUI.Key.F4,
       glfw.GLFW_KEY_F5            : PyCEGUI.Key.F5,
       glfw.GLFW_KEY_F6            : PyCEGUI.Key.F6,
       glfw.GLFW_KEY_F7            : PyCEGUI.Key.F7,
       glfw.GLFW_KEY_F8            : PyCEGUI.Key.F8,
       glfw.GLFW_KEY_F9            : PyCEGUI.Key.F9,
       glfw.GLFW_KEY_F10           : PyCEGUI.Key.F10,
       glfw.GLFW_KEY_F11           : PyCEGUI.Key.F11,
       glfw.GLFW_KEY_F12           : PyCEGUI.Key.F12,
       glfw.GLFW_KEY_F13           : PyCEGUI.Key.F13,
       glfw.GLFW_KEY_F14           : PyCEGUI.Key.F14,
       glfw.GLFW_KEY_F15           : PyCEGUI.Key.F15,
       glfw.GLFW_KEY_F16           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F17           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F18           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F19           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F20           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F21           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F22           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F23           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F24           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_F25           : PyCEGUI.Key.Unknown,
       glfw.GLFW_KEY_KP_0          : PyCEGUI.Key.Numpad0,
       glfw.GLFW_KEY_KP_1          : PyCEGUI.Key.Numpad1,
       glfw.GLFW_KEY_KP_2          : PyCEGUI.Key.Numpad2,
       glfw.GLFW_KEY_KP_3          : PyCEGUI.Key.Numpad3,
       glfw.GLFW_KEY_KP_4          : PyCEGUI.Key.Numpad4,
       glfw.GLFW_KEY_KP_5          : PyCEGUI.Key.Numpad5,
       glfw.GLFW_KEY_KP_6          : PyCEGUI.Key.Numpad6,
       glfw.GLFW_KEY_KP_7          : PyCEGUI.Key.Numpad7,
       glfw.GLFW_KEY_KP_8          : PyCEGUI.Key.Numpad8,
       glfw.GLFW_KEY_KP_9          : PyCEGUI.Key.Numpad9,
       glfw.GLFW_KEY_KP_DECIMAL    : PyCEGUI.Key.Decimal,
       glfw.GLFW_KEY_KP_DIVIDE     : PyCEGUI.Key.Divide,
       glfw.GLFW_KEY_KP_MULTIPLY   : PyCEGUI.Key.Multiply,
       glfw.GLFW_KEY_KP_SUBTRACT   : PyCEGUI.Key.Subtract,
       glfw.GLFW_KEY_KP_ADD        : PyCEGUI.Key.Add,
       glfw.GLFW_KEY_KP_ENTER      : PyCEGUI.Key.NumpadEnter,
       glfw.GLFW_KEY_KP_EQUAL      : PyCEGUI.Key.NumpadEquals,     
       glfw.GLFW_KEY_LEFT_SHIFT    : PyCEGUI.Key.LeftShift,
       glfw.GLFW_KEY_LEFT_CONTROL  : PyCEGUI.Key.LeftControl,
       glfw.GLFW_KEY_LEFT_ALT      : PyCEGUI.Key.LeftAlt,
       glfw.GLFW_KEY_LEFT_SUPER    : PyCEGUI.Key.LeftWindows,
       glfw.GLFW_KEY_RIGHT_SHIFT   : PyCEGUI.Key.RightShift,
       glfw.GLFW_KEY_RIGHT_CONTROL : PyCEGUI.Key.RightControl,
       glfw.GLFW_KEY_RIGHT_ALT     : PyCEGUI.Key.RightAlt,
       glfw.GLFW_KEY_RIGHT_SUPER   : PyCEGUI.Key.RightWindows,
       glfw.GLFW_KEY_MENU          : PyCEGUI.Key.AppMenu,
       glfw.GLFW_KEY_LAST          : PyCEGUI.Key.AppMenu
   }

Initialization glf3

   # Initialize glfw
   if not glfw.glfwInit():
       print (" Error : glfw failed to initialize")
       sys.exit (glfw.EXIT_FAILURE)

Window Hints

Glfw3 allows to define window hints prior to creation and hints about your OpenGL Context (OpenGL Version). Note the MAJOR/MINOR values are the minimum API version of the window context, i.e. if you graphics card supports GL 4.4 that is what will be returned.

GLFW_OPENGL_FORWARD_COMPAT (True) indicates that functionality deprecated in the requested version of OpenGL is removed.

For the sake of testing PyCEGUI's OpenGL render set:

 ceguiGL3Renderer(True)/ GLFW_OPENGL_FORWARD_COMPAT(True)   - OpenGL3Renderer without GL2.1
 ceguiGL3Renderer(True)/ GLFW_OPENGL_FORWARD_COMPAT(False)  - OpenGL3Renderer with    GL2.1
 ceguiGL3Renderer(False)                                    - OpenGLRenderer

   ceguiGL3Renderer = True
   if ceguiGL3Renderer:
       glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 3)
       glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 2)
       glfw.glfwWindowHint(glfw.GLFW_OPENGL_FORWARD_COMPAT, PyGL.GL_TRUE)
       glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_CORE_PROFILE)
   else:
       glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 2)
       glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 1)
       glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_ANY_PROFILE)


Creating Window

If you try to create a window with a context that you graphics card does not support glfwCreateWindow will fail. We also need to make our context current prior to creating our PyCEGUI renderer.

   glfw_window = glfw.glfwCreateWindow(1024, 768, "PyCEGUI glfw3 Demo", None, None)
   if not glfw_window:
       print (" Error : glfw failed to create a window")
       glfw.glfwTerminate()
       sys.exit()
   glfw.glfwMakeContextCurrent(glfw_window)

VSnyc

This does nothing on linux and is dependent on your card settings. For example with a NVidia card change settings with NVidia X Server Settings->OpenGL Settings->Sync to VBlank.

   glfw.glfwSwapInterval(0)

Callbacks

See the source for each of the following callbacks where we notify CEGUI of display size changes, mouse presses/movement, key presses and glfwSetCharCallback is our callback to pass the unicode char/key pressed to CEGUI.

   glfw.glfwSetKeyCallback(             glfw_window,  self.on_key)
   glfw.glfwSetMouseButtonCallback(     glfw_window,  self.on_mouse)
   glfw.glfwSetCursorPosCallback(       glfw_window,  self.on_move)
   glfw.glfwSetWindowSizeCallback(      glfw_window,  self.on_resize)
   glfw.glfwSetCharCallback(            glfw_window,  self.on_char_callback)
   glfw.glfwSetFramebufferSizeCallback( glfw_window,  self.on_framebuffer_size_callback)

PyCEGUI Renderer

Create our PyCEGUI renderer.

   if (not ceguiGL3Renderer):
       PyCEGUIOpenGLRenderer.OpenGLRenderer.bootstrapSystem()
   else :
       PyCEGUIOpenGLRenderer.OpenGL3Renderer.bootstrapSystem()


Main Loop

Our main loop runs until the glfw3 window is closed updating CEGUI, swapping the buffers and handling glfw events.

   def updateCEGUI(self, elapsed):
       ##CEGUI updates ###
       if (PyCEGUI.System.getSingleton()):
           PyCEGUI.System.getSingleton().injectTimePulse(elapsed)
           PyCEGUI.System.getSingleton().renderAllGUIContexts()
           self.labelFPS.setText("FPS : %s" %(str(int(1.0/elapsed))))
   while not glfw.glfwWindowShouldClose(self.glfw_window):
       PyGL.glClear(PyGL.GL_COLOR_BUFFER_BIT)
       # update timing
       self.current_time = glfw.glfwGetTime()
       elapsed = self.current_time - self.previous_time
       self.previous_time = self.current_time
       # update GL/CEGUI
       self.updateGL()
       self.updateCEGUI(elapsed)
       # Swap front and back buffers
       glfw.glfwSwapBuffers(self.glfw_window)
       # Handle glfw events
       glfw.glfwPollEvents()

Demo Source

This is the full source code for the demo, see above saving the keyboard mappings.

    # -- coding: utf-8 --
   import glfw
   import OpenGL.GL as PyGL
   import sys, os , site
   ## set the path of your PyCEGUI* modules
   for _path in [os.path.join(s,'cegui-0.8') for s in site.getsitepackages()]:
       print _path
       sys.path.insert(0, _path)
   sys.path.insert(0, "/media/sdb5/python-ogre-cegui/cegui-0.8/lib")
   ## set the path to our resource files
   CEGUI_PATH = "/media/sdb5/Libraries/OGRE/sdk/v1-9/share/cegui-0/"
   ## import our PyCEGUI and out glfw3 to cegui key mappings
   import PyCEGUI
   import PyCEGUIOpenGLRenderer
   from keymappings_glfw3 import *
   def ConvertMouseButton(button):
        Convert Mouse Buttons to CEGUI 
       if (button == glfw.GLFW_MOUSE_BUTTON_RIGHT):
           return PyCEGUI.RightButton
       elif (button == glfw.GLFW_MOUSE_BUTTON_LEFT):
           return PyCEGUI.LeftButton
       elif (button == glfw.GLFW_MOUSE_BUTTON_MIDDLE):
           return PyCEGUI.MiddleButton
       else:
           return PyCEGUI.LeftButton
   class Application(object):
       def __init__(self):
           # Initialize glfw
           if not glfw.glfwInit():
               print (" Error : glfw failed to initialize")
               sys.exit (glfw.EXIT_FAILURE)
           ceguiGL3Renderer = True
           if ceguiGL3Renderer:
               glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 3)
               glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 2)
               glfw.glfwWindowHint(glfw.GLFW_OPENGL_FORWARD_COMPAT, PyGL.GL_TRUE)
               glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_CORE_PROFILE)
           else:
               glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 2)
               glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 1)
               glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_ANY_PROFILE)
           # our window hints
           ## http://www.glfw.org/docs/latest/window.html
           ## set our framebuffer related hints
           glfw.glfwWindowHint(glfw.GLFW_DEPTH_BITS, 24)
           glfw.glfwWindowHint(glfw.GLFW_STENCIL_BITS, 8)
           glfw.glfwWindowHint(glfw.GLFW_FOCUSED, True)
           fullScreen = False
           # create window
           if (not fullScreen):
               glfw_window = glfw.glfwCreateWindow(1024, 768, "PyCEGUI glfw3 Demo", None, None)
           else:
               glfw_window = glfw.glfwCreateWindow(1024, 768, "PyCEGUI glfw3 Demo", glfw.glfwGetPrimaryMonitor(), None)
           # check window created
           if not glfw_window:
               print (" Error : glfw failed to create a window")
               glfw.glfwTerminate()
               sys.exit()
           self.glfw_window = glfw_window
           glfw.glfwMakeContextCurrent(glfw_window)
           self.showglfwInfo()
           ## this does nothing on linux
           glfw.glfwSwapInterval(0)
           glfw.glfwSetInputMode(glfw_window, glfw.GLFW_CURSOR, glfw.GLFW_CURSOR_HIDDEN)
           # call backs
           glfw.glfwSetKeyCallback(             glfw_window,  self.on_key)
           glfw.glfwSetMouseButtonCallback(     glfw_window,  self.on_mouse)
           glfw.glfwSetCursorPosCallback(       glfw_window,  self.on_move)
           glfw.glfwSetWindowSizeCallback(      glfw_window,  self.on_resize)
           glfw.glfwSetCharCallback(            glfw_window,  self.on_char_callback)
           glfw.glfwSetFramebufferSizeCallback( glfw_window,  self.on_framebuffer_size_callback)


           # initialise our CEGUI renderer
           ctx_major      = glfw.glfwGetWindowAttrib(glfw_window, glfw.GLFW_CONTEXT_VERSION_MAJOR)
           ctx_minor      = glfw.glfwGetWindowAttrib(glfw_window, glfw.GLFW_CONTEXT_VERSION_MINOR)
           forward_compat = glfw.glfwGetWindowAttrib(glfw_window, glfw.GLFW_OPENGL_FORWARD_COMPAT)
           if (not ceguiGL3Renderer):
               PyCEGUIOpenGLRenderer.OpenGLRenderer.bootstrapSystem()
           else :
               PyCEGUIOpenGLRenderer.OpenGL3Renderer.bootstrapSystem()


           # initialise PyCEGUI and resources
           rp = PyCEGUI.System.getSingleton().getResourceProvider()
        
           rp.setResourceGroupDirectory("schemes",    CEGUI_PATH + "schemes")
           rp.setResourceGroupDirectory("imagesets",  CEGUI_PATH + "imagesets")
           rp.setResourceGroupDirectory("fonts",      CEGUI_PATH + "fonts")
           rp.setResourceGroupDirectory("layouts",    CEGUI_PATH + "layouts")
           rp.setResourceGroupDirectory("looknfeels", CEGUI_PATH + "looknfeel")
           rp.setResourceGroupDirectory("schemas",    CEGUI_PATH + "xml_schemas")
        
           PyCEGUI.ImageManager.setImagesetDefaultResourceGroup("imagesets")
           PyCEGUI.Font.setDefaultResourceGroup("fonts")
           PyCEGUI.Scheme.setDefaultResourceGroup("schemes")
           PyCEGUI.WidgetLookManager.setDefaultResourceGroup("looknfeels")
           PyCEGUI.WindowManager.setDefaultResourceGroup("layouts")
           parser = PyCEGUI.System.getSingleton().getXMLParser()
           if parser.isPropertyPresent("SchemaDefaultResourceGroup"):
               parser.setProperty("SchemaDefaultResourceGroup", "schemas")     
           # Load schemes
           PyCEGUI.SchemeManager.getSingleton().createFromFile("TaharezLook.scheme")
           PyCEGUI.SchemeManager.getSingleton().createFromFile("WindowsLook.scheme")
           PyCEGUI.System.getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("TaharezLook/MouseArrow")
        
           # set root window
           root = PyCEGUI.WindowManager.getSingleton().createWindow("DefaultWindow", "background_wnd");
           root.setArea( PyCEGUI.UVector2(PyCEGUI.UDim(0.0, 0),PyCEGUI.UDim(0.0, 0)) ,PyCEGUI.USize(PyCEGUI.UDim(1.0, 0),PyCEGUI.UDim(1.0, 0)))
           PyCEGUI.System.getSingleton().getDefaultGUIContext().setRootWindow(root)
           # load a layout
           layout = PyCEGUI.WindowManager.getSingleton().loadLayoutFromFile("TextDemo.layout")
           root.addChild(layout.getChild('TextDemo'))
           self.edit = root.getChild('TextDemo/MultiLineGroup/editMulti')
           # create label for our FPS
           self.labelFPS = PyCEGUI.WindowManager.getSingleton().createWindow("TaharezLook/Label", "FPSLabel")
           root.addChild(self.labelFPS)
           # create hello button
           button = PyCEGUI.WindowManager.getSingleton().createWindow("TaharezLook/Button", "HelloButton")
           button.setArea( PyCEGUI.UVector2(PyCEGUI.UDim(.50, 0),PyCEGUI.UDim(.92, 0)) ,PyCEGUI.USize(PyCEGUI.UDim(0.3, 0),PyCEGUI.UDim(0.05, 0)))
           button.setText("Hello")
           root.addChild(button)
           button.subscribeEvent(PyCEGUI.PushButton.EventClicked, self.OnbuttonClicked)
           # init simple timing
           self.previous_time = glfw.glfwGetTime()
           self.current_time  = self.previous_time


       def showglfwInfo(self):
           ctx_major      = glfw.glfwGetWindowAttrib(self.glfw_window, glfw.GLFW_CONTEXT_VERSION_MAJOR)
           ctx_minor      = glfw.glfwGetWindowAttrib(self.glfw_window, glfw.GLFW_CONTEXT_VERSION_MINOR)
           forward_compat = glfw.glfwGetWindowAttrib(self.glfw_window, glfw.GLFW_OPENGL_FORWARD_COMPAT)
           print "Created Window for OpenGL version %d.%d " % ( ctx_major, ctx_major )
           if ( ctx_major >=3 and forward_compat):
               print "Context is forward compatible, you can't use OpenGL 2.x commands" 
           fwidth,fheight = glfw.glfwGetFramebufferSize(self.glfw_window)
           width, height =  glfw.glfwGetWindowSize(self.glfw_window)
    
           print "Framebuffer size %dx%d Window size %dx%d " % (fwidth,fheight, width,height) 
       def OnbuttonClicked(self, args):
           self.edit.setText(self.edit.getText() + "You Clicked")
           return
       def cleanUp(self):
            shutdown glfw and CEGUI 
           PyCEGUIOpenGLRenderer.OpenGLRenderer.destroySystem()
           glfw.glfwTerminate()
       def updateGL(self):
            glfw GL updates 
           pass
       
       def updateCEGUI(self, elapsed):
            CEGUI updates 
           #focused = glfw.glfwGetWindowAttrib(glfw_window, glfw.GLFW_CONTEXT_VERSION_MAJOR)
           if (PyCEGUI.System.getSingleton()):
               PyCEGUI.System.getSingleton().injectTimePulse(elapsed)
               PyCEGUI.System.getSingleton().renderAllGUIContexts()
               self.labelFPS.setText("FPS : %s" %(str(int(1.0/elapsed))))
       def mainLoop(self):
            Loop until glfw window is closed 
           while not glfw.glfwWindowShouldClose(self.glfw_window):
               PyGL.glClear(PyGL.GL_COLOR_BUFFER_BIT)
               # update timing
               self.current_time = glfw.glfwGetTime()
               elapsed = self.current_time - self.previous_time
               self.previous_time = self.current_time
               # update GL/CEGUI
               self.updateGL()
               self.updateCEGUI(elapsed)
               # Swap front and back buffers
               glfw.glfwSwapBuffers(self.glfw_window)
               # Handle glfw events
               glfw.glfwPollEvents()


       def on_framebuffer_size_callback(self,window,width,height):
            the framebuffer on high-DPI monitors may differ from the screen co-ords, so notify display size change here 
           PyGL.glViewport(0, 0, width, height)
           if ( PyCEGUI.System.getSingleton()):
               PyCEGUI.System.getSingleton().notifyDisplaySizeChanged(PyCEGUI.Sizef(float(width), float(height) ))
       def on_move(self, window, x,y):
            pass glfw mouse moves to CEGUI 
           if ( PyCEGUI.System.getSingleton()):
               PyCEGUI.System.getSingleton().getDefaultGUIContext().injectMousePosition(x, y)
       def on_resize(self, window, width,height):
            resize glfw viewport and CEGUI display 
           PyGL.glViewport(0, 0, width, height)
           if ( PyCEGUI.System.getSingleton()):
               PyCEGUI.System.getSingleton().notifyDisplaySizeChanged(PyCEGUI.Sizef(float(width), float(height) ))
       def on_mouse(self, window, button, action, mods):
            pass glfw mouse press events to CEGUI 
           if ( PyCEGUI.System.getSingleton()):
               context = PyCEGUI.System.getSingleton().getDefaultGUIContext()
               if (action == glfw.GLFW_PRESS):
                   context.injectMouseButtonDown( ConvertMouseButton(button) )
               if (action == glfw.GLFW_RELEASE):
                   context.injectMouseButtonUp( ConvertMouseButton(button) )
       def on_char_callback(self, window, code):
            Unicode character callback function to CEGUI 
           PyCEGUI.System.getSingleton().getDefaultGUIContext().injectChar(code)
       def on_key(self, window, key, scancode, action, mods):
            pass keypress events to CEGUI 
           if PyCEGUI.System.getSingleton():
               cegui_key = KEYMAPPINGS[key]
               if (not cegui_key==PyCEGUI.Key.Unknown):
                   if (action == glfw.GLFW_PRESS):
                       PyCEGUI.System.getSingleton().getDefaultGUIContext().injectKeyDown(PyCEGUI.Key.Scan(cegui_key))
                   if (action == glfw.GLFW_RELEASE):
                       PyCEGUI.System.getSingleton().getDefaultGUIContext().injectKeyUp(PyCEGUI.Key.Scan(cegui_key))
           ## exit
           if key == glfw.GLFW_KEY_ESCAPE and action == glfw.GLFW_PRESS:
               glfw.glfwSetWindowShouldClose(window,1)
   if __name__ == '__main__':
       app = Application()
       app.mainLoop()
       app.cleanUp()
       del app

And here is the link for the formatted source