Buffered/Unbuffered Input Question

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
charlie
Greenskin
Posts: 146
Joined: Mon Nov 15, 2004 1:43 pm
Location: Austria
Contact:

Buffered/Unbuffered Input Question

Post by charlie »

Can a FrameListener be unbuffered and buffered at the same time.
Because for CEGUI I need a buffered FrameListener.
But I guess for moving the camera a unbuffered FrameListener (like in tutorial 4) is more handy, right?

Or do i have to make two framelistener and add them both?
Is this a good solution or what is the easiest way to have CEGUI and still be able to walk with the camera as usual?

Can I get problems when my CEGUI has textfields?
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19265
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

Not at the same time.

I've happily stayed in buffered mode all the time, using mouseMoved to control the mouse and the standard isKeyDown method for the keys (which still works in buffered mode),
User avatar
pjcast
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2543
Joined: Fri Oct 24, 2003 2:53 am
Location: San Diego, Ca
x 2
Contact:

Post by pjcast »

Personally, I use buffered all the time.. for keyboard, mouse, and joysticks. Why? because, I find it easier to stick to one mode, and it is also pretty easy to create a user configurable action mapping system that maps events to actions using buffered events.

This is how I do it with the OIS Ogre action mapping demo. Though, it could also be done using Ogre's buffered input system too.
Have a question about Input? Video? WGE? Come on over... http://www.wreckedgames.com/forum/
Rackle
Gnome
Posts: 375
Joined: Sat Jul 16, 2005 1:42 am
Location: Montreal

Post by Rackle »

Actually, OIS might be best used in buffered mode only.

If you look through the source code of Win32KeyBoard.cpp you'll see that if you call capture() every frame, much like you would if you were using immediate/unbuffered mode, it calls _readBuffered(). This function retrieves buffered keyboard input and triggers the appropriate keyPressed() or keyReleased() functions of your listener.

In addition this _readBuffered() function updates an internal buffer, KeyBuffer[]. You can then use the isKeyDown() function to determine the state of your keyboard, just as if you were using immediate/unbuffered mode.

My current implementation required that I processed some keys every time they are pressed, such as the R key to change rendering from solid, wireframe, or points, as well as processing keys that are held down, such as the arrow keys for movement. Here's how I achieved this:

in the listener constructor

Code: Select all

mKeyboard = static_cast<OIS::Keyboard*>(im.createInputObject( OIS::OISKeyboard, true ));
mKeyboard->setEventCallback(this);
in ::frameStarted(const FrameEvent& evt)

Code: Select all

	if( mWindow->isClosed() )
		return false;

	if( mWindow->isActive() )
	{
		// Only process the keyboard and the mouse when the application has the focus
		mKeyboard->capture();

		mMouse->capture();
		if (processUnbufferedKeyInput(evt) == false)
			return false;
	}

	if(moveCharLeft || moveCharRight || moveCharForward || moveCharBackward)
		CharacterController::getSingletonPtr()->pc.update(evt.timeSinceLastFrame, moveCharForward, moveCharBackward, moveCharLeft, moveCharRight);

	if(xCamera || yCamera || zCamera || tiltCamera )
		CameraController::getSingletonPtr()->move(evt.timeSinceLastFrame, xCamera, yCamera, zCamera, tiltCamera);
	CameraController::getSingletonPtr()->update(evt.timeSinceLastFrame);

	moveCharLeft = moveCharRight = moveCharForward = moveCharBackward = false;
	xCamera = yCamera = zCamera = tiltCamera = 0;

within ::keyPressed( const OIS::KeyEvent &arg )

Code: Select all

	// Buffered keyboard input
	switch(arg.key)
	{
	case OIS::KC_ESCAPE:
		mShutdownRequested = true;
		break;
	case OIS::KC_R:
		mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
		switch(mSceneDetailIndex) {
			case 0 : mCamera->setDetailLevel(SDL_SOLID); break;
			case 1 : mCamera->setDetailLevel(SDL_WIREFRAME); break;
			case 2 : mCamera->setDetailLevel(SDL_POINTS); break;
		}
		break;
	default:
		CEGUI::System::getSingleton().injectKeyDown( arg.key );
	}
	return true;
within ::processUnbufferedKeyInput(const FrameEvent& evt)

Code: Select all

// This is a custom function, not a trigger callback from OIS
	// Unbuffered keyboard input
	bool lControlKey = mKeyboard->isKeyDown(OIS::KC_LCONTROL) || mKeyboard->isKeyDown(OIS::KC_RCONTROL);
	if(mKeyboard->isKeyDown(OIS::KC_LEFT) )
	{
		if(lControlKey)
			xCamera = 1;
		else
			moveCharLeft = true;
	}
	return true; // Continue rendering
}
User avatar
charlie
Greenskin
Posts: 146
Joined: Mon Nov 15, 2004 1:43 pm
Location: Austria
Contact:

Post by charlie »

sinbad wrote: I've happily stayed in buffered mode all the time, using mouseMoved to control the mouse and the standard isKeyDown method for the keys (which still works in buffered mode),
So from this comment I guess buffered input is better than unbuffered. What are the advantages/disadvantages?

With your second statement about the still working stuff do you mean what is mentioned in the tutorials?
There are also parts of the system that are broken entirely
Will this part of the API still work/be maintain in the next time/releases?

(I don't use a CVS version, so I have no idea about changes in this area)

Thanks for your comments.
Post Reply