Wrecked Games

Please login or register.

Login with username, password and session length
Advanced search  

News:

We're just that awesome.

Pages: [1] 2

Author Topic: Mouse Cursor  (Read 3409 times)

daves

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 7
    • View Profile
Mouse Cursor
« on: March 22, 2007, 09:31:20 AM »

Ok we recently converted our Ogre/CEGUI application to use OIS instead of the Ogre Mouse. With this conversion we disabled the display of the CEGUI mouse (since it sometimes lags behind the hardware mouse used by OIS. Everything works great except that when we hover the mouse over the frame of a CEGUI window the mouse cursor does not change (for example to indicate the resize cursor).

What is the right way to facilitate changes to the mouse cursor? Does OIS support this kind of bidirectional interface to the mouse, if not how have ppl handled this?
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Mouse Cursor
« Reply #1 on: March 22, 2007, 09:58:21 AM »

OIS does not support the OS mouse too much. Besides just allowing it to be displayed. You would have to wrap some win32 functions to do it for you. Or, alternatively, a patch to OIS would probably be OK, that wrapped such functionality in a friendly way. I do not have the time for such features, and mostly in game cursors are preferred over OS cursors for games. Though, the lag can be annoying for sure. Perhaps if you poll (capture) OIS more often, perhaps in a thread, you will see less lag.
Logged

daves

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 7
    • View Profile
Mouse Cursor
« Reply #2 on: March 22, 2007, 12:40:25 PM »

Thanks for the response. So would you recommend that we continue to use the cegui mouse cursor? If so then does this mean that when our application runs in a windowed mode and we drag the os mouse into our "ogre/cegui/ois application window" that we should make a call to the os to hide the os cursor and then use the cegui cursor to display the position that is being pointed to?

In the games that you develop do it sounds like you dont display the os cursor.. so do you make a call to the OS to disable the cursor display?
Logged

KungFooMasta

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
Mouse Cursor
« Reply #3 on: March 23, 2007, 10:39:38 AM »

It would be great if OIS could somehow make calls to hide the OS mouse cursor.  We'd also need to poll the mouse to see when its over the primary OGRE rendering window.

That would be pretty awesome, I need this also, but haven't looked into it...  :twisted:

KungFooMasta
Logged

Steven 'lazalong' Gay

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 22
    • View Profile
    • OGE - Open Game Engine
Mouse Cursor
« Reply #4 on: March 25, 2007, 03:00:51 AM »

This subject was discussed in this thread:
http://www.wreckedgames.com/forum/viewtopic.php?t=323

Basically the following method must be implemented:
Code: [Select]
virtual void enableHardwareCursor( bool enable )
See the other thread for more info.

Arcanor

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
    • http://arcanoria.com
Mouse Cursor
« Reply #5 on: March 27, 2007, 02:59:09 PM »

So does this mean there's no answer currently?  I'd like to use DISCL_NONEXCLUSIVE, and it's working great for me EXCEPT for the fact that when the cursor is over my app window I'm seeing both my CEGUI cursor AND the windows cursor.

How can I hide the windows cursor when I'm over my app?
Logged
Arcanoria - online medieval fantasy RPG - www.arcanoria.com

KungFooMasta

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
Mouse Cursor
« Reply #6 on: March 28, 2007, 08:57:00 AM »

I did some brief searching via google, and found something that is supposed to work, but not for me (at least on vista 64 bit):

http://msdn2.microsoft.com/en-us/library/ms648396.aspx

Sample code:
Code: [Select]

#include <time.h>
#include <Windows.h>
#include <iostream>

void wait ( int seconds )
{
  clock_t endwait;
  endwait = clock () + seconds * CLOCKS_PER_SEC ;
  while (clock() < endwait) {}
}


int main()
{
int x = ShowCursor(false);
std::cout << x << std::endl;

wait(10);

ShowCursor(true);

return 0;
}


If anybody can confirm this works or not on XP that would be great.  Or if there is a solution that also works on Vista that would be better.

KungFooMasta
Logged

KungFooMasta

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
Mouse Cursor
« Reply #7 on: March 28, 2007, 09:30:35 AM »

Here is another link.. nothing leaps out at me:

http://msdn2.microsoft.com/en-us/library/ms648380.aspx

Maybe somebody can help figure this out?

Code: [Select]
WNDCLASS  wc;
 
// Fill the window class structure with parameters that
// describe the main window.
 
wc.style = NULL;                        // class style(s)
wc.lpfnWndProc = (WNDPROC) MainWndProc; // window procedure
wc.cbClsExtra = 0;           // no per-class extra data
wc.cbWndExtra = 0;           // no per-window extra data
wc.hInstance = hinst;        // application that owns the class
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);     // class icon
wc.hCursor = LoadCursor(hinst, MAKEINTRESOURCE(230)); // class cursor
wc.hbrBackground = GetStockObject(WHITE_BRUSH); // class background
wc.lpszMenuName =  "GenericMenu";               // class menu
wc.lpszClassName = "GenericWClass"              // class name
 
// Register the window class.
 
return RegisterClass(&wc);


I'm not at home, so I can't try anything yet.  Maybe setting wc.hCursor to 0 or something, not sure, will have to look into that.  Also I'm not sure if this would affect capturing mouse input..

Maybe creating a 100% transparent cursor and setting that for the main app window.. I'll have to try it out when I get the chance!  :mrgreen: Feel free to try this out before I do, I'm working on a GUI library for OGRE at the moment. (think BetaGUI, but with some CEGUI functionality and input injection)

http://msdn2.microsoft.com/en-us/library/ms648045.aspx

KungFooMasta
Logged

Arcanor

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
    • http://arcanoria.com
it works for me!
« Reply #8 on: March 28, 2007, 12:00:54 PM »

Thanks KungFooMasta. :)

All I did was:
Code: [Select]
ShowCursor(false);

... and it worked like magic.  When the mouse is over the app window the OS cursor disappears (leaving CEGUI to provide its cursor as intended).  When the mouse leaves the app window it looks perfectly normal and does whatever it's supposed to do for each application it moves over.

I didn't even have to do any #includes, I just put in that ONE line of code and it worked.  The windows.h stuff is already in my include heirarchy due to ogre and/or cegui.

I'm running WinXP media center edition 2002 (essentially the same as winxp pro).

Couple of smaller points which may also help.  Basically, I'd like the OS cursor to come back when the cursor is over the main rendering window's EDGE, i.e. for window resizing, or to use the main window title bar to drag, maximize, minimize, or close.  Also, when the cursor is over the edges like that I don't want any clicks registering to the application itself, which it still is, and I haven't figured that part out yet (I have a post on cegui's forums about it).

Anyway, I did this by modifying my mouseMoved() event handler as follows:
Code: [Select]
bool MyInputMgr::mouseMoved( const OIS::MouseEvent &arg )
{
// for some reason ShowCursor() sets a cursor "level" which continues to increase if you
//  call ShowCursor(true) consecutively, so we only want to call it once in each direction.
//  we need to be careful that ShowCursor() is only called from here, and nowhere else in the app.
// we'll start with value 0, which is "shown" state, so we know that we need to turn it off.
static int iOSCursorVisible = 0; // anything 0 or higher is shown, -1 or lower is hidden
static bool bCEGUICursorVisible = true;
if ((unsigned int)arg.state.X.abs == mWindow->getWidth() ||
(unsigned int)arg.state.Y.abs == mWindow->getHeight() ||
arg.state.X.abs == 0 ||
arg.state.Y.abs == 0)
{
// cursor is leaving our app window, so we want to see the O/S cursor now, and hide the CEGUI cursor.
while (iOSCursorVisible < 0)
{
// this will bring the count to at least zero no matter how negative it is.
iOSCursorVisible = ShowCursor(true);
}
CEGUI::System::getSingleton().injectMouseLeaves();
if (bCEGUICursorVisible)
{
CEGUI::System::getSingleton().setMutedState(true);
CEGUI::MouseCursor::getSingleton().hide();
bCEGUICursorVisible = false;
}
}
else
{
// cursor is inside our app window, so we want to hide the O/S cursor now, and show the CEGUI cursor:
while (iOSCursorVisible > -1)
{
// this will bring the count to -1 (the trigger value) no matter how positive it is.
iOSCursorVisible = ShowCursor(false);
}
if (!bCEGUICursorVisible)
{
CEGUI::System::getSingleton().setMutedState(false);
CEGUI::MouseCursor::getSingleton().show();
bCEGUICursorVisible = true;
}
}
CEGUI::System::getSingleton().injectMousePosition(arg.state.X.abs, arg.state.Y.abs);
return true;
}


I hope this can help someone.
Logged
Arcanoria - online medieval fantasy RPG - www.arcanoria.com

KungFooMasta

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
Mouse Cursor
« Reply #9 on: March 28, 2007, 01:53:02 PM »

Awesome, glad to hear the solution is so simple! (at least this works for xp, which I'm currently using on my home machine).

Also, you're not using windows forms or anything right?  Just a regular ogre app, similar to the demo's?

I'll stick with ths simple solution for now.  Maybe when I get more into vista I'll revisit this thread and try setting the cursor to a transparent icon.  :twisted:

KungFooMasta
Logged

Arcanor

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
    • http://arcanoria.com
Mouse Cursor
« Reply #10 on: March 28, 2007, 02:33:14 PM »

No windows forms here.  Just MSVC8.
Logged
Arcanoria - online medieval fantasy RPG - www.arcanoria.com

Arcanor

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
    • http://arcanoria.com
Mouse Cursor
« Reply #11 on: March 28, 2007, 03:22:55 PM »

Figured out the one remaining issue I had above.  Instead of:
Code: [Select]
CEGUI::System::getSingleton().setMutedState(true);
I'm now doing this:
Code: [Select]
CEGUI::System::getSingleton().getGUISheet()->setEnabled(false);
... and vice versa in the 'else' clause.  It's now working as intended.  The CEGUI windows are no longer accepting the mouse clicks when they're not supposed to.
Logged
Arcanoria - online medieval fantasy RPG - www.arcanoria.com

KungFooMasta

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
Mouse Cursor
« Reply #12 on: March 28, 2007, 05:58:56 PM »

Not sure why, but this has no effect for me  :(

Code: [Select]

const OIS::MouseState ms = mMouse->getMouseState();

if( ms.X.abs <= 0 || ms.X.abs >= mWindow->getWidth() || ms.Y.abs <= 0 || ms.Y.abs >= mWindow->getHeight() )
{
// Hide OS Cursor
while(mOSCursor > -1) mOSCursor = ShowCursor(false);
}
else
{
// Show OS Cursor
while(mOSCursor < 0) mOSCursor = ShowCursor(true);
}


I guess I'll have to figure out how to make the OS mouse cursor transparent.

KungFooMasta
Logged

KungFooMasta

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
Mouse Cursor
« Reply #13 on: March 28, 2007, 06:19:06 PM »

Ug, I don't know windows API programming, lol.

This example shows a lot, but I can't seem to match it up with what I want to do:

http://www.winprog.org/tutorial/simple_window.html

pj, can we get your experience on how to obtain a Window struct object, given the window Handle?  I see in OIS you implement access to the HWND (window handle), but I don't see how to use it.  Sorry for being noob.  :P

KungFooMasta
Logged

Arcanor

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 47
    • View Profile
    • http://arcanoria.com
Mouse Cursor
« Reply #14 on: March 29, 2007, 02:45:45 AM »

Quote from: "KungFooMasta"
Not sure why, but this has no effect for me  :(

Code: [Select]

const OIS::MouseState ms = mMouse->getMouseState();

if( ms.X.abs <= 0 || ms.X.abs >= mWindow->getWidth() || ms.Y.abs <= 0 || ms.Y.abs >= mWindow->getHeight() )
{
// Hide OS Cursor
while(mOSCursor > -1) mOSCursor = ShowCursor(false);
}
else
{
// Show OS Cursor
while(mOSCursor < 0) mOSCursor = ShowCursor(true);
}


I guess I'll have to figure out how to make the OS mouse cursor transparent.

KungFooMasta

Where did you put your code?  This is important of course.  My code was meant to be placed into your mouseMoved() event handler, which would be called repeatedly whenever the mouse moves.

Exactly what are you seeing the cursor do?  How does it look outside the window, and inside?
Logged
Arcanoria - online medieval fantasy RPG - www.arcanoria.com
Pages: [1] 2