History: How to show the mouse cursor without CEGUI
Source of version: 5
Copy to clipboard
!Show / display mouse cursor without a GUI library
{maketoc}
GUI library is great for many things, but it can be a little bit overwhelming for your application. I have seen the question about how to display mouse cursor without a GUI library asked in the forums a number of times. The answer was either "Use CEGUI/QuickGUI/MyGUI", 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 a GUI library, using the example framework (somewhat).
!!First way: Software cursor (your application own cursor)
If you want the mouse cursor always stay in the render window and to use your own image you can use following.
Initial Construction:
{CODE(wrap="1", colors="c++")} mMouseCursor = new MouseCursor();
mMouseCursor->setImage("entis.png");
mMouseCursor->setVisible(true);
mMouseCursor->setWindowDimensions(win->getWidth(), win->getHeight());
{CODE}
Update mouse position when needed:
{CODE(wrap="1", colors="c++")} mMouseCursor->updatePosition(mMouse->getMouseState().X.abs, mMouse->getMouseState().Y.abs);
{CODE}
Update window dimensions when needed:
{CODE(wrap="1", colors="c++")} mMouseCursor->setWindowDimensions(rw->getWidth(), rw->getHeight());
{CODE}
__MouseCursor.h__
{CODE(wrap="1", colors="c++")}#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
{CODE}
__Main.cpp__
{CODE(wrap="1", colors="c++")}#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
{CODE}
!!Second way: System cursor (OIS cursor)
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
{CODE(wrap="1", colors="c++")} mInputSystem = OIS::InputManager::createInputSystem( paramList );
{CODE}
insert the following lines
{CODE(wrap="1", colors="c++")} #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
{CODE}
For a more information on this and OIS: [http://www.ogre3d.org/wiki/index.php/Using_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 [http://www.ogre3d.org/phpBB2/viewtopic.php?p=133212#133212|this forum entry] or privately to madmark.
---
Alias: (alias(How to show the Mouse Cursor W/O CEGUI))