Wrecked Games

Please login or register.

Login with username, password and session length
Advanced search  

News:

We're just that awesome.

Author Topic: Ogre Windowed Application  (Read 3924 times)

Anonymous

  • Guest
Ogre Windowed Application
« on: November 13, 2005, 11:39:20 AM »

I've solved the mouse difficulties and wondered about implementing it into  OIS:  "The only thing I do not want in the lib is a Win32 Message loop/pump."  My solution does involve the message loop/pump to receive notification of a few messages, which would be tucked away within Win32Mouse.h and Win32Mouse.cpp.

However there needs to be a public function within OISMouse.h in order to handle manual and application-specific access to this feature.  Manual access such as the user requesting for the mouse to be released.  And application-specific access such as implementing Kraythe's seemless transition between a DirectX/OgreApplication cursor and the Windows cursor.
Logged

Rackle

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 26
    • View Profile
Ogre Windowed Application
« Reply #1 on: November 13, 2005, 12:24:05 PM »

Bleh, I wasn't logged in when I posted.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Ogre Windowed Application
« Reply #2 on: November 13, 2005, 06:50:50 PM »

I would be interested in a patch  8) . I have contemplated the best way to handle seemless transition but have been distracted by other work and things. This only deals with the Win32 side of things? It may take me a bit of time to intergrate your patch, as I like to keep windows and linux versions of OIS is as good of sync as possible... But, I am sure I could transfer the changes of win32 to linux easily enough.

And, I really wouldn't need any of the app code (with the win32 messages).. though, you could post it in this forum as a code tip/info.. And, once I integrate the changes in I could post it to the wiki manual of OIS mouse stuff.. Or, it could go there now and just have a note as not yet implemented. Thanks for your effort on this.
Logged

Rackle

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 26
    • View Profile
Ogre Windowed Application
« Reply #3 on: November 13, 2005, 07:56:51 PM »

I'm limited to the Windows environment; I do not know how windowed Ogre applications behave under Linux nor Macintosh.  So yes, this is Windows-only code so far.  Although I think I read something about "grabbing" the mouse under Linux, much the same way the SetCapture() function works under Windows.  This could be a common ground.  But the extra message-handling code, which could be tucked away neatly within the Win32 code, would be Windows-only.  I'll see how good a job I can make of this; what I posted on the Ogre message board is the rough, dirty result of my experiments.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Ogre Windowed Application
« Reply #4 on: November 13, 2005, 08:19:20 PM »

I looked somewhat at Win32 API in reagrds to this, and did notice SetCapture call. Though, it (from the msdn doc's) seemed to differ from the X11 (linux) equivilent of Grabing. From my impression, SetCapture just enables an application to get mouse events when it is not in the foreground? In which case is equivilant to DirectInput's BACKGROUND creation flag... Though, I could e wrong from my readings. I look forward to seeing what you come up with.
Logged

Rackle

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 26
    • View Profile
Ogre Windowed Application
« Reply #5 on: November 15, 2005, 05:35:33 AM »

I've submitted my patch.  It modifies OISMouse.h,  Win32Mouse.h and Win32Mouse.cpp. OISMouse.h only contains a common function definition, which could lead to platform-specific implementations on Linux and Macintosh.  Win32Mouse.h and Win32Mouse.cpp contain the Windows specific implementations.

I've made use of a static message handler to process the relevant Windows messages.  Because of this static message handler a static variable must be used to gain access to the Win32Mouse class members; there do not seem to be any way around this.  An alternative would be to add an access method for every device, such as:

OIS::InputManager::getSingletonPtr()->getDevice(OIS::Type::OISMouse, 0)

getDevice would return a pointer to the device and receive the type of device requested (mouse, keyboard, tablet) as well as the sequential number of the device (first, second, third, ...).

In my application, within the frame listener, I added this to support manual release/acquisition:

bool keyPressed( const OIS::KeyEvent &arg )
{
   if( arg.key == OIS::KC_ESCAPE )
      mShutdownRequested = true;
   else if( arg.key == OIS::KC_Q )
      mMouse->acquire(false);
   else if( arg.key == OIS::KC_E )
      mMouse->acquire(true);
   return true;
}
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Ogre Windowed Application
« Reply #6 on: November 15, 2005, 10:15:12 AM »

I was going to post via the patch tracker.. But, seems sourceforge is offline temporarily again. So, I'll respond here.

Overall, the patch looks good. Though, I have issues with having a Windows Message loop inside the plugin. Though, how you saved the old one and call that one is a decent selling point. However, the static method to get the device would be better replaced with using the SetWindowPtrLong to store the 'this' pointer of Win32Mouse would be better... However, the fickleness of windows subclassing means anyone could have put something else there, and we could never garuntee that the pointer recieved from GetWindowPtrLong contained our custom data. And casting to a Win32Mouse would be dangerous.

I propose, instead of having the message loop in Win32Mouse (as the messages for wanting to release the mouse are heavily app oriented) be placed in the client app. And just the app can call the aquire(true) / aquire(false)? What are your feeling on this?
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Ogre Windowed Application
« Reply #7 on: November 15, 2005, 10:22:40 AM »

<rant>
This is why I feel Ogre should have 'hooks' that the client app can listen for window events (lost or gained focus, resize, etc).. For me, it feels really ineffecient to have to ask Ogre (for example) every frame if the window is active, being resized, etc.

Though, this is never a problem if you have your own message loop in your app and handle the Resizing (and other message) Ogre calls yourself.. but, since Ogre has a message loop by default, I feel it should also allow the app to know these things when they happen.
</rant>

Perhaps I will submit a patch to Ogre to create such messages.. Though, with the many platforms, and the likelihood of it being accepted by the Ogre Team, I do not know if it is worth it. Though, maybe a feature request poll in the Ogre forums might push Ogre Team into adding such a feature :)
Logged

Rackle

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 26
    • View Profile
Ogre Windowed Application
« Reply #8 on: November 15, 2005, 11:36:30 AM »

Ogre is putting the THIS pointer of D3D9RenderWindow into GWL_USERDATA, which gets carried through the message loop, so we could not put a Win32Mouse pointer in there.  Although we could maybe store the Ogre value and replace it with ours but if Ogre changes its then we would cause problems with Ogre.

I was thinking that a kludge to retrieve the state of the window (windowed or fullscreen) would be to find a message such as WM_CREATE, retrieve the D3D9RenderWindow pointer and store it inside Win32Mouse.  I tried to find the code to toggle between a windowed and a fullscreen mode but could not.  My goal was to see if they (the Ogre team) delete the win32 window, in which case a new WM_CREATE message would be sent, or if they simply create a new D3D device, in which case I would not be notified that there was a new "window" and would not know to retrieve the new pointer to D3D9RenderWindow.  Another approach would be to create an access function to tell the Mouse class of the new state.  This aspect, of detecting whether we are in windowed or fullscreen mode is still under development so nothing to propose/suggest yet.

My thoughts on the message loop is that another one may be useful to handle keyboard input, especially the WM_CHAR messages which result in UTF-16 characters.  And there's also the elusive WM_UNICHAR message that results in UTF-32 characters but I have as yet been unable to receive it; maybe it's only received when an external application (an IME) sends a message to the application.  So rather than having two message loops, a single one could be used to handle/intercept all Windows messages.

I bring up the WM_CHAR message because from what I've read on this topic keeps stating that DirectInput is good for responding to triggers (ie hit the A key to attack, SPACE to jump, etc) and WM_CHAR messages are the best for handling text input such as chat.  But keyboard input is for later.

Being integrated as it currently is makes it easier on the programmers; they have nothing new to add.  However they are stuck with a feature that is always "on" without the ability to turn it off.  It also hides the yucky static pointer to Win32Mouse, which is needed unless this type of access/retrieval is added:
OIS::InputManager::getSingletonPtr()->getDevice(OIS::Type::OISMouse, 0).

OIS was so far directed toward gathering input from peripherals.  Using a message loop (under Windows at least) would create a new type of input, such as an environmental or platform input.  As you hinted at, these messages could be packed into a new class and programmers integrate the appropriate code within the functions of this class, such as a Platform::Activate() which would include my acquire(true) function.  But this requires knowledge of the workings of the various platforms, what messages they send off, which are common and which are platform-specific.  This seems like an interesting idea.

My initial goal was to better integrate Ogre windowed applications within Windows and my changes accomplish that.  The only part that really must stay inside the Win32Mouse class is the acquire function.  The message loop handling could be taken out and placed within a platform input class.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Ogre Windowed Application
« Reply #9 on: November 15, 2005, 12:31:46 PM »

Quote from: "Rackle"
Ogre is putting the THIS pointer of D3D9RenderWindow into GWL_USERDATA, which gets carried through the message loop, so we could not put a Win32Mouse pointer in there.  Although we could maybe store the Ogre value and replace it with ours but if Ogre changes its then we would cause problems with Ogre.


Yeah, I knew that Ogre put data there. And, apps not using Ogre's Winproc probably put there own data there.. So, that is where my "fickleness" of windows subclassing comment deals with :wink:

Quote

I was thinking that a kludge to retrieve the state of the window (windowed or fullscreen) would be to find a message such as WM_CREATE, retrieve the D3D9RenderWindow pointer and store it inside Win32Mouse.  I tried to find the code to toggle between a windowed and a fullscreen mode but could not.  My goal was to see if they (the Ogre team) delete the win32 window, in which case a new WM_CREATE message would be sent, or if they simply create a new D3D device, in which case I would not be notified that there was a new "window" and would not know to retrieve the new pointer to D3D9RenderWindow.  Another approach would be to create an access function to tell the Mouse class of the new state.  This aspect, of detecting whether we are in windowed or fullscreen mode is still under development so nothing to propose/suggest yet.

This all defintely precludes the use of SetWindowPtrLong, which is another reason which I do not want to really put a WinProc in OIS unless things could be accomplished in no other way that was cleaner and more elegent.

Quote

My thoughts on the message loop is that another one may be useful to handle keyboard input, especially the WM_CHAR messages which result in UTF-16 characters.  And there's also the elusive WM_UNICHAR message that results in UTF-32 characters but I have as yet been unable to receive it; maybe it's only received when an external application (an IME) sends a message to the application.  So rather than having two message loops, a single one could be used to handle/intercept all Windows messages.

I bring up the WM_CHAR message because from what I've read on this topic keeps stating that DirectInput is good for responding to triggers (ie hit the A key to attack, SPACE to jump, etc) and WM_CHAR messages are the best for handling text input such as chat.  But keyboard input is for later.

As far as Unicode support. I have looked into the ToUnicode method of the Win32API, you do not really need to use WM_ messages. All you need (from my intial look) was a KeyCode -scancode (done) and Virtual Code (can be done with MapVirtual key or something like that IIRC), and the state of the keyboard buffer as returned from GetDeviceState (Done - contained in the char [256] array of Win32keyboard). So, using message loop for Unicode support does not seem neccessary at this point - though, thigns can always change.

Quote

Being integrated as it currently is makes it easier on the programmers; they have nothing new to add.  However they are stuck with a feature that is always "on" without the ability to turn it off.  It also hides the yucky static pointer to Win32Mouse, which is needed unless this type of access/retrieval is added:
OIS::InputManager::getSingletonPtr()->getDevice(OIS::Type::OISMouse, 0).

I definately want this to be easy on the OIS user app.

Quote

OIS was so far directed toward gathering input from peripherals.  Using a message loop (under Windows at least) would create a new type of input, such as an environmental or platform input.  As you hinted at, these messages could be packed into a new class and programmers integrate the appropriate code within the functions of this class, such as a Platform::Activate() which would include my acquire(true) function.  But this requires knowledge of the workings of the various platforms, what messages they send off, which are common and which are platform-specific.  This seems like an interesting idea.

I wasn't really saying that OIS should handle/send out OS events...I was mainly referring to Ogre should be sending out OS window event via a listener mechanism. I disscussed this with :wumpus: on IRC already today, and he agreed it would be nice feature to add, for some messages. Though, I think the best way to do this really, would be a seperate lib (OWS - Object-Oriented Windows System ?) that could be used by any app using Ogre, OIS, or neither ... Though, Ogre is pretty coupled to the Windowing system for creating windows.. So, creating a seperate lib just to listen for windows event and dispatch them would be quite of an amount of work for little gain. As it is right now, any app that would/should want to act specifically on certain OS events should override Ogre's Window Procedure with their own and issue commands to Ogre and OIS based on what happened. Until such time as Ogre has an event listener (I do not have time to make another Ogre patch ATM) class included in it.

Quote

My initial goal was to better integrate Ogre windowed applications within Windows and my changes accomplish that.  The only part that really must stay inside the Win32Mouse class is the acquire function.  The message loop handling could be taken out and placed within a platform input class.

Agreed, the base Mouse class definetly needs an acquire method which platforms could implement (ie Win32Mouse).
Logged

Rackle

  • Regular
  • *
  • Karma: +0/-0
  • Posts: 26
    • View Profile
Ogre Windowed Application
« Reply #10 on: November 15, 2005, 12:43:37 PM »

>> I wasn't really saying that OIS should handle/send out OS events...

Short reply: it could...  :wink:
Logged