How to show the Mouse Cursor W/O CEGUI

From Ogre Wiki

Jump to: navigation, search

Contents

How to show the Mouse Cursor W/O CEGUI

CEGUI is great for many things, but is just a bit too much for my application. I have seen this question asked in the forums a number of times and the answer is either "Use CEGUI" or "It shouldn't be hard to do this with a Panel" without more help for the poor newbie (like me).

Here is how I make a mouse cursor without resorting to CEGUI, using the example framework (somewhat).

First Way: If you want the mouse cursor always stay in the render window and to use your own image you can use following.

Initial Construction:

       mMouseCursor = new MouseCursor();
       mMouseCursor->setImage("entis.png");
       mMouseCursor->setVisible(true);
       mMouseCursor->setWindowDimensions(win->getWidth(), win->getHeight());

Update mouse position when needed:

       mMouseCursor->updatePosition(mMouse->getMouseState().X.abs, mMouse->getMouseState().Y.abs);

Update window dimensions when needed:

       mMouseCursor->setWindowDimensions(rw->getWidth(), rw->getHeight());

Sample program : MouseCursor.zip

MouseCursor.h

#ifndef __MOUSECURSOR_H__
#define __MOUSECURSOR_H__

#include <OgrePanelOverlayElement.h>

using namespace Ogre;

class MouseCursor
{
private:
    Overlay* mGuiOverlay;
    OverlayContainer* mCursorContainer;
    TexturePtr mTexture;
    MaterialPtr mMaterial;

    Real mWindowWidth;
    Real mWindowHeight;

public:
    MouseCursor(): mGuiOverlay(0), mCursorContainer(0)
    {
        mMaterial = MaterialManager::getSingleton().create("MouseCursor/default", "General");
        mCursorContainer = (OverlayContainer*) OverlayManager::getSingletonPtr()->createOverlayElement("Panel", "MouseCursor");
        mCursorContainer->setMaterialName(mMaterial->getName());
        mCursorContainer->setPosition(0, 0);

        mGuiOverlay = OverlayManager::getSingletonPtr()->create("MouseCursor");
        mGuiOverlay->setZOrder(649);
        mGuiOverlay->add2D(mCursorContainer);
        mGuiOverlay->show();
    }

    ~MouseCursor(void) {}

    void setImage(const String& filename)
    {
        mTexture = TextureManager::getSingleton().load(filename, "General");

        TextureUnitState *pTexState;
        if(mMaterial->getTechnique(0)->getPass(0)->getNumTextureUnitStates())
        {
            pTexState = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0);
        }
        else
        {
            pTexState = mMaterial->getTechnique(0)->getPass(0)->createTextureUnitState( mTexture->getName() );
        }
        pTexState->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
        mMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
    }

    void setWindowDimensions(unsigned int width, unsigned int height) {
        mWindowWidth = (width > 0) ? width : 1;
        mWindowHeight = (height > 0) ? height : 1;

        mCursorContainer->setWidth(mTexture->getWidth() / mWindowWidth);
        mCursorContainer->setHeight(mTexture->getHeight() / mWindowHeight);
    }

    void setVisible(bool visible)
    {
        if(visible) {
            mCursorContainer->show();
        } else {
            mCursorContainer->hide();
        }
    }

    void updatePosition(int x, int y)
    {
        Real rx = x / mWindowWidth;
        Real ry = y / mWindowHeight;
        mCursorContainer->setPosition(clamp(rx, 0.0f, 1.0f), clamp(ry, 0.0f, 1.0f));
    }

    Real clamp(Real a, Real min, Real max) {
        if (a < min) {
            return min;
        }
        if (a > max) {
            return max;
        } 
        return a;
    }
};

#endif

Main.cpp

#include "ExampleApplication.h"
#include "MouseCursor.h"

class MCFrameListener : public ExampleFrameListener
{
private :
    MouseCursor* mMouseCursor;
public:
    MCFrameListener(RenderWindow* win, Camera* cam)
        : ExampleFrameListener(win, cam), mMouseCursor(0)
    {
        mMouseCursor = new MouseCursor();
        mMouseCursor->setImage("entis.png");
        mMouseCursor->setVisible(true);
        mMouseCursor->setWindowDimensions(win->getWidth(), win->getHeight());
    }

    bool frameStarted(const FrameEvent& evt)
    {
        if(ExampleFrameListener::frameStarted(evt) == false)
    		return false;
        mMouseCursor->updatePosition(mMouse->getMouseState().X.abs, mMouse->getMouseState().Y.abs);
        return true;
    }

    virtual void windowResized(RenderWindow* rw)
	{
        ExampleFrameListener::windowResized(rw);
        mMouseCursor->setWindowDimensions(rw->getWidth(), rw->getHeight());
	}
};

class MCApplication : public ExampleApplication
{
public:
    MCApplication() {}

    ~MCApplication() {}

protected:

    virtual void chooseSceneManager(void)
    {
        mSceneMgr = mRoot->createSceneManager(ST_GENERIC);
    }

    virtual void createCamera(void)
    {
        mCamera = mSceneMgr->createCamera("Camera0");
        mCamera->setPosition(Vector3(0, 0, 100));
        mCamera->lookAt(Vector3(0, 0, 0));
        mCamera->setNearClipDistance(5);
    }

    virtual void createScene(void) {
        // put an ogrehead
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mSceneMgr->createEntity("ogre", "ogrehead.mesh"));
    }
   
    // Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new MCFrameListener(mWindow, mCamera);
        mRoot->addFrameListener(mFrameListener);
    }
};


#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char *argv[])
#endif
{
    // Create application object
    MCApplication app;

    try {
        app.go();
    } catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        std::cerr << "An exception has occured: " <<
            e.getFullDescription().c_str() << std::endl;
#endif
    }

    return 0;
}

#ifdef __cplusplus
}
#endif

Second Way: If you want to use the native mouse cursor and to let the cursor go outside the window then create your input manager with a paramlist and right before calling

   mInputSystem = OIS::InputManager::createInputSystem( paramList );

insert the following lines

   #if defined OIS_WIN32_PLATFORM
   paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
   paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
   paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
   paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
   #elif defined OIS_LINUX_PLATFORM
   paramList.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
   paramList.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
   paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
   paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
   #endif

For a more information on this and OIS: Using OIS

Notes

  • This will show the Ogre head with no lighting.
  • Any alpha blended texture will work for cursor image.
  • Please send feedback to this forum entry or privately to madmark.
Personal tools
administration