How to show the Mouse Cursor W/O CEGUI
From Ogre Wiki
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.

