How To Show The Mouse Cursor         Showing the mouse using CEGUI

This tutorial was created for Ogre version 1.0.1

See also: Intermediate Tutorial 3

This tutorial is to get the mouse working using CEGUI (Crazy Eddie’s GUI system). It has been created by copying code from the Demo_GUI sample into my own program, which is based on the ExampleRefAppApplication sample structure.

All these changes take place in the main source file, containing the example application class and main frame listener.

Getting the mouse to render

Copy the following across to your ‘createScene’ function. It initializes CEGUI, loads a mouse cursor, and sets the current cursor graphic:

// Initialize GUI
    mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000);
    mGUISystem = new CEGUI::System(mGUIRenderer);
    CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);
    
    // Load scheme and set up defaults
    CEGUI::SchemeManager::getSingleton().loadScheme( (CEGUI::utf8*)"TaharezLook.scheme");
    mGUISystem->setDefaultMouseCursor( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
    CEGUI::MouseCursor::getSingleton().setImage(CEGUI::System::getSingleton().getDefaultMouseCursor());

Add the following couple of members to your application class:

class MyGameApplication : public ExampleRefAppApplication
    {
    private:
        CEGUI::OgreCEGUIRenderer* mGUIRenderer;
        CEGUI::System* mGUISystem;

Add some constructor/destructor cleanup, and register the listener as a listener for mouse events:

MyGameApplication()
    : mGUIRenderer(0),
      mGUISystem(0),
    {    
        mEventProcessor->addMouseMotionListener(this);
        mEventProcessor->addMouseListener(this);
    }

    ~MyGameApplication() 
    {  
        if(mGUISystem)
        {
            delete mGUISystem;
            mGUISystem = 0;
        }
        if(mGUIRenderer)
        {
            delete mGUIRenderer;
            mGUIRenderer = 0;
        }
    }

Add the following includes next to the other includes at the top of the file:

// CEGUI INCLUDES
    #include <CEGUI/CEGUISystem.h>
    #include <CEGUI/CEGUILogger.h>
    #include <CEGUI/CEGUISchemeManager.h>
    #include "OgreCEGUIRenderer.h"

Add the following libs to your debug build (and the same, but without the ‘_d’ to release): CEGUIBase_d.lib OgreGUIRenderer_d.lib

Add the following two mouse listener base classes to the inheritance list of your frame listener:

class MyGameFrameListener : public ExampleRefAppFrameListener, public MouseMotionListener, public MouseListener

The listener is going to hold onto a pointer to the CEGUI:Renderer. So add a member variable for it:

private:
        CEGUI::Renderer* mGUIRenderer;

Then add a CEGUI:Renderer pointer and initialize the member in the constructor:

MyGameFrameListener(RenderWindow* win, CollideCamera* cam, CEGUI::Renderer* renderer)
        : ExampleRefAppFrameListener(win, cam , true, true),
          mGUIRenderer(renderer)
    {
    }

Then pass in a pointer to the listener in your createFrameListener function:

// Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new MyGameFrameListener(mWindow, mCamera, mGUIRenderer);
        mRoot->addFrameListener(mFrameListener);
    }

The listener is going to handle all the mouse events, and needs to implement a bunch of functions. Paste the following block of functions into your listener. Notice that the ‘mouseMoved’ handler is called by the Ogre input system and then feeds the mouse position delta into CEGUI.

// Mouse handler functions
    void mouseMoved (MouseEvent *e)
    {
        CEGUI::System::getSingleton().injectMouseMove(
                e->getRelX() * mGUIRenderer->getWidth(), 
                e->getRelY() * mGUIRenderer->getHeight());
        e->consume();
    }

    void mouseDragged (MouseEvent *e) 
    { 
        mouseMoved(e);
    }

    void mousePressed (MouseEvent *e)
    {
    //        CEGUI::System::getSingleton().injectMouseButtonDown(
    //          convertOgreButtonToCegui(e->getButtonID()));
        e->consume();
    }

    void mouseReleased (MouseEvent *e)
    {
    //        CEGUI::System::getSingleton().injectMouseButtonUp(
    //          convertOgreButtonToCegui(e->getButtonID()));
        e->consume();
    }

    void mouseClicked(MouseEvent* e) {}
    void mouseEntered(MouseEvent* e) {}
    void mouseExited(MouseEvent* e) {}
    // End of mouse handler functions

Hopefully, the mouse will now render when you run. You can now start to play with handlers and such to do what you want to do. I greatly recommend dissecting the Demo_GUI app for further understanding of CEGUI.

Troubleshooting

A general thing to try is to put a breakpoint inside the ‘mouseMoved (MouseEvent *e)’ handler function of your listener to check whether you’re actually feeding mouse movement info to CEGUI.


Check out this line:

mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, ST_INTERIOR);

This function defaults the scene type to Ogre::ST_GENERIC. If you’re using something other than this, you need to explicitly say which one you’re using, otherwise it will add the render listener to the generic renderer, which isn’t going to render. In the walkthrough above I left it to the default like it is in the sample.


The Ogre GUI sample doesn’t include the following line directly:

CEGUI::MouseCursor::getSingleton().setImage(CEGUI::System::getSingleton().getDefaultMouseCursor());

The GUI sample does something a little more complicated, as it changes the cursor depending on context. Without this line, it has a NULL pointer for the mouse texture and therefore doesn’t render it. This threw me for a little while.


Note the ‘true, true’ part of this frame listener base class initialization.

: ExampleRefAppFrameListener(win, cam , true, true),

This means that we want to use ‘buffered’ input of keyboard and mouse input. At the time or writing I still find this somewhat confusing. This is what the sample app did though. If you find your keys or mouse don’t work, you might want to dig into this.


I had two Ogre apps running at once. It seems that the one that runs first grabs all the mouse love. This stumped me for some time, my CEGUI mouse wasn’t moving, but then started working once I stopped the Ogre GUI sample which I’d left running.


It seems of little importance, but my application is based on the ExampleRefAppApplication class, while the Demo_GUI sample is based on ExampleApplication. I’ve not compared the source, but from what I’ve seen they’re at least similar.


Still stuck? Make OgreMain, OgreGUIRenderer and CEGUIBase part of your project so you can step in to them. To add CEGUIBase, you need to install the CEGUI source code. Note that the project files are called ‘BaseSystem’ instead of CEGUIBase.


If things aren’t rendering, put a breakpoint in this function:

void CEGUIRQListener::renderQueueStarted(Ogre::RenderQueueGroupID id, bool& skipThisQueue)

If the breakpoint isn’t hit then your listener isn’t registered properly in some way. If it is hit, then stepping down into it will allow you to see what’s going on.


I had problems with the wrong dll’s getting used, so you might try deleting or renaming them so you can track down which dll it’s loading. Also I found a minimally intrusive way of working was to make a post build command line action which copies the dlls from their build locations to my working directory. In MSVC land, this can be done in the project settings. The result is that you don’t need to modify any of the Ogre/CEGUI project files, and therefore upgrading to future versions of the sdk’s is will be easier.

NOTE FOR NEW USERS

if you are getting problems compiling this example make sure you added the following libraries on your compiler section:

-lCEGUIBase
-lCEGUIOgreRenderer