Readded input & event handling

c++11
scrawl 9 years ago
parent 298b3ed2ef
commit 39fb46601a

@ -442,7 +442,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
gameControllerdb = ""; //if it doesn't exist, pass in an empty string
// FIXME: shouldn't depend on Engine
MWInput::InputManager* input = new MWInput::InputManager (*this, keybinderUser, keybinderUserExists, gameControllerdb, mGrab);
MWInput::InputManager* input = new MWInput::InputManager (mWindow, mViewer, *this, keybinderUser, keybinderUserExists, gameControllerdb, mGrab);
mEnvironment.setInputManager (input);
std::string myguiResources = (mResDir / "mygui").string();

@ -1,8 +1,7 @@
#include "inputmanagerimp.hpp"
#include <OgreRoot.h>
#include <OgreRenderWindow.h>
#include <cmath>
#include <iostream>
#include <boost/lexical_cast.hpp>
@ -14,6 +13,8 @@
#include <SDL_version.h>
#include <components/sdlutil/sdlinputwrapper.hpp>
#include "../engine.hpp"
#include "../mwbase/world.hpp"
@ -31,8 +32,6 @@
#include "../mwdialogue/dialoguemanagerimp.hpp"
#include <iostream>
using namespace ICS;
namespace
@ -97,6 +96,8 @@ namespace
namespace MWInput
{
InputManager::InputManager(
SDL_Window* window,
osg::ref_ptr<osgViewer::Viewer> viewer,
OMW::Engine& engine,
const std::string& userFile, bool userFileExists,
const std::string& controllerBindingsFile, bool grab)
@ -118,8 +119,8 @@ namespace MWInput
, mGuiCursorEnabled(true)
, mDetectingKeyboard(false)
, mOverencumberedMessageDelay(0.f)
, mMouseX(0)//ogre.getWindow()->getWidth ()/2.f)
, mMouseY(0)//ogre.getWindow()->getHeight ()/2.f)
, mMouseX(0)
, mMouseY(0)
, mMouseWheel(0)
, mUserFileExists(userFileExists)
, mAlwaysRunActive(Settings::Manager::getBool("always run", "Input"))
@ -128,19 +129,20 @@ namespace MWInput
, mAttemptJump(false)
, mFakeDeviceID(1)
{
int w,h;
SDL_GetWindowSize(window, &w, &h);
mMouseX = w / 2.f;
mMouseY = h / 2.f;
/*
Ogre::RenderWindow* window = ogre.getWindow ();
mInputManager = new SFO::InputWrapper(mOgre.getSDLWindow(), mOgre.getWindow(), grab);
mInputManager = new SDLUtil::InputWrapper(window, viewer, grab);
mInputManager->setMouseEventCallback (this);
mInputManager->setKeyboardEventCallback (this);
mInputManager->setWindowEventCallback(this);
mInputManager->setControllerEventCallback(this);
*/
std::string file = userFileExists ? userFile : "";
mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
//adjustMouseRegion (window->getWidth(), window->getHeight());
loadKeyDefaults();
loadControllerDefaults();
@ -198,7 +200,7 @@ namespace MWInput
delete mInputBinder;
//delete mInputManager;
delete mInputManager;
}
void InputManager::setPlayerControlsEnabled(bool enabled)
@ -365,24 +367,24 @@ namespace MWInput
void InputManager::updateCursorMode()
{
//bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)
// && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Console;
bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)
&& MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Console;
bool was_relative = 0;//mInputManager->getMouseRelative();
bool was_relative = mInputManager->getMouseRelative();
bool is_relative = !MWBase::Environment::get().getWindowManager()->isGuiMode();
// don't keep the pointer away from the window edge in gui mode
// stop using raw mouse motions and switch to system cursor movements
//mInputManager->setMouseRelative(is_relative);
mInputManager->setMouseRelative(is_relative);
//we let the mouse escape in the main menu
//mInputManager->setGrabPointer(grab && (mGrabCursor || is_relative));
mInputManager->setGrabPointer(grab && (mGrabCursor || is_relative));
//we switched to non-relative mode, move our cursor to where the in-game
//cursor is
if( !is_relative && was_relative != is_relative )
{
//mInputManager->warpMouse(static_cast<int>(mMouseX), static_cast<int>(mMouseY));
mInputManager->warpMouse(static_cast<int>(mMouseX), static_cast<int>(mMouseY));
}
}
@ -390,9 +392,9 @@ namespace MWInput
{
mControlsDisabled = disableControls;
//mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
//mInputManager->capture(disableEvents);
mInputManager->capture(disableEvents);
// inject some fake mouse movement to force updating MyGUI's widget states
MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel);
@ -426,7 +428,7 @@ namespace MWInput
mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height)));
MyGUI::InputManager::getInstance().injectMouseMove(static_cast<int>(mMouseX), static_cast<int>(mMouseY), mMouseWheel);
//mInputManager->warpMouse(static_cast<int>(mMouseX), static_cast<int>(mMouseY));
mInputManager->warpMouse(static_cast<int>(mMouseX), static_cast<int>(mMouseY));
}
if (mMouseLookEnabled)
{
@ -657,17 +659,11 @@ namespace MWInput
mControlSwitch[sw] = value;
}
void InputManager::adjustMouseRegion(int width, int height)
{
mInputBinder->adjustMouseRegion(width, height);
}
void InputManager::keyPressed( const SDL_KeyboardEvent &arg )
{
// HACK: to make Morrowind's default keybinding for the console work without printing an extra "^" upon closing
// This assumes that SDL_TextInput events always come *after* the key event
// (which is somewhat reasonable, and hopefully true for all SDL platforms)
/*
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE)
== arg.keysym.scancode
@ -685,7 +681,6 @@ namespace MWInput
if (!mControlsDisabled && !consumed)
mInputBinder->keyPressed (arg);
mJoystickLastUsed = false;
*/
}
void InputManager::textInput(const SDL_TextInputEvent &arg)
@ -698,13 +693,11 @@ namespace MWInput
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
{
/*
mJoystickLastUsed = false;
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
mInputBinder->keyReleased (arg);
*/
}
void InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id )
@ -751,7 +744,7 @@ namespace MWInput
}
}
void InputManager::mouseMoved(const SFO::MouseMotionEvent &arg )
void InputManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg )
{
mInputBinder->mouseMoved (arg);
@ -830,9 +823,9 @@ namespace MWInput
setPlayerControlsEnabled(!guiMode);
//esc, to leave initial movie screen
//OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
//bool guiFocus = MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0);
//setPlayerControlsEnabled(!guiFocus);
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
bool guiFocus = MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0);
setPlayerControlsEnabled(!guiFocus);
if (!mControlsDisabled)
mInputBinder->buttonPressed(deviceID, arg);
@ -857,8 +850,8 @@ namespace MWInput
mInputBinder->buttonReleased(deviceID, arg);
///to escape initial movie
//OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
//setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
}
void InputManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg )
@ -883,12 +876,15 @@ namespace MWInput
void InputManager::windowVisibilityChange(bool visible)
{
//TODO: Pause game?
//TODO: Pause game?
}
void InputManager::windowResized(int x, int y)
{
//mOgre.windowResized(x,y);
Settings::Manager::setInt("resolution x", "Video", x);
Settings::Manager::setInt("resolution y", "Video", y);
MWBase::Environment::get().getWindowManager()->windowResized(x, y);
}
void InputManager::windowClosed()

@ -3,11 +3,17 @@
#include "../mwgui/mode.hpp"
#include <osg/ref_ptr>
#include <extern/oics/ICSChannelListener.h>
#include <extern/oics/ICSInputControlSystem.h>
#include <components/settings/settings.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/sdlutil/events.hpp>
#include "../mwbase/inputmanager.hpp"
#include <extern/sdl4ogre/sdlinputwrapper.hpp>
namespace MWWorld
{
@ -39,8 +45,17 @@ namespace Files
struct ConfigurationManager;
}
#include <extern/oics/ICSChannelListener.h>
#include <extern/oics/ICSInputControlSystem.h>
namespace SDLUtil
{
class InputWrapper;
}
namespace osgViewer
{
class Viewer;
}
struct SDL_Window;
namespace MWInput
{
@ -50,15 +65,17 @@ namespace MWInput
*/
class InputManager :
public MWBase::InputManager,
public SFO::KeyListener,
public SFO::MouseListener,
public SFO::WindowListener,
public SFO::ControllerListener,
public SDLUtil::KeyListener,
public SDLUtil::MouseListener,
public SDLUtil::WindowListener,
public SDLUtil::ControllerListener,
public ICS::ChannelListener,
public ICS::DetectingBindingListener
{
public:
InputManager(
SDL_Window* window,
osg::ref_ptr<osgViewer::Viewer> viewer,
OMW::Engine& engine,
const std::string& userFile, bool userFileExists,
const std::string& controllerBindingsFile, bool grab);
@ -100,7 +117,7 @@ namespace MWInput
virtual void mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id );
virtual void mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
virtual void mouseMoved( const SFO::MouseMotionEvent &arg );
virtual void mouseMoved( const SDLUtil::MouseMotionEvent &arg );
virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg);
virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg);
@ -140,8 +157,7 @@ namespace MWInput
ICS::InputControlSystem* mInputBinder;
SFO::InputWrapper* mInputManager;
SDLUtil::InputWrapper* mInputManager;
std::string mUserFile;
@ -178,7 +194,6 @@ namespace MWInput
std::map<std::string, bool> mControlSwitch;
private:
void adjustMouseRegion(int width, int height);
MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button);
virtual std::string sdlControllerAxisToString(int axis);

@ -127,7 +127,7 @@ add_component_dir (fontloader
)
add_component_dir (sdlutil
sdlgraphicswindow imagetosurface
sdlgraphicswindow imagetosurface sdlinputwrapper OISCompat events
)
add_component_dir (version

@ -8,7 +8,8 @@
// Events //
////////////
namespace SFO {
namespace SDLUtil
{
/** Extended mouse event struct where we treat the wheel like an axis, like everyone expects */
struct MouseMotionEvent : SDL_MouseMotionEvent {

@ -12,6 +12,33 @@ GraphicsWindowSDL2::~GraphicsWindowSDL2()
close(true);
}
GraphicsWindowSDL2::GraphicsWindowSDL2(osg::GraphicsContext::Traits *traits)
: mWindow(0)
, mContext(0)
, mValid(false)
, mRealized(false)
, mOwnsWindow(false)
{
_traits = traits;
init();
if(valid())
{
setState(new osg::State);
getState()->setGraphicsContext(this);
if(_traits.valid() && _traits->sharedContext.valid())
{
getState()->setContextID(_traits->sharedContext->getState()->getContextID());
incrementContextIDUsageCount(getState()->getContextID());
}
else
{
getState()->setContextID(osg::GraphicsContext::createNewContextID());
}
}
}
bool GraphicsWindowSDL2::setWindowDecorationImplementation(bool flag)
{

@ -1,7 +1,7 @@
#ifndef OSGGRAPHICSWINDOW_H
#define OSGGRAPHICSWINDOW_H
#ifndef OPENMW_COMPONENTS_SDLUTIL_SDLGRAPHICSWINDOW_H
#define OPENMW_COMPONENTS_SDLUTIL_SDLGRAPHICSWINDOW_H
#include <SDL.h>
#include <SDL_video.h>
#include <osgViewer/GraphicsWindow>
@ -22,32 +22,7 @@ class GraphicsWindowSDL2 : public osgViewer::GraphicsWindow
virtual ~GraphicsWindowSDL2();
public:
GraphicsWindowSDL2(osg::GraphicsContext::Traits *traits)
: mWindow(0)
, mContext(0)
, mValid(false)
, mRealized(false)
, mOwnsWindow(false)
{
_traits = traits;
init();
if(valid())
{
setState(new osg::State);
getState()->setGraphicsContext(this);
if(_traits.valid() && _traits->sharedContext.valid())
{
getState()->setContextID(_traits->sharedContext->getState()->getContextID());
incrementContextIDUsageCount(getState()->getContextID());
}
else
{
getState()->setContextID(osg::GraphicsContext::createNewContextID());
}
}
}
GraphicsWindowSDL2(osg::GraphicsContext::Traits *traits);
virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsWindowSDL2*>(object)!=0; }
virtual const char* libraryName() const { return "osgViewer"; }

@ -1,17 +1,16 @@
#include "sdlinputwrapper.hpp"
#include <SDL_syswm.h>
#include <OgrePlatform.h>
#include <OgreRoot.h>
#include <iostream>
#include <stdexcept>
#include <osgViewer/Viewer>
namespace SFO
namespace SDLUtil
{
/// \brief General purpose wrapper for OGRE applications around SDL's event
/// queue, mostly used for handling input-related events.
InputWrapper::InputWrapper(SDL_Window* window, Ogre::RenderWindow* ogreWindow, bool grab) :
InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> viewer, bool grab) :
mSDLWindow(window),
mOgreWindow(ogreWindow),
mViewer(viewer),
mWarpCompensate(false),
mMouseRelative(false),
mGrabPointer(false),
@ -147,28 +146,26 @@ namespace SFO
mMouseInWindow = false;
updateMouseSettings();
break;
case SDL_WINDOWEVENT_MOVED:
// I'm not sure what OSG is using the window position for, but I don't think it's needed,
// so we ignore window moved events (improves window movement performance)
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
int w,h;
SDL_GetWindowSize(mSDLWindow, &w, &h);
// TODO: Fix Ogre to handle this more consistently (fixed in 1.9)
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
mOgreWindow->resize(w, h);
#else
mOgreWindow->windowMovedOrResized();
#endif
int x,y;
SDL_GetWindowPosition(mSDLWindow, &x,&y);
mViewer->getCamera()->getGraphicsContext()->resized(x,y,w,h);
mViewer->getEventQueue()->windowResize(x,y,w,h);
if (mWindowListener)
mWindowListener->windowResized(w, h);
break;
case SDL_WINDOWEVENT_RESIZED:
// TODO: Fix Ogre to handle this more consistently (fixed in 1.9)
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
mOgreWindow->resize(evt.window.data1, evt.window.data2);
#else
mOgreWindow->windowMovedOrResized();
#endif
if (mWindowListener)
mWindowListener->windowResized(evt.window.data1, evt.window.data2);
// This should also fire SIZE_CHANGED, so no need to handle
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
@ -187,12 +184,10 @@ namespace SFO
case SDL_WINDOWEVENT_CLOSE:
break;
case SDL_WINDOWEVENT_SHOWN:
mOgreWindow->setVisible(true);
if (mWindowListener)
mWindowListener->windowVisibilityChange(true);
break;
case SDL_WINDOWEVENT_HIDDEN:
mOgreWindow->setVisible(false);
if (mWindowListener)
mWindowListener->windowVisibilityChange(false);
break;

@ -1,24 +1,27 @@
#ifndef SDL4OGRE_SDLINPUTWRAPPER_H
#define SDL4OGRE_SDLINPUTWRAPPER_H
#ifndef OPENMW_COMPONENTS_SDLUTIL_SDLINPUTWRAPPER_H
#define OPENMW_COMPONENTS_SDLUTIL_SDLINPUTWRAPPER_H
#define NOMINMAX
#include <map>
#include <SDL_events.h>
#include <OgreRenderWindow.h>
#include <boost/unordered_map.hpp>
#include <osg/ref_ptr>
#include "OISCompat.h"
#include "events.h"
#include <SDL_events.h>
#include "OISCompat.hpp"
#include "events.hpp"
namespace osgViewer
{
class Viewer;
}
namespace SFO
namespace SDLUtil
{
/// \brief A wrapper around SDL's event queue, mostly used for handling input-related events.
class InputWrapper
{
public:
InputWrapper(SDL_Window *window, Ogre::RenderWindow* ogreWindow, bool grab);
InputWrapper(SDL_Window *window, osg::ref_ptr<osgViewer::Viewer> viewer, bool grab);
~InputWrapper();
void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; }
@ -42,7 +45,6 @@ namespace SFO
void updateMouseSettings();
private:
void handleWindowEvent(const SDL_Event& evt);
bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
@ -51,12 +53,15 @@ namespace SFO
void _setupOISKeys();
SFO::MouseListener* mMouseListener;
SFO::KeyListener* mKeyboardListener;
SFO::WindowListener* mWindowListener;
SFO::ControllerListener* mConListener;
SDL_Window* mSDLWindow;
osg::ref_ptr<osgViewer::Viewer> mViewer;
MouseListener* mMouseListener;
KeyListener* mKeyboardListener;
WindowListener* mWindowListener;
ControllerListener* mConListener;
typedef boost::unordered_map<SDL_Keycode, OIS::KeyCode> KeyMap;
typedef std::map<SDL_Keycode, OIS::KeyCode> KeyMap;
KeyMap mKeyMap;
Uint16 mWarpX;
@ -79,9 +84,6 @@ namespace SFO
bool mWindowHasFocus;
bool mMouseInWindow;
SDL_Window* mSDLWindow;
Ogre::RenderWindow* mOgreWindow;
};
}

@ -32,8 +32,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "ICSControl.h"
#include "ICSChannel.h"
#include "../sdl4ogre/events.h"
#include "boost/lexical_cast.hpp"
#define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() );
@ -51,11 +49,8 @@ namespace ICS
virtual void logMessage(const char* text) = 0;
};
class DllExport InputControlSystem :
public SFO::MouseListener,
public SFO::KeyListener,
public SFO::ControllerListener
{
class DllExport InputControlSystem
{
public:
@ -64,7 +59,7 @@ namespace ICS
typedef NamedAxis MouseAxis; // MouseAxis is deprecated. It will be removed in future versions
typedef std::map<int, SDL_GameController*> JoystickInstanceMap;
typedef std::map<int, SDL_GameController*> JoystickInstanceMap;
typedef std::list<int> JoystickIDList;
typedef struct
@ -101,13 +96,13 @@ namespace ICS
inline void activate(){ this->mActive = true; };
inline void deactivate(){ this->mActive = false; };
void controllerAdded (int deviceID, const SDL_ControllerDeviceEvent &args);
void controllerAdded (int deviceID, const SDL_ControllerDeviceEvent &args);
void controllerRemoved(const SDL_ControllerDeviceEvent &args);
JoystickIDList& getJoystickIdList(){ return mJoystickIDList; };
JoystickIDList& getJoystickIdList(){ return mJoystickIDList; };
JoystickInstanceMap& getJoystickInstanceMap(){ return mJoystickInstanceMap; };
// MouseListener
void mouseMoved(const SFO::MouseMotionEvent &evt);
void mouseMoved(const SDL_MouseMotionEvent &evt);
void mousePressed(const SDL_MouseButtonEvent &evt, Uint8);
void mouseReleased(const SDL_MouseButtonEvent &evt, Uint8);
@ -185,9 +180,9 @@ namespace ICS
typedef std::map<SDL_Scancode, ControlKeyBinderItem> ControlsKeyBinderMapType; // <Scancode, [direction, control]>
typedef std::map<int, ControlAxisBinderItem> ControlsAxisBinderMapType; // <axis, [direction, control]>
typedef std::map<int, ControlButtonBinderItem> ControlsButtonBinderMapType; // <button, [direction, control]>
typedef std::map<int, ControlsAxisBinderMapType> JoystickAxisBinderMapType; // <joystick_id, <axis, [direction, control]> >
typedef std::map<int, ControlButtonBinderItem> ControlsButtonBinderMapType; // <button, [direction, control]>
typedef std::map<int, ControlsAxisBinderMapType> JoystickAxisBinderMapType; // <joystick_id, <axis, [direction, control]> >
typedef std::map<int, ControlsButtonBinderMapType> JoystickButtonBinderMapType; // <joystick_id, <button, [direction, control]> >
ControlsAxisBinderMapType mControlsMouseAxisBinderMap; // <axis, [direction, control]>
@ -210,7 +205,7 @@ namespace ICS
bool mXmouseAxisBinded;
bool mYmouseAxisBinded;
JoystickIDList mJoystickIDList;
JoystickIDList mJoystickIDList;
JoystickInstanceMap mJoystickInstanceMap;
int mMouseAxisBindingInitialValues[3];
@ -237,7 +232,7 @@ namespace ICS
, int axis, Control::ControlChangingDirection direction);
virtual void joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control
, unsigned int button, Control::ControlChangingDirection direction);
, unsigned int button, Control::ControlChangingDirection direction);
};

@ -224,11 +224,11 @@ namespace ICS
}
// mouse Listeners
void InputControlSystem::mouseMoved(const SFO::MouseMotionEvent& evt)
void InputControlSystem::mouseMoved(const SDL_MouseMotionEvent& evt)
{
if(mActive)
{
if(!mDetectingBindingControl)
if(!mDetectingBindingControl)
{
if(mXmouseAxisBinded && evt.xrel)
{
@ -289,7 +289,7 @@ namespace ICS
mMouseAxisBindingInitialValues[0] += evt.xrel;
mMouseAxisBindingInitialValues[1] += evt.yrel;
mMouseAxisBindingInitialValues[2] += evt.zrel;
// mMouseAxisBindingInitialValues[2] += evt.zrel;
if( abs(mMouseAxisBindingInitialValues[0]) > ICS_MOUSE_BINDING_MARGIN )
{

@ -1,99 +0,0 @@
#include "imagerotate.hpp"
#include <OgreRoot.h>
#include <OgreSceneManager.h>
#include <OgreImage.h>
#include <OgreTexture.h>
#include <OgreRenderTarget.h>
#include <OgreCamera.h>
#include <OgreTextureUnitState.h>
#include <OgreHardwarePixelBuffer.h>
#include <OgreTechnique.h>
#include <OgreMaterialManager.h>
#include <OgreRectangle2D.h>
#include <OgreSceneNode.h>
#include <OgreTextureManager.h>
#include <OgreRenderTexture.h>
#include <OgreViewport.h>
using namespace Ogre;
namespace SFO
{
void ImageRotate::rotate(const std::string& sourceImage, const std::string& destImage, const float angle)
{
Root* root = Ogre::Root::getSingletonPtr();
std::string destImageRot = std::string(destImage) + std::string("_rot");
SceneManager* sceneMgr = root->createSceneManager(ST_GENERIC);
Camera* camera = sceneMgr->createCamera("ImageRotateCamera");
MaterialPtr material = MaterialManager::getSingleton().create("ImageRotateMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
TextureUnitState* tus = material->getTechnique(0)->getPass(0)->createTextureUnitState(sourceImage);
Degree deg(angle);
tus->setTextureRotate(Radian(deg.valueRadians()));
tus->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
tus->setTextureBorderColour(ColourValue(0, 0, 0, 0));
Rectangle2D* rect = new Rectangle2D(true);
rect->setCorners(-1.0, 1.0, 1.0, -1.0);
rect->setMaterial("ImageRotateMaterial");
// Render the background before everything else
rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
// Use infinite AAB to always stay visible
AxisAlignedBox aabInf;
aabInf.setInfinite();
rect->setBoundingBox(aabInf);
// Attach background to the scene
SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(rect);
// retrieve image width and height
TexturePtr sourceTexture = TextureManager::getSingleton().getByName(sourceImage);
unsigned int width = sourceTexture->getWidth();
unsigned int height = sourceTexture->getHeight();
TexturePtr destTextureRot = TextureManager::getSingleton().createManual(
destImageRot,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
width, height,
0,
PF_A8B8G8R8,
TU_RENDERTARGET);
RenderTarget* rtt = destTextureRot->getBuffer()->getRenderTarget();
rtt->setAutoUpdated(false);
Viewport* vp = rtt->addViewport(camera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setBackgroundColour(ColourValue(0,0,0,0));
rtt->update();
//copy the rotated image to a static texture
TexturePtr destTexture = TextureManager::getSingleton().createManual(
destImage,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
width, height,
0,
PF_A8B8G8R8,
Ogre::TU_STATIC);
destTexture->getBuffer()->blit(destTextureRot->getBuffer());
// remove all the junk we've created
TextureManager::getSingleton().remove(destImageRot);
MaterialManager::getSingleton().remove("ImageRotateMaterial");
root->destroySceneManager(sceneMgr);
delete rect;
}
}

@ -1,25 +0,0 @@
#ifndef OENGINE_OGRE_IMAGEROTATE_HPP
#define OENGINE_OGRE_IMAGEROTATE_HPP
#include <string>
namespace SFO
{
/// Rotate an image by certain degrees and save as file, uses the GPU
/// Make sure Ogre Root is initialised before calling
class ImageRotate
{
public:
/**
* @param source image (file name - has to exist in an resource group)
* @param name of the destination texture to save to (in memory)
* @param angle in degrees to turn
*/
static void rotate(const std::string& sourceImage, const std::string& destImage, const float angle);
};
}
#endif

@ -1,12 +0,0 @@
#ifndef SDL4OGRE_OSX_UTILS_H
#define SDL4OGRE_OSX_UTILS_H
#include <SDL_syswm.h>
namespace SFO {
extern unsigned long WindowContentViewHandle(SDL_SysWMinfo &info);
}
#endif // SDL4OGRE_OSX_UTILS_H

@ -1,15 +0,0 @@
#include "osx_utils.h"
#import <AppKit/NSWindow.h>
namespace SFO {
unsigned long WindowContentViewHandle(SDL_SysWMinfo &info)
{
NSWindow *window = info.info.cocoa.window;
NSView *view = [window contentView];
return (unsigned long)view;
}
}

@ -1,130 +0,0 @@
#include "sdlwindowhelper.hpp"
#include <OgreStringConverter.h>
#include <OgreRoot.h>
#include <OgreTextureManager.h>
#include <SDL_syswm.h>
#include <SDL_endian.h>
#include <stdexcept>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include "osx_utils.h"
#endif
namespace SFO
{
SDLWindowHelper::SDLWindowHelper (SDL_Window* window, int w, int h,
const std::string& title, bool fullscreen, Ogre::NameValuePairList params)
: mSDLWindow(window)
{
//get the native whnd
struct SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(mSDLWindow, &wmInfo) == SDL_FALSE)
throw std::runtime_error("Couldn't get WM Info!");
Ogre::String winHandle;
switch (wmInfo.subsystem)
{
#ifdef WIN32
case SDL_SYSWM_WINDOWS:
// Windows code
winHandle = Ogre::StringConverter::toString((uintptr_t)wmInfo.info.win.window);
break;
#elif __MACOSX__
case SDL_SYSWM_COCOA:
//required to make OGRE play nice with our window
params.insert(std::make_pair("macAPI", "cocoa"));
params.insert(std::make_pair("macAPICocoaUseNSView", "true"));
winHandle = Ogre::StringConverter::toString(WindowContentViewHandle(wmInfo));
break;
#elif ANDROID
case SDL_SYSWM_ANDROID:
winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.android.window);
break;
#else
case SDL_SYSWM_X11:
winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.window);
break;
#endif
default:
throw std::runtime_error("Unexpected WM!");
break;
}
/// \todo externalWindowHandle is deprecated according to the source code. Figure out a way to get parentWindowHandle
/// to work properly. On Linux/X11 it causes an occasional GLXBadDrawable error.
#ifdef ANDROID
SDL_GLContext context= SDL_GL_CreateContext(window);
params.insert(std::make_pair("currentGLContext","True"));
#endif
params.insert(std::make_pair("externalWindowHandle", winHandle));
mWindow = Ogre::Root::getSingleton().createRenderWindow(title, w, h, fullscreen, &params);
}
void SDLWindowHelper::setWindowIcon(const std::string &name)
{
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().load(name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
if (texture.isNull())
{
std::stringstream error;
error << "Window icon not found: " << name;
throw std::runtime_error(error.str());
}
Ogre::Image image;
texture->convertToImage(image);
SDL_Surface* surface = SDL_CreateRGBSurface(0,texture->getWidth(),texture->getHeight(),32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF);
//copy the Ogre texture to an SDL surface
for(size_t x = 0; x < texture->getWidth(); ++x)
{
for(size_t y = 0; y < texture->getHeight(); ++y)
{
Ogre::ColourValue clr = image.getColourAt(x, y, 0);
//set the pixel on the SDL surface to the same value as the Ogre texture's
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
Uint32 pixel = SDL_MapRGBA(surface->format, static_cast<Uint8>(clr.r * 255),
static_cast<Uint8>(clr.g * 255), static_cast<Uint8>(clr.b * 255), static_cast<Uint8>(clr.a * 255));
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
}
SDL_SetWindowIcon(mSDLWindow, surface);
SDL_FreeSurface(surface);
}
}

@ -1,31 +0,0 @@
#ifndef SDL4OGRE_SDLWINDOWHELPER_H
#define SDL4OGRE_SDLWINDOWHELPER_H
#include <OgreRenderWindow.h>
namespace Ogre
{
class RenderWindow;
}
struct SDL_Window;
namespace SFO
{
/// @brief Creates an Ogre window from an SDL window and allows setting an Ogre texture as window icon
class SDLWindowHelper
{
public:
SDLWindowHelper (SDL_Window* window, int w, int h, const std::string& title, bool fullscreen, Ogre::NameValuePairList params);
void setWindowIcon(const std::string& name);
Ogre::RenderWindow* getWindow() { return mWindow; }
private:
Ogre::RenderWindow* mWindow;
SDL_Window* mSDLWindow;
};
}
#endif
Loading…
Cancel
Save