Переглянути джерело

OIS set up but not working
Better plugin loading

Marko Pintera 13 роки тому
батько
коміт
3a33dcbc18

+ 92 - 0
CamelotOISInput/CamelotOISInput.vcxproj

@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}</ProjectGuid>
+    <RootNamespace>CamelotOISInput</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>..\bin\$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>..\bin\$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../CamelotRenderer/Include;../CamelotUtility/Include;./Include;../Dependencies/Include;./Dependencies/Include</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>CM_OIS_EXPORTS;_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>../lib/$(Configuration);../Dependencies/lib/Debug;./Dependencies/lib/Debug</AdditionalLibraryDirectories>
+      <AdditionalDependencies>CamelotRenderer.lib;CamelotUtility.lib;OIS_d.lib;libboost_signals-vc110-mt-gd-1_49.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ImportLibrary>..\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>../CamelotRenderer/Include;../CamelotUtility/Include;./Include;../Dependencies/Include;./Dependencies/Include</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>CM_OIS_EXPORTS;_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>../lib/$(Configuration);../Dependencies/lib/Release;./Dependencies/lib/Release</AdditionalLibraryDirectories>
+      <AdditionalDependencies>CamelotRenderer.lib;CamelotUtility.lib;OIS.lib;libboost_signals-vc110-mt-1_49.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ImportLibrary>..\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="Include\CmOISPrerequisites.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Include\CmInputHandlerOIS.h">
+      <FileType>CppCode</FileType>
+    </ClInclude>
+    <ClCompile Include="Source\CmOISPlugin.cpp" />
+    <ClCompile Include="Source\CmInputHandlerOIS.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 33 - 0
CamelotOISInput/CamelotOISInput.vcxproj.filters

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Include\CmOISPrerequisites.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmInputHandlerOIS.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Source\CmOISPlugin.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmInputHandlerOIS.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 32 - 0
CamelotOISInput/Include/CmInputHandlerOIS.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#include "CmOISPrerequisites.h"
+#include "CmInputHandler.h"
+
+#include <OIS/OISEvents.h>
+#include <OIS/OISInputManager.h>
+#include <OIS/OISKeyboard.h>
+#include <OIS/OISMouse.h>
+
+namespace CamelotEngine
+{
+	class CM_OIS_EXPORT InputHandlerOIS : public InputHandler, public OIS::KeyListener, public OIS::MouseListener
+	{
+	public:
+		InputHandlerOIS(unsigned int hWnd);
+		virtual ~InputHandlerOIS();
+
+	private:
+		OIS::InputManager*	mInputManager;
+		OIS::Mouse*			mMouse;
+		OIS::Keyboard*		mKeyboard;
+
+		virtual bool keyPressed(const OIS::KeyEvent& arg);
+		virtual bool keyReleased(const OIS::KeyEvent& arg);
+		virtual bool mouseMoved(const OIS::MouseEvent& arg);
+		virtual bool mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID id);
+		virtual bool mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID id);
+
+		virtual void update();
+	};
+}

+ 19 - 0
CamelotOISInput/Include/CmOISPrerequisites.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+#if (CM_PLATFORM == CM_PLATFORM_WIN32) && !defined(__MINGW32__)
+#	ifdef CM_OIS_EXPORTS
+#		define CM_OIS_EXPORT __declspec(dllexport)
+#	else
+#       if defined( __MINGW32__ )
+#           define CM_OIS_EXPORT
+#       else
+#    		define CM_OIS_EXPORT __declspec(dllimport)
+#       endif
+#	endif
+#elif defined ( CM_GCC_VISIBILITY )
+#    define CM_OIS_EXPORT  __attribute__ ((visibility("default")))
+#else
+#    define CM_OIS_EXPORT
+#endif

+ 104 - 0
CamelotOISInput/Source/CmInputHandlerOIS.cpp

@@ -0,0 +1,104 @@
+#include "CmInputHandlerOIS.h"
+#include "CmPoint.h"
+
+namespace CamelotEngine
+{
+	InputHandlerOIS::InputHandlerOIS(unsigned int hWnd)
+		:mInputManager(nullptr), mKeyboard(nullptr), mMouse(nullptr)
+	{
+		OIS::ParamList pl;
+		std::ostringstream windowHndStr;
+		windowHndStr << hWnd;
+		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
+
+#if defined CM_PLATFORM == CM_PLATFORM_WIN32
+		pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
+		pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
+		pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
+		pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
+#elif defined CM_PLATFORM == CM_PLATFORM_LINUX || CM_PLATFORM == CM_PLATFORM_APPLE
+		pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
+		pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
+		pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
+		pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
+#endif
+
+		mInputManager = OIS::InputManager::createInputSystem(pl);
+
+		mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject(OIS::OISKeyboard, true));
+		mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject(OIS::OISMouse, true));
+
+		mMouse->setEventCallback(this);
+		mKeyboard->setEventCallback(this);
+	}
+
+	InputHandlerOIS::~InputHandlerOIS()
+	{
+		if(mInputManager)
+		{		
+			if(mMouse)
+				mInputManager->destroyInputObject(mMouse);
+
+			if(mKeyboard)
+				mInputManager->destroyInputObject(mKeyboard);
+
+			OIS::InputManager::destroyInputSystem(mInputManager);
+			mInputManager = nullptr;
+		}
+	}
+
+	void InputHandlerOIS::update()
+	{
+		mMouse->capture();
+		mKeyboard->capture();
+	}
+
+	bool InputHandlerOIS::keyPressed(const OIS::KeyEvent &arg)
+	{
+		onKeyDown((KeyCode)(int)arg.key);
+
+		return true;
+	}
+
+	bool InputHandlerOIS::keyReleased(const OIS::KeyEvent& arg)
+	{
+		onKeyUp((KeyCode)(int)arg.key);
+
+		return true;
+	}
+
+	bool InputHandlerOIS::mouseMoved(const OIS::MouseEvent& arg)
+	{
+		MouseEvent event;
+		event.coords = Point(arg.state.X.abs, arg.state.Y.abs);
+		event.relCoords = Point(arg.state.X.rel, arg.state.Y.rel);
+		event.z = arg.state.Z.abs;
+		event.relZ = arg.state.Z.rel;
+		onMouseMoved(event);
+
+		return true;
+	}
+
+	bool InputHandlerOIS::mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
+	{
+		MouseEvent event;
+		event.coords = Point(arg.state.X.abs, arg.state.Y.abs);
+		event.relCoords = Point(arg.state.X.rel, arg.state.Y.rel);
+		event.z = arg.state.Z.abs;
+		event.relZ = arg.state.Z.rel;
+		onMouseDown(event, (MouseButton)(int)id);
+
+		return true;
+	}
+
+	bool InputHandlerOIS::mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
+	{
+		MouseEvent event;
+		event.coords = Point(arg.state.X.abs, arg.state.Y.abs);
+		event.relCoords = Point(0, 0);
+		event.z = arg.state.Z.abs;
+		onMouseUp(event, (MouseButton)(int)id);
+
+		return true;
+	}
+}

+ 19 - 0
CamelotOISInput/Source/CmOISPlugin.cpp

@@ -0,0 +1,19 @@
+#include "CmOISPrerequisites.h"
+#include "CmInputHandlerOIS.h"
+#include "CmApplication.h"
+#include "CmInput.h"
+
+namespace CamelotEngine
+{
+	extern "C" CM_OIS_EXPORT const String& getPluginName()
+	{
+		static String pluginName = "OISInput";
+		return pluginName;
+	}
+
+	extern "C" CM_OIS_EXPORT void loadPlugin()
+	{
+		InputHandlerOIS* inputHandler = new InputHandlerOIS(gApplication().getAppWindowId());
+		gInput().registerInputHandler(inputHandler);
+	}
+}

+ 16 - 0
CamelotRenderer.sln

@@ -19,6 +19,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotClient", "CamelotCli
 		{122B7A22-0C62-4B35-B661-EBF3F394EA79} = {122B7A22-0C62-4B35-B661-EBF3F394EA79}
 		{F58FF869-2EA6-4FFF-AB84-328C531BA9D9} = {F58FF869-2EA6-4FFF-AB84-328C531BA9D9}
 		{7F449698-73DF-4203-9F31-0877DBF01695} = {7F449698-73DF-4203-9F31-0877DBF01695}
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1} = {BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}
 		{796B6DFF-BA04-42B7-A43A-2B14D707A33A} = {796B6DFF-BA04-42B7-A43A-2B14D707A33A}
 	EndProjectSection
 EndProject
@@ -43,6 +44,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotFBXImporter", "Camel
 		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotOISInput", "CamelotOISInput\CamelotOISInput.vcxproj", "{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}"
+	ProjectSection(ProjectDependencies) = postProject
+		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SubversionScc) = preSolution
 		Svn-Managed = True
@@ -127,6 +133,16 @@ Global
 		{7F449698-73DF-4203-9F31-0877DBF01695}.Release|Mixed Platforms.Build.0 = Release|Win32
 		{7F449698-73DF-4203-9F31-0877DBF01695}.Release|Win32.ActiveCfg = Release|Win32
 		{7F449698-73DF-4203-9F31-0877DBF01695}.Release|Win32.Build.0 = Release|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Debug|Any CPU.ActiveCfg = Debug|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Debug|Win32.Build.0 = Debug|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Release|Any CPU.ActiveCfg = Release|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Release|Win32.ActiveCfg = Release|Win32
+		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 9 - 0
CamelotRenderer/Include/CmApplication.h

@@ -24,6 +24,15 @@ namespace CamelotEngine
 
 			void DBG_renderSimpleFrame();
 
+			UINT32 getAppWindowId();
+
+			/**
+			 * @brief	Loads a plugin.
+			 *
+			 * @param	pluginName	Name of the plugin to load, without extension.
+			 */
+			void loadPlugin(const String& pluginName);
+
 		private:
 			RenderWindow* mRenderWindow;
 			std::shared_ptr<Camera> mCamera;

+ 4 - 9
CamelotRenderer/Include/CmInput.h

@@ -20,14 +20,9 @@ namespace CamelotEngine
 		boost::signal<void(const MouseEvent&, MouseButton)> onMouseDown;
 		boost::signal<void(const MouseEvent&, MouseButton)> onMouseUp;
 
-		/**
-		 * @brief	Initializes the input manager with a specific input handler that sends input events
-		 * 			to the manager. Should only be called by Application.
-		 *
-		 * @param [in]	inputHandler	Input handler that determines how do we capture input.
-		 * @param [in]	clipRect		If non-zero, mouse input will be ignored unless within the specified area.
-		 */
-		void init(std::shared_ptr<InputHandler> inputHandler, Rect& clipRect);
+
+		void initClipRect(Rect& clipRect);
+		void registerInputHandler(InputHandler* inputHandler);
 
 		/**
 		 * @brief	Called every frame. Should only be called by Application.
@@ -49,7 +44,7 @@ namespace CamelotEngine
 		float getVerticalAxis() const;
 
 	private:
-		std::shared_ptr<InputHandler> mInputHandler;
+		InputHandler* mInputHandler;
 
 		float mSmoothHorizontalAxis;
 		float mSmoothVerticalAxis;

+ 2 - 1
CamelotRenderer/Include/CmInputHandler.h

@@ -174,9 +174,10 @@ namespace CamelotEngine
 	 * @brief	Represents a specific way of acquiring low-level input. InputManager (which provides a higher level input)
 	 * 			must have at least one InputHandler attached. Attach events handler to the provided signals to handle input.
 	 */
-	class InputHandler
+	class CM_EXPORT InputHandler
 	{
 	public:
+		InputHandler() {}
 		virtual ~InputHandler() {}
 
 		boost::signal<void(KeyCode)> onKeyDown;

+ 2 - 0
CamelotRenderer/Include/CmPrerequisites.h

@@ -94,6 +94,8 @@ namespace CamelotEngine {
     class VertexBufferBinding;
     class VertexData;
     class VertexDeclaration;
+	class Input;
+	class InputHandler;
 	// Asset import
 	class SpecificImporter;
 	class Importer;

+ 47 - 19
CamelotRenderer/Source/CmApplication.cpp

@@ -135,25 +135,8 @@ namespace CamelotEngine
 
 		// IMPORTER TEST
 		Importer::startUp(new Importer());
-		DynLib* freeImgLibrary = gDynLibManager().load("CamelotFreeImgImporter.dll"); // TODO - Load this automatically somehow
-
-		if(freeImgLibrary != nullptr)
-		{
-			typedef const void (*LoadPluginFunc)();
-
-			LoadPluginFunc loadPluginFunc = (LoadPluginFunc)freeImgLibrary->getSymbol("loadPlugin");
-			loadPluginFunc();
-		}
-
-		DynLib* fbxLibrary = gDynLibManager().load("CamelotFBXImporter.dll"); // TODO - Load this automatically somehow
-
-		if(fbxLibrary != nullptr)
-		{
-			typedef const void (*LoadPluginFunc)();
-
-			LoadPluginFunc loadPluginFunc = (LoadPluginFunc)fbxLibrary->getSymbol("loadPlugin");
-			loadPluginFunc();
-		}
+		loadPlugin("CamelotFreeImgImporter"); // TODO - Load this automatically somehow
+		loadPlugin("CamelotFBXImporter"); // TODO - Load this automatically somehow
 
 		//mDbgTexture = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
 		TexturePtr testTex = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
@@ -169,6 +152,8 @@ namespace CamelotEngine
 		mDbgMesh = std::static_pointer_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
 
 		mDbgTexture = testTex;
+
+		loadPlugin("CamelotOISInput"); // TODO - Load this automatically somehow
 	}
 
 	void Application::runMainLoop()
@@ -180,6 +165,7 @@ namespace CamelotEngine
 			DBG_renderSimpleFrame();
 
 			gTime().update();
+			gInput().update();
 		}
 	}
 
@@ -197,6 +183,48 @@ namespace CamelotEngine
 		Time::shutDown();
 	}
 
+	void Application::loadPlugin(const String& pluginName)
+	{
+		String name = pluginName;
+#if CM_PLATFORM == CM_PLATFORM_LINUX
+		// dlopen() does not add .so to the filename, like windows does for .dll
+		if (name.substr(name.length() - 3, 3) != ".so")
+			name += ".so";
+#elif CM_PLATFORM == CM_PLATFORM_APPLE
+		// dlopen() does not add .dylib to the filename, like windows does for .dll
+		if (name.substr(name.length() - 6, 6) != ".dylib")
+			name += ".dylib";
+#elif CM_PLATFORM == CM_PLATFORM_WIN32
+		// Although LoadLibraryEx will add .dll itself when you only specify the library name,
+		// if you include a relative path then it does not. So, add it to be sure.
+		if (name.substr(name.length() - 4, 4) != ".dll")
+			name += ".dll";
+#endif
+
+		DynLib* library = gDynLibManager().load(name);
+
+		if(library != nullptr)
+		{
+			typedef const void (*LoadPluginFunc)();
+
+			LoadPluginFunc loadPluginFunc = (LoadPluginFunc)library->getSymbol("loadPlugin");
+			loadPluginFunc();
+		}
+	}
+
+	UINT32 Application::getAppWindowId()
+	{
+		if(!mRenderWindow)
+		{
+			CM_EXCEPT(InternalErrorException, "Unable to get window handle. No active window is set!");
+		}
+
+		UINT32 windowId;
+		mRenderWindow->getCustomAttribute("WINDOW", &windowId);
+
+		return windowId;
+	}
+
 	void Application::DBG_renderSimpleFrame()
 	{
 		RenderOperation ro;

+ 28 - 8
CamelotRenderer/Source/CmInput.cpp

@@ -2,6 +2,7 @@
 #include "CmTime.h"
 #include "CmMath.h"
 #include "CmRect.h"
+#include "CmDebug.h"
 
 #include <boost/bind.hpp>
 
@@ -12,7 +13,7 @@ namespace CamelotEngine
 
 	Input::Input()
 		:mSmoothHorizontalAxis(0.0f), mSmoothVerticalAxis(0.0f), mCurrentBufferIdx(0), mMouseLastRel(0, 0),
-		mUsingClipRect(false), mClipRect(0, 0, 0, 0)
+		mUsingClipRect(false), mClipRect(0, 0, 0, 0), mInputHandler(nullptr)
 	{ 
 		mHorizontalHistoryBuffer = new float[HISTORY_BUFFER_SIZE];
 		mVerticalHistoryBuffer = new float[HISTORY_BUFFER_SIZE];
@@ -33,23 +34,42 @@ namespace CamelotEngine
 		delete[] mTimesHistoryBuffer;
 	}
 
-	void Input::init(std::shared_ptr<InputHandler> inputHandler, Rect& clipRect)
+	void Input::initClipRect(Rect& clipRect)
 	{
-		mInputHandler = inputHandler;
 		mClipRect = clipRect;
 
 		mUsingClipRect = (clipRect.width > 0 && clipRect.height > 0);
+	}
+
+	void Input::registerInputHandler(InputHandler* inputHandler)
+	{
+		if(mInputHandler != inputHandler)
+		{
+			if(mInputHandler != nullptr)
+				delete mInputHandler;
+
+			mInputHandler = inputHandler;
 
-		mInputHandler->onKeyDown.connect(boost::bind(&Input::keyDown, this, _1));
-		mInputHandler->onKeyUp.connect(boost::bind(&Input::keyUp, this, _1));
+			if(mInputHandler != nullptr)
+			{
+				mInputHandler->onKeyDown.connect(boost::bind(&Input::keyDown, this, _1));
+				mInputHandler->onKeyUp.connect(boost::bind(&Input::keyUp, this, _1));
 
-		mInputHandler->onMouseMoved.connect(boost::bind(&Input::mouseMoved, this, _1));
-		mInputHandler->onMouseDown.connect(boost::bind(&Input::mouseDown, this, _1, _2));
-		mInputHandler->onMouseUp.connect(boost::bind(&Input::mouseUp, this, _1, _2));
+				mInputHandler->onMouseMoved.connect(boost::bind(&Input::mouseMoved, this, _1));
+				mInputHandler->onMouseDown.connect(boost::bind(&Input::mouseDown, this, _1, _2));
+				mInputHandler->onMouseUp.connect(boost::bind(&Input::mouseUp, this, _1, _2));
+			}
+		}
 	}
 
 	void Input::update()
 	{
+		if(mInputHandler == nullptr)
+		{
+			LOGERR("Input handler not initialized!");
+			return;
+		}
+
 		mInputHandler->update();
 
 		updateSmoothInput();