Преглед изворни кода

Splash screen and browse dialogs are now executed on the core thread along with all other windows, to prevent deadlocks when calling win32 methods from one thread while another one is blocking
More work on preparing documentation for Doxygen generation

BearishSun пре 10 година
родитељ
комит
f14a275a31
31 измењених фајлова са 779 додато и 1076 уклоњено
  1. 1 0
      BansheeCore/BansheeCore.vcxproj
  2. 3 0
      BansheeCore/BansheeCore.vcxproj.filters
  3. 1 1
      BansheeCore/Include/BsCoreObject.h
  4. 13 0
      BansheeCore/Include/BsPlatform.h
  5. 1 1
      BansheeCore/Source/BsCoreObject.cpp
  6. 1 1
      BansheeCore/Source/BsCoreObjectCore.cpp
  7. 25 4
      BansheeCore/Source/Win32/BsWin32BrowseDialogs.cpp
  8. 1 3
      BansheeD3D11RenderAPI/Include/BsD3D11Prerequisites.h
  9. 8 14
      BansheeD3D11RenderAPI/Include/BsD3D11RenderTexture.h
  10. 36 104
      BansheeD3D11RenderAPI/Include/BsD3D11RenderWindow.h
  11. 43 73
      BansheeD3D11RenderAPI/Include/BsD3D11Texture.h
  12. 2 4
      BansheeD3D11RenderAPI/Source/BsD3D11RenderWindow.cpp
  13. 20 41
      BansheeD3D9RenderAPI/Include/BsD3D9RenderTexture.h
  14. 36 104
      BansheeD3D9RenderAPI/Include/BsD3D9RenderWindow.h
  15. 38 106
      BansheeD3D9RenderAPI/Include/BsD3D9Texture.h
  16. 2 4
      BansheeD3D9RenderAPI/Source/BsD3D9RenderWindow.cpp
  17. 1 1
      BansheeEditor/Source/BsEditorApplication.cpp
  18. 412 412
      BansheeEditor/Source/BsScenePicking.cpp
  19. 9 9
      BansheeEngine/Include/BsSplashScreen.h
  20. 12 1
      BansheeEngine/Source/BsSplashScreen.cpp
  21. 17 43
      BansheeGLRenderAPI/Include/BsGLRenderTexture.h
  22. 15 40
      BansheeGLRenderAPI/Include/BsGLTexture.h
  23. 30 86
      BansheeGLRenderAPI/Include/Win32/BsWin32RenderWindow.h
  24. 2 4
      BansheeGLRenderAPI/Source/win32/BsWin32RenderWindow.cpp
  25. 0 1
      BansheeUtility/BansheeUtility.vcxproj
  26. 0 3
      BansheeUtility/BansheeUtility.vcxproj.filters
  27. 0 13
      BansheeUtility/Include/BsPlatformUtility.h
  28. 1 0
      BansheeUtility/Include/BsThreadDefines.h
  29. 4 0
      BansheeUtility/Include/Win32/BsWin32Window.h
  30. 42 0
      BansheeUtility/Source/Win32/BsWin32Window.cpp
  31. 3 3
      SBansheeEditor/Source/BsScriptBrowseDialog.cpp

+ 1 - 0
BansheeCore/BansheeCore.vcxproj

@@ -567,6 +567,7 @@
     <ClCompile Include="Source\BsSceneObject.cpp" />
     <ClCompile Include="Source\BsComponent.cpp" />
     <ClCompile Include="Source\BsMaterialParams.cpp" />
+    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp" />
     <ClCompile Include="Source\Win32\BsWin32Platform.cpp" />
     <ClCompile Include="Source\Win32\BsWin32FolderMonitor.cpp" />
   </ItemGroup>

+ 3 - 0
BansheeCore/BansheeCore.vcxproj.filters

@@ -910,5 +910,8 @@
     <ClCompile Include="Source\BsMaterialParams.cpp">
       <Filter>Source Files\Material</Filter>
     </ClCompile>
+    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp">
+      <Filter>Source Files\Platform</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 1
BansheeCore/Include/BsCoreObject.h

@@ -62,7 +62,7 @@ namespace BansheeEngine
 		 * @note	
 		 * If you call this without calling initialize first a deadlock will occur. You should not call this from core thread.
 		 */
-		void blockUntilCoreInitialized();
+		void blockUntilCoreInitialized() const;
 
 		/** Returns an unique identifier for this object. */
 		UINT64 getInternalID() const { return mInternalID; }

+ 13 - 0
BansheeCore/Include/BsPlatform.h

@@ -331,6 +331,19 @@ namespace BansheeEngine
 		/** Destroys a drop target previously created with createDropTarget. */
 		static void destroyDropTarget(OSDropTarget& target);
 
+		/**
+		 * Displays a platform specific file/folder open/save dialog.
+		 *
+		 * @param[in]	type		Type of dialog to open.
+		 * @param[in]	defaultPath	Initial path the dialog will be set to once opened.
+		 * @param[in]	filterList	Semi-colon separated list of file names or types to display in the dialog, 
+		 *							e.g. "exe;txt;png". Ignored if dialog is to display folders instead of files.
+		 * @param[out]	paths		Output list of selected file or folder paths (if any).
+		 * @return					True if file was selected and false if selection was canceled.
+		 */
+		static bool openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
+			Vector<Path>& paths);
+
 		/**
 		 * Message pump. Processes OS messages and returns when it's free.
 		 *

+ 1 - 1
BansheeCore/Source/BsCoreObject.cpp

@@ -80,7 +80,7 @@ namespace BansheeEngine
 		markDependenciesDirty();
 	}
 
-	void CoreObject::blockUntilCoreInitialized()
+	void CoreObject::blockUntilCoreInitialized() const
 	{
 		if (mCoreSpecific != nullptr)
 			mCoreSpecific->synchronize();

+ 1 - 1
BansheeCore/Source/BsCoreObjectCore.cpp

@@ -6,7 +6,7 @@
 namespace BansheeEngine
 {
 	BS_STATIC_THREAD_SYNCHRONISER_CLASS_INSTANCE(mCoreGpuObjectLoadedCondition, CoreObjectCore)
-		BS_STATIC_MUTEX_CLASS_INSTANCE(mCoreGpuObjectLoadedMutex, CoreObjectCore)
+	BS_STATIC_MUTEX_CLASS_INSTANCE(mCoreGpuObjectLoadedMutex, CoreObjectCore)
 
 	CoreObjectCore::CoreObjectCore()
 		:mFlags(0)

+ 25 - 4
BansheeUtility/Source/Win32/BsWin32BrowseDialogs.cpp → BansheeCore/Source/Win32/BsWin32BrowseDialogs.cpp

@@ -1,10 +1,15 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsPrerequisitesUtil.h"
+#include "BsCorePrerequisites.h"
+#include "BsPlatform.h"
+#include "BsAsyncOp.h"
+#include "BsCoreThread.h"
 #include "Win32/BsWin32Window.h"
 #include <atlbase.h>
 #include <ShObjIdl.h>
 
+using namespace std::placeholders;
+
 namespace BansheeEngine
 {
 	void addFiltersToDialog(IFileDialog* fileDialog, const WString& filterList)
@@ -74,8 +79,8 @@ namespace BansheeEngine
 		}
 	}
 
-	bool PlatformUtility::openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
-		Vector<Path>& paths)
+	void openBrowseDialogCore(FileDialogType type, const Path& defaultPath, const WString& filterList,
+		Vector<Path>& paths, AsyncOp& returnValue)
 	{
 		// Init COM library.
 		CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
@@ -118,6 +123,10 @@ namespace BansheeEngine
 		// Show the dialog
 		bool finalResult = false;
 
+		// Need to enable all windows, otherwise when the browse dialog closes the active window will become some 
+		// background window
+		Win32Window::_enableAllWindows();
+
 		if (SUCCEEDED(fileDialog->Show(nullptr)))
 		{
 			if (isMultiselect)
@@ -151,8 +160,20 @@ namespace BansheeEngine
 			finalResult = true;
 		}
 
+		// Restore modal window state (before we enabled all windows)
+		Win32Window::_restoreModalWindows();
+
 		CoUninitialize();
 
-		return finalResult;
+		returnValue._completeOperation(finalResult);
+	}
+
+	bool Platform::openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
+		Vector<Path>& paths)
+	{
+		AsyncOp returnValue = gCoreThread().queueReturnCommand(std::bind(&openBrowseDialogCore, type, 
+			std::cref(defaultPath), std::cref(filterList), std::ref(paths), _1), true);
+
+		return returnValue.getReturnValue<bool>();
 	}
 }

+ 1 - 3
BansheeD3D11RenderAPI/Include/BsD3D11Prerequisites.h

@@ -52,9 +52,7 @@ namespace BansheeEngine
 	class D3D11RenderUtility;
 	class D3D11GpuProgramCore;
 
-	/**
-	 * @brief	DirectX 11 specific types to track resource statistics for.
-	 */
+	/**	DirectX 11 specific types to track resource statistics for. */
 	enum D3D11RenderStatResourceType
 	{
 		RenderStatObject_DepthStencilState = 100,

+ 8 - 14
BansheeD3D11RenderAPI/Include/BsD3D11RenderTexture.h

@@ -11,7 +11,7 @@ namespace BansheeEngine
 	class D3D11RenderTexture;
 
 	/**
-	 * @brief	DirectX 11 implementation of a render texture.
+	 * DirectX 11 implementation of a render texture.
 	 *
 	 * @note	Core thread only.
 	 */
@@ -21,22 +21,18 @@ namespace BansheeEngine
 		D3D11RenderTextureCore(const RENDER_TEXTURE_CORE_DESC& desc);
 		virtual ~D3D11RenderTextureCore() { }
 
-		/**
-		 * @copydoc	RenderTextureCore::getCustomAttribute
-		 */
-		void getCustomAttribute(const String& name, void* pData) const;
+		/** @copydoc RenderTextureCore::getCustomAttribute */
+		void getCustomAttribute(const String& name, void* pData) const override;
 
 	protected:
-		/**
-		 * @copydoc	RenderTextureCore::getProperties
-		 */
-		const RenderTargetProperties& getPropertiesInternal() const { return mProperties; }
+		/** @copydoc RenderTextureCore::getProperties */
+		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
 		RenderTextureProperties mProperties;
 	};
 
 	/**
-	 * @brief	DirectX 11 implementation of a render texture.
+	 * DirectX 11 implementation of a render texture.
 	 *
 	 * @note	Sim thread only.
 	 */
@@ -50,10 +46,8 @@ namespace BansheeEngine
 
 		D3D11RenderTexture(const RENDER_TEXTURE_DESC& desc);
 
-		/**
-		 * @copydoc	RenderTexture::getProperties
-		 */
-		const RenderTargetProperties& getPropertiesInternal() const { return mProperties; }
+		/** @copydoc RenderTexture::getProperties */
+		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
 		RenderTextureProperties mProperties;
 	};

+ 36 - 104
BansheeD3D11RenderAPI/Include/BsD3D11RenderWindow.h

@@ -9,9 +9,7 @@ namespace BansheeEngine
 {
 	class D3D11RenderWindow;
 
-	/**
-	 * @brief	Contains various properties that describe a render window.
-	 */
+	/**	Contains various properties that describe a render window. */
 	class BS_D3D11_EXPORT D3D11RenderWindowProperties : public RenderWindowProperties
 	{
 	public:
@@ -24,147 +22,95 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Render window implementation for Windows and DirectX 11.
+	 * Render window implementation for Windows and DirectX 11.
 	 *
 	 * @note	Core thread only.
 	 */
 	class BS_D3D11_EXPORT D3D11RenderWindowCore : public RenderWindowCore
 	{
 	public:
-		/**
-		 * @copydoc	RenderWindowCore::RenderWindowCore
-		 */
+		/** @copydoc RenderWindowCore::RenderWindowCore */
 		D3D11RenderWindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId,
 			D3D11Device& device, IDXGIFactory* DXGIFactory);
 
 		~D3D11RenderWindowCore();
 
-		/**
-		 * @copydoc RenderWindowCore::move
-		 */
+		/** @copydoc RenderWindowCore::move */
 		void move(INT32 left, INT32 top) override;
 
-		/**
-		 * @copydoc RenderWindowCore::resize
-		 */
+		/** @copydoc RenderWindowCore::resize */
 		void resize(UINT32 width, UINT32 height) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setHidden
-		 */
+		/** @copydoc RenderWindowCore::setHidden */
 		void setHidden(bool hidden) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setActive
-		 */
+		/** @copydoc RenderWindowCore::setActive */
 		void setActive(bool state) override;
 
-		/**
-		 * @copydoc	RenderWindowCore::minimize
-		 */
+		/** @copydoc RenderWindowCore::minimize */
 		void minimize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::maximize
-		 */
+		/** @copydoc RenderWindowCore::maximize */
 		void maximize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::restore
-		 */
+		/** @copydoc RenderWindowCore::restore */
 		void restore() override;
 
-		/**
-		 * @copydoc RenderWindowCore::setFullscreen(UINT32, UINT32, float, UINT32)
-		 */
+		/** @copydoc RenderWindowCore::setFullscreen(UINT32, UINT32, float, UINT32) */
 		void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setFullscreen(const VideoMode&)
-		 */
+		/** @copydoc RenderWindowCore::setFullscreen(const VideoMode&) */
 		void setFullscreen(const VideoMode& mode) override;
 
-		/**
-		* @copydoc RenderWindowCore::setWindowed
-		*/
+		/** @copydoc RenderWindowCore::setWindowed */
 		void setWindowed(UINT32 width, UINT32 height) override;
 
-		/**
-		 * @copydoc RenderWindowCore::copyContentsToMemory
-		 */
+		/** @copydoc RenderWindowCore::copyContentsToMemory */
 		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 
-		/**
-		 * @copydoc RenderWindowCore::swapBuffers
-		 */
+		/** @copydoc RenderWindowCore::swapBuffers */
 		void swapBuffers() override;
 
-		/**
-		 * @copydoc RenderWindowCore::getCustomAttribute
-		 */
+		/** @copydoc RenderWindowCore::getCustomAttribute */
 		void getCustomAttribute(const String& name, void* pData) const override;
 
-		/**
-		 * @copydoc	RenderWindowCore::_windowMovedOrResized
-		 */
+		/** @copydoc RenderWindowCore::_windowMovedOrResized */
 		void _windowMovedOrResized() override;
 
-		/**
-		 * @brief	Returns presentation parameters used for creating the window swap chain.
-		 */
+		/**	Returns presentation parameters used for creating the window swap chain. */
 		DXGI_SWAP_CHAIN_DESC* _getPresentationParameters() { return &mSwapChainDesc; }
 
-		/**
-		 * @brief	Returns internal window handle.
-		 */
+		/**	Returns internal window handle. */
 		HWND _getWindowHandle() const;
 
 	protected:
 		friend class D3D11RenderWindow;
 
-		/**
-		 * @copydoc	CoreObjectCore::initialize
-		 */
+		/** @copydoc CoreObjectCore::initialize */
 		virtual void initialize() override;
 
-		/**
-		 * @brief	Creates internal resources dependent on window size.
-		 */
+		/**	Creates internal resources dependent on window size. */
 		void createSizeDependedD3DResources();
 
-		/**
-		 * @brief	Destroys internal resources dependent on window size.
-		 */
+		/**	Destroys internal resources dependent on window size. */
 		void destroySizeDependedD3DResources();
 
-		/**
-		 * @brief	Queries the current DXGI device. Make sure to release the returned object when done with it.
-		 */
+		/**	Queries the current DXGI device. Make sure to release the returned object when done with it. */
 		IDXGIDevice* queryDxgiDevice(); 
 
-		/**
-		 * @brief	Creates a swap chain for the window.
-		 */
+		/**	Creates a swap chain for the window. */
 		void createSwapChain();
 
-		/**
-		 * @brief	Resizes all buffers attached to the swap chain to the specified size.
-		 */
+		/**	Resizes all buffers attached to the swap chain to the specified size. */
 		void resizeSwapChainBuffers(UINT32 width, UINT32 height);
 
-		/**
-		 * @copydoc	RenderWindowCore::getProperties
-		 */
+		/** @copydoc RenderWindowCore::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
-		/**
-		 * @copydoc	RenderWindowCore::getSyncedProperties
-		 */
+		/** @copydoc RenderWindowCore::getSyncedProperties */
 		RenderWindowProperties& getSyncedProperties() override { return mSyncedProperties; }
 
-		/**
-		 * @copydoc	RenderWindowCore::syncProperties
-		 */
+		/** @copydoc RenderWindowCore::syncProperties */
 		void syncProperties() override;
 
 	protected:
@@ -192,7 +138,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Render window implementation for Windows and DirectX 11.
+	 * Render window implementation for Windows and DirectX 11.
 	 *
 	 * @note	Sim thread only.
 	 */
@@ -201,24 +147,16 @@ namespace BansheeEngine
 	public:
 		~D3D11RenderWindow() { }
 
-		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
+		/** @copydoc RenderWindow::screenToWindowPos */
 		void getCustomAttribute(const String& name, void* pData) const override;
 
-		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
+		/** @copydoc RenderWindow::screenToWindowPos */
 		Vector2I screenToWindowPos(const Vector2I& screenPos) const override;
 
-		/**
-		 * @copydoc RenderWindow::windowToScreenPos
-		 */
+		/** @copydoc RenderWindow::windowToScreenPos */
 		Vector2I windowToScreenPos(const Vector2I& windowPos) const override;
 
-		/**
-		 * @copydoc	RenderWindow::getCore
-		 */
+		/** @copydoc RenderWindow::getCore */
 		SPtr<D3D11RenderWindowCore> getCore() const;
 
 	protected:
@@ -228,19 +166,13 @@ namespace BansheeEngine
 		D3D11RenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 windowId, 
 			D3D11Device& device, IDXGIFactory* DXGIFactory);
 
-		/**
-		 * @copydoc	RenderWindowCore::getProperties
-		 */
+		/** @copydoc RenderWindowCore::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
-		/**
-		 * @copydoc	RenderWindow::syncProperties
-		 */
+		/** @copydoc RenderWindow::syncProperties */
 		void syncProperties() override;
 
-		/**
-		 * @brief	Retrieves internal window handle.
-		 */
+		/**	Retrieves internal window handle. */
 		HWND getHWnd() const;
 
 	private:

+ 43 - 73
BansheeD3D11RenderAPI/Include/BsD3D11Texture.h

@@ -7,9 +7,7 @@
 
 namespace BansheeEngine
 {
-	/**
-	 * @brief	DirectX 11 implementation of a texture.
-	 */
+	/**	DirectX 11 implementation of a texture. */
 	class D3D11TextureCore : public TextureCore
 	{
 	public:
@@ -36,120 +34,92 @@ namespace BansheeEngine
 		D3D11TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
 			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount, const PixelDataPtr& initialData);
 
-		/**
-		* @copydoc	CoreObjectCore::initialize()
-		*/
+		/** @copydoc CoreObjectCore::initialize() */
 		void initialize() override;
 
-		/**
-		 * @copydoc Texture::lockImpl
-		 */
+		/** @copydoc TextureCore::lockImpl */
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0) override;
 
-		/**
-		 * @copydoc Texture::unlockImpl
-		 */
+		/** @copydoc TextureCore::unlockImpl */
 		void unlockImpl() override;
 
-		/**
-		 * @copydoc Texture::copyImpl
-		 */
+		/** @copydoc TextureCore::copyImpl */
 		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target) override;
 
-		/**
-		 * @copydoc Texture::readData
-		 */
+		/** @copydoc TextureCore::readData */
 		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0) override;
 
-		/**
-		 * @copydoc Texture::writeData
-		 */
+		/** @copydoc TextureCore::writeData */
 		void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false) override;
 
-		/**
-		 * @brief	Creates a blank DX11 1D texture object.
-		 */
+		/**	Creates a blank DX11 1D texture object. */
 		void create1DTex();
 
-		/**
-		 * @brief	Creates a blank DX11 2D texture object.
-		 */
+		/**	Creates a blank DX11 2D texture object. */
 		void create2DTex();
 
-		/**
-		 * @brief	Creates a blank DX11 3D texture object.
-		 */
+		/**	Creates a blank DX11 3D texture object. */
 		void create3DTex();
 
 		/**
-		 * @brief	Creates a staging buffer that is used as a temporary buffer for read operations on textures
-		 *			that do not support direct reading.
+		 * Creates a staging buffer that is used as a temporary buffer for read operations on textures that do not support
+		 * direct reading.
 		 */
 		void createStagingBuffer();
 
 		/**
-		 * @brief	Maps the specified texture surface for reading/writing. 
-		 *
-		 * @param	res			Texture resource to map.
-		 * @param	flags		Mapping flags that let the API know what are we planning to do with mapped memory.
-		 * @param	mipLevel	Mip level to map (0 being the base level).
-		 * @param	face		Texture face to map, in case texture has more than one.
-		 * @param	rowPitch	Output size of a single row in bytes.
-		 * @param	slicePitch	Output size of a single slice in bytes (relevant only for 3D textures).
+		 * Maps the specified texture surface for reading/writing. 
 		 *
-		 * @returns	Pointer to the mapped area of memory.
+		 * @param[in]	res			Texture resource to map.
+		 * @param[in]	flags		Mapping flags that let the API know what are we planning to do with mapped memory.
+		 * @param[in]	mipLevel	Mip level to map (0 being the base level).
+		 * @param[in]	face		Texture face to map, in case texture has more than one.
+		 * @param[out]	rowPitch	Output size of a single row in bytes.
+		 * @param[out]	slicePitch	Output size of a single slice in bytes (relevant only for 3D textures).
+		 * @return					Pointer to the mapped area of memory.
 		 *
-		 * @note	Non-staging textures must be dynamic in order to be mapped directly and only for writing.
-		 *			No restrictions are made on staging textures.
+		 * @note	
+		 * Non-staging textures must be dynamic in order to be mapped directly and only for writing. No restrictions are
+		 * made on staging textures.
 		 */
 		void* map(ID3D11Resource* res, D3D11_MAP flags, UINT32 mipLevel, UINT32 face, UINT32& rowPitch, UINT32& slicePitch);
 
-		/**
-		 * @brief	Unmaps a previously mapped texture.
-		 */
+		/**	Unmaps a previously mapped texture. */
 		void unmap(ID3D11Resource* res);
 
 		/**
-		 * @brief	Copies texture data into a staging buffer and maps the staging buffer. Will create a staging
-		 *			buffer if one doesn't already exist (potentially wasting a lot of memory).
-		 *
-		 * @param	flags		Mapping flags that let the API know what are we planning to do with mapped memory.
-		 * @param	mipLevel	Mip level to map (0 being the base level).
-		 * @param	face		Texture face to map, in case texture has more than one.
-		 * @param	rowPitch	Output size of a single row in bytes.
-		 * @param	slicePitch	Output size of a single slice in bytes (relevant only for 3D textures).
+		 * Copies texture data into a staging buffer and maps the staging buffer. Will create a staging buffer if one 
+		 * doesn't already exist (potentially wasting a lot of memory).
 		 *
-		 * @returns	Pointer to the mapped area of memory.
+		 * @param[in]	flags		Mapping flags that let the API know what are we planning to do with mapped memory.
+		 * @param[in]	mipLevel	Mip level to map (0 being the base level).
+		 * @param[in]	face		Texture face to map, in case texture has more than one.
+		 * @param[out]	rowPitch	Output size of a single row in bytes.
+		 * @param[out]	slicePitch	Output size of a single slice in bytes (relevant only for 3D textures).
+		 * @return					Pointer to the mapped area of memory.
 		 */
 		void* mapstagingbuffer(D3D11_MAP flags, UINT32 mipLevel, UINT32 face, UINT32& rowPitch, UINT32& slicePitch);
 
-		/**
-		 * @brief	Unmaps a previously mapped staging buffer.
-		 */
+		/**	Unmaps a previously mapped staging buffer. */
 		void unmapstagingbuffer();
 		
 		/**
-		 * @brief	Maps a static buffer, for writing only. Returned pointer points to temporary CPU memory
-		 *			that will be copied to the mapped resource on "unmap" call.
+		 * Maps a static buffer, for writing only. Returned pointer points to temporary CPU memory that will be copied to
+		 * the mapped resource on "unmap" call.
 		 *
-		 * @param	flags		Mapping flags that let the API know what are we planning to do with mapped memory.
-		 * @param	mipLevel	Mip level to map (0 being the base level).
-		 * @param	face		Texture face to map, in case texture has more than one.
-		 * @param	rowPitch	Output size of a single row in bytes.
-		 * @param	slicePitch	Output size of a single slice in bytes (relevant only for 3D textures).
-		 *
-		 * @returns	Pointer to the mapped area of memory.
+		 * @param[in]	flags		Mapping flags that let the API know what are we planning to do with mapped memory.
+		 * @param[in]	mipLevel	Mip level to map (0 being the base level).
+		 * @param[in]	face		Texture face to map, in case texture has more than one.
+		 * @param[out]	rowPitch	Output size of a single row in bytes.
+		 * @param[out]	slicePitch	Output size of a single slice in bytes (relevant only for 3D textures).
+		 * @return					Pointer to the mapped area of memory.
 		 */
 		void* mapstaticbuffer(PixelData lock, UINT32 mipLevel, UINT32 slice);
 
-		/**
-		 * @brief	Unmaps a previously mapped static buffer and flushes its data to the actual GPU buffer.
-		 */
+		/**	Unmaps a previously mapped static buffer and flushes its data to the actual GPU buffer. */
 		void unmapstaticbuffer();
 
-		/**
-		 * @brief	Creates an empty and uninitialized texture view object.
-		 */
+		/**	Creates an empty and uninitialized texture view object. */
 		TextureViewPtr createView(const SPtr<TextureCore>& texture, const TEXTURE_VIEW_DESC& desc) override;
 
 	protected:

+ 2 - 4
BansheeD3D11RenderAPI/Source/BsD3D11RenderWindow.cpp

@@ -55,8 +55,6 @@ namespace BansheeEngine
 
 	void D3D11RenderWindowCore::initialize()
 	{
-		RenderWindowCore::initialize();
-
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 
 		D3D11RenderWindowProperties& props = mProperties;
@@ -159,6 +157,7 @@ namespace BansheeEngine
 		}
 
 		RenderWindowManager::instance().notifySyncDataDirty(this);
+		RenderWindowCore::initialize();
 	}
 
 	void D3D11RenderWindowCore::swapBuffers()
@@ -748,8 +747,7 @@ namespace BansheeEngine
 
 	HWND D3D11RenderWindow::getHWnd() const
 	{
-		// HACK: I'm accessing core method from sim thread, which means an invalid handle
-		// could be returned here if requested too soon after initialization.
+		blockUntilCoreInitialized();
 		return getCore()->_getWindowHandle();
 	}
 

+ 20 - 41
BansheeD3D9RenderAPI/Include/BsD3D9RenderTexture.h

@@ -11,7 +11,7 @@ namespace BansheeEngine
 	class D3D9RenderTexture;
 
 	/**
-	 * @brief	DirectX 9 implementation of a render texture.
+	 * DirectX 9 implementation of a render texture.
 	 *
 	 * @note	Core thread only.
 	 */
@@ -22,55 +22,36 @@ namespace BansheeEngine
 
 		virtual ~D3D9RenderTextureCore();
 
-		/**
-		 * @copydoc	RenderTextureCore::getCustomAttribute
-		 */
-		virtual void getCustomAttribute(const String& name, void* pData) const;
+		/** @copydoc RenderTextureCore::getCustomAttribute */
+		void getCustomAttribute(const String& name, void* pData) const override;
 
-		/**
-		 * @copydoc	D3D9Resource::notifyOnDeviceCreate
-		 */
-		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
+		/** @copydoc D3D9Resource::notifyOnDeviceCreate */
+		void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) override;
 
-		/**
-		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
-		 */
-		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
+		/** @copydoc D3D9Resource::notifyOnDeviceDestroy */
+		void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) override;
 
-		/**
-		 * @copydoc	D3D9Resource::notifyOnDeviceLost
-		 */
-		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
+		/** @copydoc D3D9Resource::notifyOnDeviceLost */
+		void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) override;
 
-		/**
-		 * @copydoc	D3D9Resource::notifyOnDeviceReset
-		 */
-		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
+		/** @copydoc D3D9Resource::notifyOnDeviceReset */
+		void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) override;
 
 	protected:
 		friend class D3D9RenderTexture;
 
-		/**
-		 * @copydoc	CoreObjectCore::initialize
-		 */
-		virtual void initialize();
+		/** @copydoc CoreObjectCore::initialize */
+		void initialize() override;
 
-		/**
-		 * @brief	Initializes the internal color and depth surfaces.
-		 */
+		/**	Initializes the internal color and depth surfaces. */
 		void initializeSurfaces();
 
-		/**
-		 * @brief	Releases the internal color and depth surfaces.
-		 */
+		/**	Releases the internal color and depth surfaces. */
 		void releaseSurfaces();
 
-		/**
-		 * @copydoc	RenderTextureCore::getProperties
-		 */
-		const RenderTargetProperties& getPropertiesInternal() const { return mProperties; }
+		/** @copydoc RenderTextureCore::getProperties */
+		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
-	protected:
 		IDirect3DSurface9* mDX9ColorSurface;
 		IDirect3DSurface9* mDX9DepthStencilSurface;
 		bool mIsBindableToShader;
@@ -78,7 +59,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	DirectX 9 implementation of a render texture.
+	 * DirectX 9 implementation of a render texture.
 	 *
 	 * @note	Sim thread only.
 	 */
@@ -92,10 +73,8 @@ namespace BansheeEngine
 
 		D3D9RenderTexture(const RENDER_TEXTURE_DESC& desc);
 
-		/**
-		 * @copydoc	RenderTexture::getProperties
-		 */
-		const RenderTargetProperties& getPropertiesInternal() const { return mProperties; }
+		/** @copydoc RenderTexture::getProperties */
+		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
 		RenderTextureProperties mProperties;
 	};

+ 36 - 104
BansheeD3D9RenderAPI/Include/BsD3D9RenderWindow.h

@@ -10,9 +10,7 @@ namespace BansheeEngine
 {
 	class D3D9RenderWindow;
 
-	/**
-	 * @brief	Contains various properties that describe a render window.
-	 */
+	/**	Contains various properties that describe a render window. */
 	class BS_D3D9_EXPORT D3D9RenderWindowProperties : public RenderWindowProperties
 	{
 	public:
@@ -25,7 +23,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Render window implementation for Windows.
+	 * Render window implementation for Windows.
 	 *
 	 * @note	Core thread only.
 	 */
@@ -35,137 +33,85 @@ namespace BansheeEngine
 		D3D9RenderWindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId, HINSTANCE instance);
 		~D3D9RenderWindowCore();
 		
-		/**
-		 * @copydoc RenderWindowCore::setFullscreen(UINT32, UINT32, float, UINT32)
-		 */
+		/** @copydoc RenderWindowCore::setFullscreen(UINT32, UINT32, float, UINT32) */
 		void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setFullscreen(const VideoMode&)
-		 */
+		/** @copydoc RenderWindowCore::setFullscreen(const VideoMode&) */
 		void setFullscreen(const VideoMode& mode) override;
 
-		/**
-		* @copydoc RenderWindowCore::setWindowed
-		*/
+		/** @copydoc RenderWindowCore::setWindowed */
 		void setWindowed(UINT32 width, UINT32 height) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setActive
-		 */
+		/** @copydoc RenderWindowCore::setActive */
 		virtual void setActive(bool state) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setHidden
-		 */
+		/** @copydoc RenderWindowCore::setHidden */
 		void setHidden(bool hidden) override;
 
-		/**
-		 * @copydoc	RenderWindowCore::minimize
-		 */
+		/** @copydoc RenderWindowCore::minimize */
 		void minimize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::maximize
-		 */
+		/** @copydoc RenderWindowCore::maximize */
 		void maximize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::restore
-		 */
+		/** @copydoc RenderWindowCore::restore */
 		void restore() override;
 
-		/**
-		 * @copydoc RenderWindowCore::move
-		 */
+		/** @copydoc RenderWindowCore::move */
 		void move(INT32 left, INT32 top) override;
 
-		/**
-		 * @copydoc RenderWindowCore::resize
-		 */
+		/** @copydoc RenderWindowCore::resize */
 		void resize(UINT32 width, UINT32 height) override;
 
-		/**
-		 * @copydoc RenderWindowCore::getCustomAttribute
-		 */
+		/** @copydoc RenderWindowCore::getCustomAttribute */
 		void getCustomAttribute(const String& name, void* pData) const override;
 
-		/**
-		 * @copydoc RenderWindowCore::copyContentsToMemory
-		 */
+		/** @copydoc RenderWindowCore::copyContentsToMemory */
 		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 
-		/**
-		 * @copydoc RenderWindowCore::swapBuffers
-		 */
+		/** @copydoc RenderWindowCore::swapBuffers */
 		void swapBuffers() override;
 
-		/**
-		 * @copydoc RenderWindowCore::_windowMovedOrResized
-		 */
+		/** @copydoc RenderWindowCore::_windowMovedOrResized */
 		void _windowMovedOrResized() override;
 
-		/**
-		 * @brief	Gets internal Win32 window handle.
-		 */
+		/**	Gets internal Win32 window handle. */
 		HWND _getWindowHandle() const;
 
-		/**
-		 * @brief	Gets the DirectX 9 device object that manages this window.
-		 */
+		/**	Gets the DirectX 9 device object that manages this window. */
 		IDirect3DDevice9* _getD3D9Device() const;
 
-		/**
-		 * @brief	Gets the device that manages this window.
-		 */
+		/**	Gets the device that manages this window. */
 		D3D9Device* _getDevice() const;
 
-		/**
-		 * @brief	Sets the device that manages this window.
-		 */
+		/**	Sets the device that manages this window. */
 		void _setDevice(D3D9Device* device);
 
-		/**
-		 * @brief	Build the presentation parameters used with this window.
-		 */
+		/**	Build the presentation parameters used with this window. */
 		void _buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) const;
 
-		/**
-		 * @brief	Accessor for render surface.
-		 */
+		/**	Accessor for render surface. */
 		IDirect3DSurface9* _getRenderSurface() const;
 	
-		/**
-		 * @brief	Returns true if this window use depth buffer.
-		 */
+		/**	Returns true if this window use depth buffer. */
 		bool _isDepthBuffered() const;
 
-		/**
-		 * @brief	Validate the device for this window.
-		 */
+		/**	Validate the device for this window. */
 		bool _validateDevice();
 		
 	protected:
 		friend class D3D9RenderWindow;
 
-		/**
-		 * @copydoc	CoreObjectCore::initialize
-		 */
+		/** @copydoc CoreObjectCore::initialize */
 		virtual void initialize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::getProperties
-		 */
+		/** @copydoc RenderWindowCore::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
-		/**
-		 * @copydoc	RenderWindowCore::getSyncedProperties
-		 */
+		/** @copydoc RenderWindowCore::getSyncedProperties */
 		RenderWindowProperties& getSyncedProperties() override { return mSyncedProperties; }
 
-		/**
-		 * @copydoc	RenderWindowCore::syncProperties
-		 */
+		/** @copydoc RenderWindowCore::syncProperties */
 		void syncProperties() override;
 
 	protected:
@@ -186,7 +132,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Render window implementation for Windows.
+	 * Render window implementation for Windows.
 	 *
 	 * @note	Sim thread only.
 	 */
@@ -195,24 +141,16 @@ namespace BansheeEngine
 	public:
 		~D3D9RenderWindow() { }
 
-		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
+		/** @copydoc RenderWindow::screenToWindowPos */
 		void getCustomAttribute(const String& name, void* pData) const override;
 
-		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
+		/** @copydoc RenderWindow::screenToWindowPos */
 		Vector2I screenToWindowPos(const Vector2I& screenPos) const override;
 
-		/**
-		 * @copydoc RenderWindow::windowToScreenPos
-		 */
+		/** @copydoc RenderWindow::windowToScreenPos */
 		Vector2I windowToScreenPos(const Vector2I& windowPos) const override;
 
-		/**
-		 * @copydoc	RenderWindow::getCore
-		 */
+		/** @copydoc RenderWindow::getCore */
 		SPtr<D3D9RenderWindowCore> getCore() const;
 
 	protected:
@@ -221,19 +159,13 @@ namespace BansheeEngine
 
 		D3D9RenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 windowId, HINSTANCE instance);
 
-		/**
-		 * @copydoc	RenderWindowCore::getProperties
-		 */
+		/** @copydoc RenderWindowCore::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
-		/**
-		 * @copydoc	RenderWindow::syncProperties
-		 */
+		/** @copydoc RenderWindow::syncProperties */
 		void syncProperties() override;
 
-		/**
-		 * @brief	Retrieves internal window handle.
-		 */
+		/**	Retrieves internal window handle. */
 		HWND getHWnd() const;
 
 	private:

+ 38 - 106
BansheeD3D9RenderAPI/Include/BsD3D9Texture.h

@@ -4,22 +4,16 @@
 
 #include "BsD3D9Prerequisites.h"
 #include "BsTexture.h"
-#include "BsRenderTexture.h"
-#include "BsException.h"
 #include "BsD3D9PixelBuffer.h"
 #include "BsD3D9Resource.h"
 
 namespace BansheeEngine 
 {
-	/**
-	 * @brief	DirectX 9 implementation of a texture.
-	 */
+	/**	DirectX 9 implementation of a texture. */
 	class BS_D3D9_EXPORT D3D9TextureCore : public TextureCore, public D3D9Resource
 	{
 	protected:
-		/**
-		 * @brief	Container for internal resources.
-		 */
+		/**	Container for internal resources. */
 		struct TextureResources
 		{
 			IDirect3DTexture9* pNormTex;
@@ -33,37 +27,27 @@ namespace BansheeEngine
 	public:
 		~D3D9TextureCore();
 
-		/**
-		 * @copydoc Texture::isBindableAsShaderResource
-		 */
+		/** @copydoc Texture::isBindableAsShaderResource */
 		bool isBindableAsShaderResource() const override { return mIsBindableAsShaderResource; }
 
-		/**
-		 * @brief	Returns internal DirectX 9 texture object.
-		 */
+		/**	Returns internal DirectX 9 texture object. */
 		IDirect3DBaseTexture9* getTexture_internal();	
 
-		/**
-		 * @brief	Returns internal DirectX 9 texture object pointing to a 1D or 2D texture.
-		 */
+		/**	Returns internal DirectX 9 texture object pointing to a 1D or 2D texture. */
 		IDirect3DTexture9* getNormTexture_internal();
 
-		/**
-		 * @brief	Returns internal DirectX 9 texture object pointing to a cube texture.
-		 */
+		/**	Returns internal DirectX 9 texture object pointing to a cube texture. */
 		IDirect3DCubeTexture9* getCubeTexture_internal();
 
-		/**
-		 * @brief	Indicates whether the hardware gamma is enabled and supported.
-		 */
+		/**	Indicates whether the hardware gamma is enabled and supported. */
 		bool isHardwareGammaReadToBeUsed() const { return mProperties.isHardwareGammaEnabled() && mHwGammaReadSupported; }
 					
 		/**
-		 * @brief	Returns a hardware pixel buffer for a certain face and level of the texture.
+		 * Returns a hardware pixel buffer for a certain face and level of the texture.
 		 * 
-		 * @param	face	Index of the texture face, if texture has more than one. Array index for
-		 *					texture arrays and a cube face for cube textures.
-		 * @param	mipmap	Index of the mip level. 0 being the largest mip level.
+		 * @param[in]	face	Index of the texture face, if texture has more than one. Array index for texture arrays and
+		 *						a cube face for cube textures.
+		 * @param[in]	mipmap	Index of the mip level. 0 being the largest mip level.
 		 *
 		 * @note	Cube face indices: +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)
 		 */
@@ -74,19 +58,13 @@ namespace BansheeEngine
 		 */
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) override;
 
-		/**
-		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
-		 */
+		/** @copydoc D3D9Resource::notifyOnDeviceDestroy */
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) override;
 
-		/**
-		 * @copydoc	D3D9Resource::notifyOnDeviceLost
-		 */
+		/** @copydoc D3D9Resource::notifyOnDeviceLost */
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) override;
 
-		/**
-		 * @copydoc	D3D9Resource::notifyOnDeviceReset
-		 */
+		/** @copydoc D3D9Resource::notifyOnDeviceReset */
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) override;
 
 	protected:	
@@ -96,123 +74,77 @@ namespace BansheeEngine
 		D3D9TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
 			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount, const PixelDataPtr& initialData);
 
-		/**
-		 * @copydoc TextureCore::initialize
-		 */
+		/** @copydoc TextureCore::initialize */
 		void initialize() override;
 		
-		/**
-		 * @copydoc TextureCore::lock
-		 */
+		/** @copydoc TextureCore::lock */
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0) override;
 
-		/**
-		 * @copydoc TextureCore::unlock
-		 */
+		/** @copydoc TextureCore::unlock */
 		void unlockImpl() override;
 
-		/**
-		 * @copydoc TextureCore::copy
-		 */
+		/** @copydoc TextureCore::copy */
 		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target) override;
 
-		/**
-		 * @copydoc TextureCore::readData
-		 */
+		/** @copydoc TextureCore::readData */
 		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0) override;
 
-		/**
-		 * @copydoc TextureCore::writeData
-		 */
+		/** @copydoc TextureCore::writeData */
 		void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false) override;
 
-		/**
-		 * @brief	Returns true if the texture should be allocated in the default pool.
-		 */
+		/**	Returns true if the texture should be allocated in the default pool. */
 		bool useDefaultPool();
 
-		/**
-		 * @brief	Creates a DirectX object for blank normal 1D/2D texture.
-		 */
+		/**	Creates a DirectX object for blank normal 1D/2D texture. */
 		void createNormTex(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @brief	Creates a DirectX object for blank cube texture.
-		 */
+		/**	Creates a DirectX object for blank cube texture. */
 		void createCubeTex(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @brief	Creates a DirectX object for blank volume (3D) texture.
-		 */	
+		/**	Creates a DirectX object for blank volume (3D) texture. */	
 		void createVolumeTex(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @brief	Selects a DirectX 9 pixel format depending on requested format
-		 *			and device capabilities.
-		 */
+		/**	Selects a DirectX 9 pixel format depending on requested format and device capabilities. */
 		D3DFORMAT chooseD3DFormat(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @copydoc	Texture::calculateSize
-		 */
+		/** @copydoc Texture::calculateSize */
 		UINT32 calculateSize() const;
 
-		/**
-		 * @brief	Creates internal resources for the texture for the specified device.
-		 */
+		/**	Creates internal resources for the texture for the specified device. */
 		void createInternalResources(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @brief	Updates texture attributes with final attributes provided by the API after
-		 *			the texture has been created.
-		 */
+		/** Updates texture attributes with final attributes provided by the API after the texture has been created. */
 		void setFinalAttributes(IDirect3DDevice9* d3d9Device, TextureResources* textureResources, 
 			UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
 
-		/**
-		 * @brief	Returns best texture filtering method.
-		 */
+		/**	Returns best texture filtering method. */
 		D3DTEXTUREFILTERTYPE getBestFilterMethod(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @brief	Returns if the specified combination of texture type, format and usage supports dynamic texture usage.
-		 */
+		/**	Returns if the specified combination of texture type, format and usage supports dynamic texture usage. */
 		bool canUseDynamicTextures(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat);
 
-		/**
-		 * @brief	Returns if the specified combination of texture type, format and usage supports automatic mipmap generation.
-		 */
+		/**	Returns if the specified combination of texture type, format and usage supports automatic mipmap generation. */
 		bool canAutoGenMipmaps(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat);
 
-		/**
-		 * @brief	Returns if the specified combination of texture type, format and usage supports hardware gamma.
-		 */
+		/**	Returns if the specified combination of texture type, format and usage supports hardware gamma. */
 		bool canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting);
 
 		/**
-		 * @brief	Creates a list of pixel buffers for all surfaces in the texture. This must be called after the texture
-		 *			has been created.
+		 * Creates a list of pixel buffers for all surfaces in the texture. This must be called after the texture has been
+		 * created.
 		 */
 		void createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources);
 	 
-		/**
-		 * @brief	Retrieves texture resources for the device, or null if they don't exist.
-		 */
+		/**	Retrieves texture resources for the device, or null if they don't exist. */
 		TextureResources* getTextureResources(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @brief	Allocates a new set of texture resources for the device.
-		 */
+		/**	Allocates a new set of texture resources for the device. */
 		TextureResources* allocateTextureResources(IDirect3DDevice9* d3d9Device);
 
-		/**
-		 * @brief	Frees all the given texture resources.
-		 */
+		/**	Frees all the given texture resources. */
 		void freeTextureResources(IDirect3DDevice9* d3d9Device, TextureResources* textureResources);
 
-		/**
-		 * @brief	Determines the pool in which to create the texture in.
-		 */
+		/**	Determines the pool in which to create the texture in. */
 		void determinePool();
 
 	protected:

+ 2 - 4
BansheeD3D9RenderAPI/Source/BsD3D9RenderWindow.cpp

@@ -47,8 +47,6 @@ namespace BansheeEngine
 
 	void D3D9RenderWindowCore::initialize()
 	{
-		RenderWindowCore::initialize();
-
 		D3D9RenderWindowProperties& props = mProperties;
 
 		mMultisampleType = D3DMULTISAMPLE_NONE;
@@ -119,6 +117,7 @@ namespace BansheeEngine
 		}
 
 		RenderWindowManager::instance().notifySyncDataDirty(this);
+		RenderWindowCore::initialize();
 	}
 
 	void D3D9RenderWindowCore::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
@@ -576,8 +575,7 @@ namespace BansheeEngine
 
 	HWND D3D9RenderWindow::getHWnd() const
 	{
-		// HACK: I'm accessing core method from sim thread, which means an invalid handle
-		// could be returned here if requested too soon after initialization.
+		blockUntilCoreInitialized();
 		return getCore()->_getWindowHandle();
 	}
 

+ 1 - 1
BansheeEditor/Source/BsEditorApplication.cpp

@@ -80,8 +80,8 @@ namespace BansheeEngine
 
 	void EditorApplication::onStartUp()
 	{
-		SplashScreen::show();
 		Application::onStartUp();
+		SplashScreen::show();
 
 		// In editor we render game on a separate surface, handled in Game window
 		SceneManager::instance().setMainRenderTarget(nullptr);

+ 412 - 412
BansheeEditor/Source/BsScenePicking.cpp

@@ -1,415 +1,415 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsScenePicking.h"
-#include "BsSceneManager.h"
-#include "BsColor.h"
-#include "BsMatrix4.h"
-#include "BsDebug.h"
-#include "BsMath.h"
-#include "BsCRenderable.h"
-#include "BsSceneObject.h"
-#include "BsMesh.h"
-#include "BsConvexVolume.h"
-#include "BsCCamera.h"
-#include "BsCoreThread.h"
-#include "BsRenderAPI.h"
-#include "BsMaterial.h"
-#include "BsPass.h"
-#include "BsBlendState.h"
-#include "BsDepthStencilState.h"
-#include "BsRasterizerState.h"
-#include "BsRenderTarget.h"
-#include "BsPixelData.h"
-#include "BsGpuParams.h"
-#include "BsBuiltinEditorResources.h"
-#include "BsShader.h"
-#include "BsCoreRenderer.h"
-#include "BsGizmoManager.h"
-#include "BsRendererUtility.h"
-
-using namespace std::placeholders;
-
-namespace BansheeEngine
-{
-	const float ScenePickingCore::ALPHA_CUTOFF = 0.5f;
-
-	ScenePicking::ScenePicking()
-	{
-		mCore = bs_new<ScenePickingCore>();
-
-		for (UINT32 i = 0; i < 3; i++)
-		{
-			HMaterial matPicking = BuiltinEditorResources::instance().createPicking((CullingMode)i);
-			HMaterial matPickingAlpha = BuiltinEditorResources::instance().createPickingAlpha((CullingMode)i);
-
-			mCore->mMaterialData[i].mMatPickingCore = matPicking->getCore();
-			mCore->mMaterialData[i].mMatPickingAlphaCore = matPickingAlpha->getCore();
-		}
-
-		gCoreAccessor().queueCommand(std::bind(&ScenePickingCore::initialize, mCore));
-	}
-
-	ScenePicking::~ScenePicking()
-	{
-		gCoreAccessor().queueCommand(std::bind(&ScenePickingCore::destroy, mCore));
-	}
-
-	HSceneObject ScenePicking::pickClosestObject(const CameraPtr& cam, const Vector2I& position, const Vector2I& area)
-	{
-		Vector<HSceneObject> selectedObjects = pickObjects(cam, position, area);
-		if (selectedObjects.size() == 0)
-			return HSceneObject();
-
-		return selectedObjects[0];
-	}
-
-	Vector<HSceneObject> ScenePicking::pickObjects(const CameraPtr& cam, const Vector2I& position, const Vector2I& area)
-	{
-		auto comparePickElement = [&] (const ScenePicking::RenderablePickData& a, const ScenePicking::RenderablePickData& b)
-		{
-			// Sort by alpha setting first, then by cull mode, then by index
-			if (a.alpha == b.alpha)
-			{
-				if (a.cullMode == b.cullMode)
-					return a.index > b.index;
-				else
-					return (UINT32)a.cullMode > (UINT32)b.cullMode;
-			}
-			else
-				return (UINT32)a.alpha > (UINT32)b.alpha;
-		};
-
-		Matrix4 viewProjMatrix = cam->getProjectionMatrixRS() * cam->getViewMatrix();
-
-		const Map<Renderable*, SceneRenderableData>& renderables = SceneManager::instance().getAllRenderables();
-		RenderableSet pickData(comparePickElement);
-		Map<UINT32, HSceneObject> idxToRenderable;
-
-		for (auto& renderableData : renderables)
-		{
-			RenderablePtr renderable = renderableData.second.renderable;
-			HSceneObject so = renderableData.second.sceneObject;
-
-			if (!so->getActive())
-				continue;
-
-			HMesh mesh = renderable->getMesh();
-			if (!mesh.isLoaded())
-				continue;
-
-			Bounds worldBounds = mesh->getProperties().getBounds();
-			Matrix4 worldTransform = so->getWorldTfrm();
-			worldBounds.transformAffine(worldTransform);
-
-			// TODO - I could limit the frustum to the visible area we're rendering for a speed boost
-			// but this is unlikely to be a performance bottleneck
-			const ConvexVolume& frustum = cam->getWorldFrustum();
-			if (frustum.intersects(worldBounds.getSphere()))
-			{
-				// More precise with the box
-				if (frustum.intersects(worldBounds.getBox()))
-				{
-					for (UINT32 i = 0; i < mesh->getProperties().getNumSubMeshes(); i++)
-					{
-						UINT32 idx = (UINT32)pickData.size();
-
-						bool useAlphaShader = false;
-						RasterizerStatePtr rasterizerState;
-
-						HMaterial originalMat = renderable->getMaterial(i);
-						if (originalMat != nullptr && originalMat->getNumPasses() > 0)
-						{
-							PassPtr firstPass = originalMat->getPass(0); // Note: We only ever check the first pass, problem?
-							useAlphaShader = firstPass->hasBlending();
-
-							if (firstPass->getRasterizerState() == nullptr)
-								rasterizerState = RasterizerState::getDefault();
-							else
-								rasterizerState = firstPass->getRasterizerState();
-						}
-						else
-							rasterizerState = RasterizerState::getDefault();
-
-						CullingMode cullMode = rasterizerState->getProperties().getCullMode();
-
-						HTexture mainTexture;
-						if (useAlphaShader)
-						{
-							const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams = originalMat->getShader()->getTextureParams();
-							for (auto& objectParam : textureParams)
-							{
-								if (objectParam.second.rendererSemantic == RPS_Diffuse)
-								{
-									mainTexture = originalMat->getTexture(objectParam.first);
-									break;
-								}
-							}
-						}
-
-						idxToRenderable[idx] = so;
-
-						Matrix4 wvpTransform = viewProjMatrix * worldTransform;
-						pickData.insert({ mesh->getCore(), idx, wvpTransform, useAlphaShader, cullMode, mainTexture });
-					}
-				}
-			}
-		}
-
-		UINT32 firstGizmoIdx = (UINT32)pickData.size();
-
-		SPtr<RenderTargetCore> target = cam->getViewport()->getTarget()->getCore();
-		gCoreAccessor().queueCommand(std::bind(&ScenePickingCore::corePickingBegin, mCore, target,
-			cam->getViewport()->getNormArea(), std::cref(pickData), position, area));
-
-		GizmoManager::instance().renderForPicking(cam, [&](UINT32 inputIdx) { return encodeIndex(firstGizmoIdx + inputIdx); });
-
-		AsyncOp op = gCoreAccessor().queueReturnCommand(std::bind(&ScenePickingCore::corePickingEnd, mCore, target, 
-			cam->getViewport()->getNormArea(), position, area, _1));
-		gCoreAccessor().submitToCoreThread(true);
-
-		assert(op.hasCompleted());
-
-		Vector<UINT32>& selectedObjects = op.getReturnValue<Vector<UINT32>>();
-		Vector<HSceneObject> results;
-
-		for (auto& selectedObjectIdx : selectedObjects)
-		{
-			if (selectedObjectIdx < firstGizmoIdx)
-			{
-				auto iterFind = idxToRenderable.find(selectedObjectIdx);
-
-				if (iterFind != idxToRenderable.end())
-					results.push_back(iterFind->second);
-			}
-			else
-			{
-				UINT32 gizmoIdx = selectedObjectIdx - firstGizmoIdx;
-
-				HSceneObject so = GizmoManager::instance().getSceneObject(gizmoIdx);
-				if (so)
-					results.push_back(so);
-			}
-		}
-
-		return results;
-	}
-
-	Color ScenePicking::encodeIndex(UINT32 index)
-	{
-		Color encoded;
-		encoded.r = (index & 0xFF) / 255.0f;
-		encoded.g = ((index >> 8) & 0xFF) / 255.0f;
-		encoded.b = ((index >> 16) & 0xFF) / 255.0f;
-		encoded.a = 1.0f;
-
-		if (((index >> 24) & 0xFF))
-			LOGERR("Index when picking out of valid range.");
-
-		return encoded;
-	}
-
-	UINT32 ScenePicking::decodeIndex(Color color)
-	{
-		UINT32 r = Math::roundToInt(color.r * 255.0f);
-		UINT32 g = Math::roundToInt(color.g * 255.0f);
-		UINT32 b = Math::roundToInt(color.b * 255.0f);
-
-		return (r & 0xFF) | ((g & 0xFF) << 8) | ((b & 0xFF) << 16);
-	}
-
-	void ScenePickingCore::initialize()
-	{
-		for (UINT32 i = 0; i < 3; i++)
-		{
-			MaterialData& md = mMaterialData[i];
-
-			{
-				SPtr<PassParametersCore> passParams = md.mMatPickingCore->getPassParameters(0);
-
-				md.mParamPickingVertParams = passParams->mVertParams;
-				md.mParamPickingVertParams->getParam("matWorldViewProj", md.mParamPickingWVP);
-
-				md.mParamPickingFragParams = passParams->mFragParams;
-				md.mParamPickingFragParams->getParam("colorIndex", md.mParamPickingColor);
-			}
-
-			{
-				SPtr<PassParametersCore> passParams = md.mMatPickingAlphaCore->getPassParameters(0);
-
-				md.mParamPickingAlphaVertParams = passParams->mVertParams;
-				md.mParamPickingAlphaVertParams->getParam("matWorldViewProj", md.mParamPickingAlphaWVP);
-
-				md.mParamPickingAlphaFragParams = passParams->mFragParams;
-
-				md.mParamPickingAlphaFragParams->getParam("colorIndex", md.mParamPickingAlphaColor);
-				md.mParamPickingAlphaFragParams->getTextureParam("mainTexture", md.mParamPickingAlphaTexture);
-
-				GpuParamFloatCore alphaCutoffParam;
-				md.mParamPickingAlphaFragParams->getParam("alphaCutoff", alphaCutoffParam);
-				alphaCutoffParam.set(ALPHA_CUTOFF);
-			}
-		}
-	}
-
-	void ScenePickingCore::destroy()
-	{
-		bs_delete(this);
-	}
-
-	void ScenePickingCore::corePickingBegin(const SPtr<RenderTargetCore>& target, const Rect2& viewportArea,
-		const ScenePicking::RenderableSet& renderables, const Vector2I& position, const Vector2I& area)
-	{
-		RenderAPICore& rs = RenderAPICore::instance();
-
-		rs.beginFrame();
-		rs.setRenderTarget(target);
-		rs.setViewport(viewportArea);
-		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
-		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
-
-		gRendererUtility().setPass(mMaterialData[0].mMatPickingCore, 0);
-		bool activeMaterialIsAlpha = false;
-		CullingMode activeMaterialCull = (CullingMode)0;
-
-		for (auto& renderable : renderables)
-		{
-			if (activeMaterialIsAlpha != renderable.alpha || activeMaterialCull != renderable.cullMode)
-			{
-				activeMaterialIsAlpha = renderable.alpha;
-				activeMaterialCull = renderable.cullMode;
-
-				if (activeMaterialIsAlpha)
-					gRendererUtility().setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingAlphaCore, 0);
-				else
-					gRendererUtility().setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingCore, 0);
-			}
-
-			Color color = ScenePicking::encodeIndex(renderable.index);
-			MaterialData& md = mMaterialData[(UINT32)activeMaterialCull];
-
-			if (activeMaterialIsAlpha)
-			{
-				md.mParamPickingAlphaWVP.set(renderable.wvpTransform);
-				md.mParamPickingAlphaColor.set(color);
-				md.mParamPickingAlphaTexture.set(renderable.mainTexture->getCore());
-
-				rs.setGpuParams(GPT_VERTEX_PROGRAM, md.mParamPickingAlphaVertParams);
-				rs.setGpuParams(GPT_FRAGMENT_PROGRAM, md.mParamPickingAlphaFragParams);
-			}
-			else
-			{
-				md.mParamPickingWVP.set(renderable.wvpTransform);
-				md.mParamPickingColor.set(color);
-
-				rs.setGpuParams(GPT_VERTEX_PROGRAM, md.mParamPickingVertParams);
-				rs.setGpuParams(GPT_FRAGMENT_PROGRAM, md.mParamPickingFragParams);
-			}
-
-			UINT32 numSubmeshes = renderable.mesh->getProperties().getNumSubMeshes();
-
-			for (UINT32 i = 0; i < numSubmeshes; i++)
-				gRendererUtility().draw(renderable.mesh, renderable.mesh->getProperties().getSubMesh(i));
-		}
-	}
-
-	void ScenePickingCore::corePickingEnd(const SPtr<RenderTargetCore>& target, const Rect2& viewportArea, const Vector2I& position,
-		const Vector2I& area, AsyncOp& asyncOp)
-	{
-		const RenderTargetProperties& rtProps = target->getProperties();
-
-		if (rtProps.isWindow())
-		{
-			// TODO: When I do implement this then I will likely want a method in RenderTarget that unifies both render window and render texture readback
-			BS_EXCEPT(NotImplementedException, "Picking is not supported on render windows as framebuffer readback methods aren't implemented");
-		}
-
-		SPtr<RenderTextureCore> rtt = std::static_pointer_cast<RenderTextureCore>(target);
-		SPtr<TextureCore> outputTexture = rtt->getBindableColorTexture();
-
-		if (position.x < 0 || position.x >= (INT32)outputTexture->getProperties().getWidth() ||
-			position.y < 0 || position.y >= (INT32)outputTexture->getProperties().getHeight())
-		{
-			asyncOp._completeOperation(Vector<UINT32>());
-			return;
-		}
-
-		PixelDataPtr outputPixelData = outputTexture->getProperties().allocateSubresourceBuffer(0);
-		AsyncOp unused;
-
-		RenderAPICore& rs = RenderAPICore::instance();
-
-		rs.endFrame();
-		outputTexture->readSubresource(0, *outputPixelData);
-
-		Map<UINT32, UINT32> selectionScores;
-		UINT32 numPixels = outputPixelData->getWidth() * outputPixelData->getHeight();
-
-		UINT32 maxWidth = std::min((UINT32)(position.x + area.x), outputPixelData->getWidth());
-		UINT32 maxHeight = std::min((UINT32)(position.y + area.y), outputPixelData->getHeight());
-
-		if (rtProps.requiresTextureFlipping())
-		{
-			UINT32 vertOffset = outputPixelData->getHeight() - 1;
-
-			for (UINT32 y = maxHeight; y > (UINT32)position.y; y--)
-			{
-				for (UINT32 x = (UINT32)position.x; x < maxWidth; x++)
-				{
-					Color color = outputPixelData->getColorAt(x, vertOffset - y);
-					UINT32 index = ScenePicking::decodeIndex(color);
-
-					if (index == 0x00FFFFFF) // Nothing selected
-						continue;
-
-					auto iterFind = selectionScores.find(index);
-					if (iterFind == selectionScores.end())
-						selectionScores[index] = 1;
-					else
-						iterFind->second++;
-				}
-			}
-		}
-		else
-		{
-			for (UINT32 y = (UINT32)position.y; y < maxHeight; y++)
-			{
-				for (UINT32 x = (UINT32)position.x; x < maxWidth; x++)
-				{
-					Color color = outputPixelData->getColorAt(x, y);
-					UINT32 index = ScenePicking::decodeIndex(color);
-
-					if (index == 0x00FFFFFF) // Nothing selected
-						continue;
-
-					auto iterFind = selectionScores.find(index);
-					if (iterFind == selectionScores.end())
-						selectionScores[index] = 1;
-					else
-						iterFind->second++;
-				}
-			}
-		}
-
-		// Sort by score
-		struct SelectedObject { UINT32 index; UINT32 score; };
-
-		Vector<SelectedObject> selectedObjects(selectionScores.size());
-		UINT32 idx = 0;
-		for (auto& selectionScore : selectionScores)
-		{
-			selectedObjects[idx++] = { selectionScore.first, selectionScore.second };
-		}
-
-		std::sort(selectedObjects.begin(), selectedObjects.end(),
-			[&](const SelectedObject& a, const SelectedObject& b)
-		{
-			return b.score < a.score;
-		});
-
-		Vector<UINT32> results;
-		for (auto& selectedObject : selectedObjects)
-			results.push_back(selectedObject.index);
-
-		asyncOp._completeOperation(results);
-	}
+#include "BsScenePicking.h"
+#include "BsSceneManager.h"
+#include "BsColor.h"
+#include "BsMatrix4.h"
+#include "BsDebug.h"
+#include "BsMath.h"
+#include "BsCRenderable.h"
+#include "BsSceneObject.h"
+#include "BsMesh.h"
+#include "BsConvexVolume.h"
+#include "BsCCamera.h"
+#include "BsCoreThread.h"
+#include "BsRenderAPI.h"
+#include "BsMaterial.h"
+#include "BsPass.h"
+#include "BsBlendState.h"
+#include "BsDepthStencilState.h"
+#include "BsRasterizerState.h"
+#include "BsRenderTarget.h"
+#include "BsPixelData.h"
+#include "BsGpuParams.h"
+#include "BsBuiltinEditorResources.h"
+#include "BsShader.h"
+#include "BsCoreRenderer.h"
+#include "BsGizmoManager.h"
+#include "BsRendererUtility.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	const float ScenePickingCore::ALPHA_CUTOFF = 0.5f;
+
+	ScenePicking::ScenePicking()
+	{
+		mCore = bs_new<ScenePickingCore>();
+
+		for (UINT32 i = 0; i < 3; i++)
+		{
+			HMaterial matPicking = BuiltinEditorResources::instance().createPicking((CullingMode)i);
+			HMaterial matPickingAlpha = BuiltinEditorResources::instance().createPickingAlpha((CullingMode)i);
+
+			mCore->mMaterialData[i].mMatPickingCore = matPicking->getCore();
+			mCore->mMaterialData[i].mMatPickingAlphaCore = matPickingAlpha->getCore();
+		}
+
+		gCoreAccessor().queueCommand(std::bind(&ScenePickingCore::initialize, mCore));
+	}
+
+	ScenePicking::~ScenePicking()
+	{
+		gCoreAccessor().queueCommand(std::bind(&ScenePickingCore::destroy, mCore));
+	}
+
+	HSceneObject ScenePicking::pickClosestObject(const CameraPtr& cam, const Vector2I& position, const Vector2I& area)
+	{
+		Vector<HSceneObject> selectedObjects = pickObjects(cam, position, area);
+		if (selectedObjects.size() == 0)
+			return HSceneObject();
+
+		return selectedObjects[0];
+	}
+
+	Vector<HSceneObject> ScenePicking::pickObjects(const CameraPtr& cam, const Vector2I& position, const Vector2I& area)
+	{
+		auto comparePickElement = [&] (const ScenePicking::RenderablePickData& a, const ScenePicking::RenderablePickData& b)
+		{
+			// Sort by alpha setting first, then by cull mode, then by index
+			if (a.alpha == b.alpha)
+			{
+				if (a.cullMode == b.cullMode)
+					return a.index > b.index;
+				else
+					return (UINT32)a.cullMode > (UINT32)b.cullMode;
+			}
+			else
+				return (UINT32)a.alpha > (UINT32)b.alpha;
+		};
+
+		Matrix4 viewProjMatrix = cam->getProjectionMatrixRS() * cam->getViewMatrix();
+
+		const Map<Renderable*, SceneRenderableData>& renderables = SceneManager::instance().getAllRenderables();
+		RenderableSet pickData(comparePickElement);
+		Map<UINT32, HSceneObject> idxToRenderable;
+
+		for (auto& renderableData : renderables)
+		{
+			RenderablePtr renderable = renderableData.second.renderable;
+			HSceneObject so = renderableData.second.sceneObject;
+
+			if (!so->getActive())
+				continue;
+
+			HMesh mesh = renderable->getMesh();
+			if (!mesh.isLoaded())
+				continue;
+
+			Bounds worldBounds = mesh->getProperties().getBounds();
+			Matrix4 worldTransform = so->getWorldTfrm();
+			worldBounds.transformAffine(worldTransform);
+
+			// TODO - I could limit the frustum to the visible area we're rendering for a speed boost
+			// but this is unlikely to be a performance bottleneck
+			const ConvexVolume& frustum = cam->getWorldFrustum();
+			if (frustum.intersects(worldBounds.getSphere()))
+			{
+				// More precise with the box
+				if (frustum.intersects(worldBounds.getBox()))
+				{
+					for (UINT32 i = 0; i < mesh->getProperties().getNumSubMeshes(); i++)
+					{
+						UINT32 idx = (UINT32)pickData.size();
+
+						bool useAlphaShader = false;
+						RasterizerStatePtr rasterizerState;
+
+						HMaterial originalMat = renderable->getMaterial(i);
+						if (originalMat != nullptr && originalMat->getNumPasses() > 0)
+						{
+							PassPtr firstPass = originalMat->getPass(0); // Note: We only ever check the first pass, problem?
+							useAlphaShader = firstPass->hasBlending();
+
+							if (firstPass->getRasterizerState() == nullptr)
+								rasterizerState = RasterizerState::getDefault();
+							else
+								rasterizerState = firstPass->getRasterizerState();
+						}
+						else
+							rasterizerState = RasterizerState::getDefault();
+
+						CullingMode cullMode = rasterizerState->getProperties().getCullMode();
+
+						HTexture mainTexture;
+						if (useAlphaShader)
+						{
+							const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams = originalMat->getShader()->getTextureParams();
+							for (auto& objectParam : textureParams)
+							{
+								if (objectParam.second.rendererSemantic == RPS_Diffuse)
+								{
+									mainTexture = originalMat->getTexture(objectParam.first);
+									break;
+								}
+							}
+						}
+
+						idxToRenderable[idx] = so;
+
+						Matrix4 wvpTransform = viewProjMatrix * worldTransform;
+						pickData.insert({ mesh->getCore(), idx, wvpTransform, useAlphaShader, cullMode, mainTexture });
+					}
+				}
+			}
+		}
+
+		UINT32 firstGizmoIdx = (UINT32)pickData.size();
+
+		SPtr<RenderTargetCore> target = cam->getViewport()->getTarget()->getCore();
+		gCoreAccessor().queueCommand(std::bind(&ScenePickingCore::corePickingBegin, mCore, target,
+			cam->getViewport()->getNormArea(), std::cref(pickData), position, area));
+
+		GizmoManager::instance().renderForPicking(cam, [&](UINT32 inputIdx) { return encodeIndex(firstGizmoIdx + inputIdx); });
+
+		AsyncOp op = gCoreAccessor().queueReturnCommand(std::bind(&ScenePickingCore::corePickingEnd, mCore, target, 
+			cam->getViewport()->getNormArea(), position, area, _1));
+		gCoreAccessor().submitToCoreThread(true);
+
+		assert(op.hasCompleted());
+
+		Vector<UINT32>& selectedObjects = op.getReturnValue<Vector<UINT32>>();
+		Vector<HSceneObject> results;
+
+		for (auto& selectedObjectIdx : selectedObjects)
+		{
+			if (selectedObjectIdx < firstGizmoIdx)
+			{
+				auto iterFind = idxToRenderable.find(selectedObjectIdx);
+
+				if (iterFind != idxToRenderable.end())
+					results.push_back(iterFind->second);
+			}
+			else
+			{
+				UINT32 gizmoIdx = selectedObjectIdx - firstGizmoIdx;
+
+				HSceneObject so = GizmoManager::instance().getSceneObject(gizmoIdx);
+				if (so)
+					results.push_back(so);
+			}
+		}
+
+		return results;
+	}
+
+	Color ScenePicking::encodeIndex(UINT32 index)
+	{
+		Color encoded;
+		encoded.r = (index & 0xFF) / 255.0f;
+		encoded.g = ((index >> 8) & 0xFF) / 255.0f;
+		encoded.b = ((index >> 16) & 0xFF) / 255.0f;
+		encoded.a = 1.0f;
+
+		if (((index >> 24) & 0xFF))
+			LOGERR("Index when picking out of valid range.");
+
+		return encoded;
+	}
+
+	UINT32 ScenePicking::decodeIndex(Color color)
+	{
+		UINT32 r = Math::roundToInt(color.r * 255.0f);
+		UINT32 g = Math::roundToInt(color.g * 255.0f);
+		UINT32 b = Math::roundToInt(color.b * 255.0f);
+
+		return (r & 0xFF) | ((g & 0xFF) << 8) | ((b & 0xFF) << 16);
+	}
+
+	void ScenePickingCore::initialize()
+	{
+		for (UINT32 i = 0; i < 3; i++)
+		{
+			MaterialData& md = mMaterialData[i];
+
+			{
+				SPtr<PassParametersCore> passParams = md.mMatPickingCore->getPassParameters(0);
+
+				md.mParamPickingVertParams = passParams->mVertParams;
+				md.mParamPickingVertParams->getParam("matWorldViewProj", md.mParamPickingWVP);
+
+				md.mParamPickingFragParams = passParams->mFragParams;
+				md.mParamPickingFragParams->getParam("colorIndex", md.mParamPickingColor);
+			}
+
+			{
+				SPtr<PassParametersCore> passParams = md.mMatPickingAlphaCore->getPassParameters(0);
+
+				md.mParamPickingAlphaVertParams = passParams->mVertParams;
+				md.mParamPickingAlphaVertParams->getParam("matWorldViewProj", md.mParamPickingAlphaWVP);
+
+				md.mParamPickingAlphaFragParams = passParams->mFragParams;
+
+				md.mParamPickingAlphaFragParams->getParam("colorIndex", md.mParamPickingAlphaColor);
+				md.mParamPickingAlphaFragParams->getTextureParam("mainTexture", md.mParamPickingAlphaTexture);
+
+				GpuParamFloatCore alphaCutoffParam;
+				md.mParamPickingAlphaFragParams->getParam("alphaCutoff", alphaCutoffParam);
+				alphaCutoffParam.set(ALPHA_CUTOFF);
+			}
+		}
+	}
+
+	void ScenePickingCore::destroy()
+	{
+		bs_delete(this);
+	}
+
+	void ScenePickingCore::corePickingBegin(const SPtr<RenderTargetCore>& target, const Rect2& viewportArea,
+		const ScenePicking::RenderableSet& renderables, const Vector2I& position, const Vector2I& area)
+	{
+		RenderAPICore& rs = RenderAPICore::instance();
+
+		rs.beginFrame();
+		rs.setRenderTarget(target);
+		rs.setViewport(viewportArea);
+		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
+		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
+
+		gRendererUtility().setPass(mMaterialData[0].mMatPickingCore, 0);
+		bool activeMaterialIsAlpha = false;
+		CullingMode activeMaterialCull = (CullingMode)0;
+
+		for (auto& renderable : renderables)
+		{
+			if (activeMaterialIsAlpha != renderable.alpha || activeMaterialCull != renderable.cullMode)
+			{
+				activeMaterialIsAlpha = renderable.alpha;
+				activeMaterialCull = renderable.cullMode;
+
+				if (activeMaterialIsAlpha)
+					gRendererUtility().setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingAlphaCore, 0);
+				else
+					gRendererUtility().setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingCore, 0);
+			}
+
+			Color color = ScenePicking::encodeIndex(renderable.index);
+			MaterialData& md = mMaterialData[(UINT32)activeMaterialCull];
+
+			if (activeMaterialIsAlpha)
+			{
+				md.mParamPickingAlphaWVP.set(renderable.wvpTransform);
+				md.mParamPickingAlphaColor.set(color);
+				md.mParamPickingAlphaTexture.set(renderable.mainTexture->getCore());
+
+				rs.setGpuParams(GPT_VERTEX_PROGRAM, md.mParamPickingAlphaVertParams);
+				rs.setGpuParams(GPT_FRAGMENT_PROGRAM, md.mParamPickingAlphaFragParams);
+			}
+			else
+			{
+				md.mParamPickingWVP.set(renderable.wvpTransform);
+				md.mParamPickingColor.set(color);
+
+				rs.setGpuParams(GPT_VERTEX_PROGRAM, md.mParamPickingVertParams);
+				rs.setGpuParams(GPT_FRAGMENT_PROGRAM, md.mParamPickingFragParams);
+			}
+
+			UINT32 numSubmeshes = renderable.mesh->getProperties().getNumSubMeshes();
+
+			for (UINT32 i = 0; i < numSubmeshes; i++)
+				gRendererUtility().draw(renderable.mesh, renderable.mesh->getProperties().getSubMesh(i));
+		}
+	}
+
+	void ScenePickingCore::corePickingEnd(const SPtr<RenderTargetCore>& target, const Rect2& viewportArea, const Vector2I& position,
+		const Vector2I& area, AsyncOp& asyncOp)
+	{
+		const RenderTargetProperties& rtProps = target->getProperties();
+
+		if (rtProps.isWindow())
+		{
+			// TODO: When I do implement this then I will likely want a method in RenderTarget that unifies both render window and render texture readback
+			BS_EXCEPT(NotImplementedException, "Picking is not supported on render windows as framebuffer readback methods aren't implemented");
+		}
+
+		SPtr<RenderTextureCore> rtt = std::static_pointer_cast<RenderTextureCore>(target);
+		SPtr<TextureCore> outputTexture = rtt->getBindableColorTexture();
+
+		if (position.x < 0 || position.x >= (INT32)outputTexture->getProperties().getWidth() ||
+			position.y < 0 || position.y >= (INT32)outputTexture->getProperties().getHeight())
+		{
+			asyncOp._completeOperation(Vector<UINT32>());
+			return;
+		}
+
+		PixelDataPtr outputPixelData = outputTexture->getProperties().allocateSubresourceBuffer(0);
+		AsyncOp unused;
+
+		RenderAPICore& rs = RenderAPICore::instance();
+
+		rs.endFrame();
+		outputTexture->readSubresource(0, *outputPixelData);
+
+		Map<UINT32, UINT32> selectionScores;
+		UINT32 numPixels = outputPixelData->getWidth() * outputPixelData->getHeight();
+
+		UINT32 maxWidth = std::min((UINT32)(position.x + area.x), outputPixelData->getWidth());
+		UINT32 maxHeight = std::min((UINT32)(position.y + area.y), outputPixelData->getHeight());
+
+		if (rtProps.requiresTextureFlipping())
+		{
+			UINT32 vertOffset = outputPixelData->getHeight() - 1;
+
+			for (UINT32 y = maxHeight; y > (UINT32)position.y; y--)
+			{
+				for (UINT32 x = (UINT32)position.x; x < maxWidth; x++)
+				{
+					Color color = outputPixelData->getColorAt(x, vertOffset - y);
+					UINT32 index = ScenePicking::decodeIndex(color);
+
+					if (index == 0x00FFFFFF) // Nothing selected
+						continue;
+
+					auto iterFind = selectionScores.find(index);
+					if (iterFind == selectionScores.end())
+						selectionScores[index] = 1;
+					else
+						iterFind->second++;
+				}
+			}
+		}
+		else
+		{
+			for (UINT32 y = (UINT32)position.y; y < maxHeight; y++)
+			{
+				for (UINT32 x = (UINT32)position.x; x < maxWidth; x++)
+				{
+					Color color = outputPixelData->getColorAt(x, y);
+					UINT32 index = ScenePicking::decodeIndex(color);
+
+					if (index == 0x00FFFFFF) // Nothing selected
+						continue;
+
+					auto iterFind = selectionScores.find(index);
+					if (iterFind == selectionScores.end())
+						selectionScores[index] = 1;
+					else
+						iterFind->second++;
+				}
+			}
+		}
+
+		// Sort by score
+		struct SelectedObject { UINT32 index; UINT32 score; };
+
+		Vector<SelectedObject> selectedObjects(selectionScores.size());
+		UINT32 idx = 0;
+		for (auto& selectionScore : selectionScores)
+		{
+			selectedObjects[idx++] = { selectionScore.first, selectionScore.second };
+		}
+
+		std::sort(selectedObjects.begin(), selectedObjects.end(),
+			[&](const SelectedObject& a, const SelectedObject& b)
+		{
+			return b.score < a.score;
+		});
+
+		Vector<UINT32> results;
+		for (auto& selectedObject : selectedObjects)
+			results.push_back(selectedObject.index);
+
+		asyncOp._completeOperation(results);
+	}
 }

+ 9 - 9
BansheeEngine/Include/BsSplashScreen.h

@@ -6,23 +6,23 @@
 
 namespace BansheeEngine
 {
-	/**
-	 * @brief	Displays a splash screen with Banshee Engine logo.
-	 */
+	/**	Displays a splash screen with Banshee Engine logo. */
 	class BS_EXPORT SplashScreen
 	{
 	public:
-		/**
-		 * @brief	Displays a splash screen with Banshee Engine logo.
-		 */
+		/**	Displays a splash screen with Banshee Engine logo. */
 		static void show();
 
-		/**
-		 * @brief	Hides the splash screen.
-		 */
+		/**	Hides the splash screen. */
 		static void hide();
 
 	private:
+		/** Creates the splash screen window. */
+		static void create();
+
+		/** Destroys the splash screen window. */
+		static void destroy();
+
 		struct Pimpl;
 		static Pimpl* m;
 

+ 12 - 1
BansheeEngine/Source/BsSplashScreen.cpp

@@ -3,6 +3,7 @@
 #include "BsSplashScreen.h"
 #include "BsBuiltinResources.h"
 #include "BsTimer.h"
+#include "BsCoreThread.h"
 
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 #include "Win32/BsWin32Platform.h"
@@ -21,6 +22,16 @@ namespace BansheeEngine
 	const UINT32 SplashScreen::SPLASH_SCREEN_DURATION_MS = 1000;
 
 	void SplashScreen::show()
+	{
+		gCoreThread().queueCommand(&SplashScreen::create);
+	}
+
+	void SplashScreen::hide()
+	{
+		gCoreThread().queueCommand(&SplashScreen::destroy);
+	}
+
+	void SplashScreen::create()
 	{
 		if (m->window != nullptr)
 			return;
@@ -49,7 +60,7 @@ namespace BansheeEngine
 		m->timer.reset();
 	}
 
-	void SplashScreen::hide()
+	void SplashScreen::destroy()
 	{
 		if (m->window == nullptr)
 			return;

+ 17 - 43
BansheeGLRenderAPI/Include/BsGLRenderTexture.h

@@ -14,7 +14,7 @@ namespace BansheeEngine
 	class GLRenderTexture;
 
 	/**
-	 * @brief	OpenGL implementation of a render texture.
+	 * OpenGL implementation of a render texture.
 	 *
 	 * @note	Core thread only.
 	 */
@@ -24,22 +24,16 @@ namespace BansheeEngine
 		GLRenderTextureCore(const RENDER_TEXTURE_CORE_DESC& desc);
 		virtual ~GLRenderTextureCore();
 
-		/**
-		 * @copydoc	RenderTextureCore::getCustomAttribute
-		 */
+		/** @copydoc RenderTextureCore::getCustomAttribute */
 		virtual void getCustomAttribute(const String& name, void* pData) const override;
 
 	protected:
 		friend class GLRenderTexture;
 
-		/**
-		 * @copydoc	RenderTextureCore::initialize
-		 */
+		/** @copydoc RenderTextureCore::initialize */
 		virtual void initialize() override;
 
-		/**
-		 * @copydoc	RenderTextureCore::getProperties
-		 */
+		/** @copydoc RenderTextureCore::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
 		RenderTextureProperties mProperties;
@@ -47,7 +41,7 @@ namespace BansheeEngine
     };
 
     /**
-     * @brief	Manager that handles valid render texture formats.
+     * Manager that handles valid render texture formats.
      * 			
 	 * @note	Must be initialized when RenderSystem is first started.
      */
@@ -58,39 +52,29 @@ namespace BansheeEngine
 		~GLRTTManager();
         
         /**
-         * @brief	Check if a certain format is usable as a render target format.
+         * Check if a certain format is usable as a render target format.
          *
          * @note	Thread safe.
          */
-        bool checkFormat(PixelFormat format) { return mProps[format].valid; }
+        bool checkFormat(PixelFormat format) const { return mProps[format].valid; }
         
         /**
-         * @brief	Get the closest supported alternative format. If format is supported, returns format.
+         * Get the closest supported alternative format. If format is supported, returns format.
          *
          * @note	Thread safe.
          */
         virtual PixelFormat getSupportedAlternative(PixelFormat format);
 
-		/**
-		 * @brief	Returns a persistent FBO that is used as a
-		 *			source buffer for blit operations.
-		 */
+		/** Returns a persistent FBO that is used as a source buffer for blit operations. */
 		GLuint getBlitReadFBO() const { return mBlitReadFBO; }
 
-		/**
-		 * @brief	Returns a persistent FBO that is used as a 
-		 *			destination buffer for blit operations.
-		 */
+		/** Returns a persistent FBO that is used as a destination buffer for blit operations. */
 		GLuint getBlitDrawFBO() const { return mBlitWriteFBO; }
     private:
-        /** 
-		 * Frame buffer object properties for a certain texture format.
-         */
+        /** Frame buffer object properties for a certain texture format. */
         struct FormatProperties
         {
-            /** 
-			 * Allowed modes/properties for this pixel format
-             */
+            /** Allowed modes/properties for this pixel format. */
             struct Mode
             {
                 UINT32 depth;     /**< Depth format (0 = no depth). */
@@ -101,21 +85,13 @@ namespace BansheeEngine
 			bool valid;
         };
 
-		/**
-		 * @brief	Detect which internal formats are allowed to be used on render target 
-		 *			color or depth/stencil surfaces.
-		 */
+		/** Detect which internal formats are allowed to be used on render target color or depth/stencil surfaces. */
         void detectFBOFormats();
 
-		/**
-		 * @brief	Checks are the specified depth & stencil formats compatible.
-		 */
+		/**	Checks are the specified depth & stencil formats compatible. */
 		bool _tryFormat(GLenum depthFormat, GLenum stencilFormat);
 
-		/**
-		 * @brief	Checks is the specified packed format valid for using
-		 *			in the render target.
-		 */
+		/**	Checks is the specified packed format valid for using in the render target. */
         bool _tryPackedFormat(GLenum packedFormat);
 
 		FormatProperties mProps[PF_COUNT];
@@ -124,7 +100,7 @@ namespace BansheeEngine
     };
 
 	/**
-	 * @brief	DirectX 9 implementation of a render texture.
+	 * OpenGL implementation of a render texture.
 	 *
 	 * @note	Sim thread only.
 	 */
@@ -138,9 +114,7 @@ namespace BansheeEngine
 
 		GLRenderTexture(const RENDER_TEXTURE_DESC& desc);
 
-		/**
-		 * @copydoc	RenderTexture::getProperties
-		 */
+		/** @copydoc RenderTexture::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
 		RenderTextureProperties mProperties;

+ 15 - 40
BansheeGLRenderAPI/Include/BsGLTexture.h

@@ -3,42 +3,32 @@
 #pragma once
 
 #include "BsGLPrerequisites.h"
-#include "BsRenderTexture.h"
 #include "BsTexture.h"
 #include "BsGLSupport.h"
-#include "BsPixelBuffer.h"
 
 namespace BansheeEngine 
 {
-	/**
-	 * @brief	OpenGL implementation of a texture.
-	 */
+	/**	OpenGL implementation of a texture. */
     class BS_RSGL_EXPORT GLTextureCore : public TextureCore
     {
     public:
 		virtual ~GLTextureCore();
 
-		/**
-		 * @brief	Returns OpenGL texture target type
-		 */
+		/**	Returns OpenGL texture target type. */
         GLenum getGLTextureTarget() const;
 
-		/**
-		 * @brief	Returns internal OpenGL texture handle.
-		 */
+		/**	Returns internal OpenGL texture handle. */
         GLuint getGLID() const;
 
-		/**
-		 * @brief	Returns the internal OpenGL format used by the texture.
-		 */
+		/**	Returns the internal OpenGL format used by the texture. */
 		GLenum getGLFormat() const { return mGLFormat; }
 		
 		/**
-		 * @brief	Returns a hardware pixel buffer for a certain face and level of the texture.
+		 * Returns a hardware pixel buffer for a certain face and level of the texture.
 		 * 
-		 * @param	face	Index of the texture face, if texture has more than one. Array index for
-		 *					texture arrays and a cube face for cube textures.
-		 * @param	mipmap	Index of the mip level. 0 being the largest mip level.
+		 * @param[in]	face	Index of the texture face, if texture has more than one. Array index for texture arrays and
+		 *						a cube face for cube textures.
+		 * @param[in]	mipmap	Index of the mip level. 0 being the largest mip level.
 		 *
 		 * @note	Cube face indices: +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)
 		 */
@@ -50,40 +40,25 @@ namespace BansheeEngine
 		GLTextureCore(GLSupport& support, TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
 			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount, const PixelDataPtr& initialData);
 
-		/**
-		 * @copydoc TextureCore::initialize
-		 */
+		/** @copydoc TextureCore::initialize */
 		void initialize() override;
 
-		/**
-		 * @copydoc TextureCore::lock
-		 */
+		/** @copydoc TextureCore::lock */
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0) override;
 
-		/**
-		 * @copydoc TextureCore::unlock
-		 */
+		/** @copydoc TextureCore::unlock */
 		void unlockImpl() override;
 
-		/**
-		 * @copydoc TextureCore::copy
-		 */
+		/** @copydoc TextureCore::copy */
 		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target) override;
 
-		/**
-		 * @copydoc TextureCore::readData
-		 */
+		/** @copydoc TextureCore::readData */
 		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0) override;
 
-		/**
-		 * @copydoc TextureCore::writeData
-		 */
+		/** @copydoc TextureCore::writeData */
 		void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false) override;
 
-		/**
-		 * @brief	Creates pixel buffers for each face and mip level. Texture must 
-		 *			have been created previously.
-		 */
+		/** Creates pixel buffers for each face and mip level. Texture must have been created previously. */
 		void createSurfaceList();
 
     private:

+ 30 - 86
BansheeGLRenderAPI/Include/Win32/BsWin32RenderWindow.h

@@ -9,9 +9,7 @@ namespace BansheeEngine
 {
 	class Win32RenderWindow;
 
-	/**
-	 * @brief	Contains various properties that describe a render window.
-	 */
+	/**	Contains various properties that describe a render window. */
 	class BS_RSGL_EXPORT Win32RenderWindowProperties : public RenderWindowProperties
 	{
 	public:
@@ -24,7 +22,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Render window implementation for Windows.
+	 * Render window implementation for Windows.
 	 *
 	 * @note	Core thread only.
 	 */
@@ -34,107 +32,67 @@ namespace BansheeEngine
 		Win32RenderWindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId, Win32GLSupport &glsupport);
 		~Win32RenderWindowCore();
 
-		/**
-		 * @copydoc RenderWindowCore::setFullscreen(UINT32, UINT32, float, UINT32)
-		 */
+		/** @copydoc RenderWindowCore::setFullscreen(UINT32, UINT32, float, UINT32) */
 		void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setFullscreen(const VideoMode&)
-		 */
+		/** @copydoc RenderWindowCore::setFullscreen(const VideoMode&) */
 		void setFullscreen(const VideoMode& mode) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setWindowed
-		 */
+		/** @copydoc RenderWindowCore::setWindowed */
 		void setWindowed(UINT32 width, UINT32 height) override;
 
-		/**
-		 * @copydoc RenderWindowCore::setHidden
-		 */
+		/** @copydoc RenderWindowCore::setHidden */
 		void setHidden(bool hidden) override;
 
-		/**
-		 * @copydoc	RenderWindowCore::minimize
-		 */
+		/** @copydoc RenderWindowCore::minimize */
 		void minimize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::maximize
-		 */
+		/** @copydoc RenderWindowCore::maximize */
 		void maximize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::restore
-		 */
+		/** @copydoc RenderWindowCore::restore */
 		void restore() override;
 
-		/**
-		 * @copydoc RenderWindowCore::move
-		 */
+		/** @copydoc RenderWindowCore::move */
 		void move(INT32 left, INT32 top) override;
 
-		/**
-		 * @copydoc RenderWindowCore::resize
-		 */
+		/** @copydoc RenderWindowCore::resize */
 		void resize(UINT32 width, UINT32 height) override;
 
-		/**
-		 * @copydoc RenderWindowCore::copyContentsToMemory
-		 */
+		/** @copydoc RenderWindowCore::copyContentsToMemory */
 		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 
-		/**
-		 * @copydoc RenderWindowCore::swapBuffers
-		 */
+		/** @copydoc RenderWindowCore::swapBuffers */
 		void swapBuffers() override;
 
-		/**
-		 * @copydoc RenderWindowCore::getCustomAttribute
-		 */
+		/** @copydoc RenderWindowCore::getCustomAttribute */
 		void getCustomAttribute(const String& name, void* pData) const override;
 
-		/**
-		 * @copydoc RenderWindowCore::setActive
-		 */
+		/** @copydoc RenderWindowCore::setActive */
 		virtual void setActive(bool state) override;
 
-		/**
-		 * @copydoc RenderWindowCore::_windowMovedOrResized
-		 */
+		/** @copydoc RenderWindowCore::_windowMovedOrResized */
 		void _windowMovedOrResized() override;
 
-		/**
-		 * @brief	Returns handle to device context associated with the window.
-		 */
+		/**	Returns handle to device context associated with the window. */
 		HDC _getHDC() const { return mHDC; }
 
-		/**
-		 * @brief	Returns internal window handle.
-		 */
+		/**	Returns internal window handle. */
 		HWND _getHWnd() const;
 
 	protected:
 		friend class Win32GLSupport;
 
-		/**
-		 * @copydoc	CoreObjectCore::initialize
-		 */
+		/** @copydoc CoreObjectCore::initialize */
 		virtual void initialize() override;
 
-		/**
-		 * @copydoc	RenderWindowCore::getProperties
-		 */
+		/** @copydoc RenderWindowCore::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
-		/**
-		 * @copydoc	RenderWindowCore::getSyncedProperties
-		 */
+		/** @copydoc RenderWindowCore::getSyncedProperties */
 		RenderWindowProperties& getSyncedProperties() override { return mSyncedProperties; }
 
-		/**
-		 * @copydoc	RenderWindowCore::syncProperties
-		 */
+		/** @copydoc RenderWindowCore::syncProperties */
 		void syncProperties() override;
 
 	protected:
@@ -153,7 +111,7 @@ namespace BansheeEngine
     };
 
 	/**
-	 * @brief	Render window implementation for Windows.
+	 * Render window implementation for Windows.
 	 *
 	 * @note	Sim thread only.
 	 */
@@ -162,24 +120,16 @@ namespace BansheeEngine
 	public:
 		~Win32RenderWindow() { }
 
-		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
+		/** @copydoc RenderWindow::screenToWindowPos */
 		void getCustomAttribute(const String& name, void* pData) const override;
 
-		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
+		/** @copydoc RenderWindow::screenToWindowPos */
 		Vector2I screenToWindowPos(const Vector2I& screenPos) const override;
 
-		/**
-		 * @copydoc RenderWindow::windowToScreenPos
-		 */
+		/** @copydoc RenderWindow::windowToScreenPos */
 		Vector2I windowToScreenPos(const Vector2I& windowPos) const override;
 
-		/**
-		 * @copydoc	RenderWindow::getCore
-		 */
+		/** @copydoc RenderWindow::getCore */
 		SPtr<Win32RenderWindowCore> getCore() const;
 
 	protected:
@@ -189,19 +139,13 @@ namespace BansheeEngine
 
 		Win32RenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 windowId, Win32GLSupport& glsupport);
 
-		/**
-		 * @copydoc	RenderWindow::getProperties
-		 */
+		/** @copydoc RenderWindow::getProperties */
 		const RenderTargetProperties& getPropertiesInternal() const override { return mProperties; }
 
-		/**
-		 * @copydoc	RenderWindow::syncProperties
-		 */
+		/** @copydoc RenderWindow::syncProperties */
 		void syncProperties() override;
 
-		/**
-		 * @brief	Retrieves internal window handle.
-		 */
+		/**	Retrieves internal window handle. */
 		HWND getHWnd() const;
 
 	private:

+ 2 - 4
BansheeGLRenderAPI/Source/win32/BsWin32RenderWindow.cpp

@@ -57,8 +57,6 @@ namespace BansheeEngine
 
 	void Win32RenderWindowCore::initialize()
 	{
-		RenderWindowCore::initialize();
-
 		Win32RenderWindowProperties& props = mProperties;
 
 		props.mIsFullScreen = mDesc.fullscreen;
@@ -203,6 +201,7 @@ namespace BansheeEngine
 		}
 
 		RenderWindowManager::instance().notifySyncDataDirty(this);
+		RenderWindowCore::initialize();
 	}
 
 	void Win32RenderWindowCore::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
@@ -561,8 +560,7 @@ namespace BansheeEngine
 
 	HWND Win32RenderWindow::getHWnd() const
 	{
-		// HACK: I'm accessing core method from sim thread, which means an invalid handle
-		// could be returned here if requested too soon after initialization.
+		blockUntilCoreInitialized();
 		return getCore()->_getHWnd();
 	}
 }

+ 0 - 1
BansheeUtility/BansheeUtility.vcxproj

@@ -306,7 +306,6 @@
     <ClCompile Include="Source\BsSphere.cpp" />
     <ClCompile Include="Source\BsTexAtlasGenerator.cpp" />
     <ClCompile Include="Source\ThirdParty\md5.cpp" />
-    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp" />
     <ClCompile Include="Source\Win32\BsWin32CrashHandler.cpp" />
     <ClCompile Include="Source\Win32\BsWin32FileSystem.cpp" />
     <ClCompile Include="Source\Win32\BsWin32PlatformUtility.cpp" />

+ 0 - 3
BansheeUtility/BansheeUtility.vcxproj.filters

@@ -478,9 +478,6 @@
     <ClCompile Include="Source\Win32\BsWin32PlatformUtility.cpp">
       <Filter>Source Files\Win32</Filter>
     </ClCompile>
-    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp">
-      <Filter>Source Files\Win32</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsFrameAlloc.cpp">
       <Filter>Source Files\Allocators</Filter>
     </ClCompile>

+ 0 - 13
BansheeUtility/Include/BsPlatformUtility.h

@@ -82,19 +82,6 @@ namespace BansheeEngine
 		 * @param[in]	path	Absolute path to the file or folder to open.
 		 */
 		static void open(const Path& path);
-
-		/**
-		 * Displays a platform specific file/folder open/save dialog.
-		 *
-		 * @param[in]	type		Type of dialog to open.
-		 * @param[in]	defaultPath	Initial path the dialog will be set to once opened.
-		 * @param[in]	filterList	Semi-colon separated list of file names or types to display in the dialog, e.g. "exe;txt;png".
-		 *							Ignored if dialog is to display folders instead of files.
-		 * @param[out]	paths		Output list of selected file or folder paths (if any).
-		 * @return					True if file was selected and false if selection was canceled.
-		 */
-		static bool openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
-			Vector<Path>& paths);
 	};
 
 	/** Represents a MAC (ethernet) address. */

+ 1 - 0
BansheeUtility/Include/BsThreadDefines.h

@@ -33,6 +33,7 @@
 #define BS_STATIC_THREAD_SYNCHRONISER(sync) static std::condition_variable sync;
 #define BS_STATIC_THREAD_SYNCHRONISER_CLASS_INSTANCE(sync, classTypeName) std::condition_variable classTypeName##::sync;
 #define BS_THREAD_WAIT(sync, mutex, lock) sync.wait(lock);
+#define BS_THREAD_WAIT_FOR(sync, mutex, lock, ms) sync.wait_for(lock, std::chrono::milliseconds(ms));
 #define BS_THREAD_NOTIFY_ONE(sync) sync.notify_one(); 
 #define BS_THREAD_NOTIFY_ALL(sync) sync.notify_all(); 
 #define BS_THREAD_JOIN(thread) thread.join();

+ 4 - 0
BansheeUtility/Include/Win32/BsWin32Window.h

@@ -111,6 +111,10 @@ namespace BansheeEngine
 		/** Called when window is moved or resized externally. */
 		void _windowMovedOrResized();
 
+		// DEBUG ONLY
+		void static _enableAllWindows();
+		void static _restoreModalWindows();
+
 	private:
 		friend class Win32WindowManager;
 

+ 42 - 0
BansheeUtility/Source/Win32/BsWin32Window.cpp

@@ -454,4 +454,46 @@ namespace BansheeEngine
 	{
 		return m->styleEx;
 	}
+
+	void Win32Window::_enableAllWindows()
+	{
+		Vector<HWND> windowsToEnable;
+
+		{
+			BS_LOCK_MUTEX(sWindowsMutex);
+			for (auto& window : sAllWindows)
+				windowsToEnable.push_back(window->m->hWnd);
+		}
+
+		for (auto& entry : windowsToEnable)
+			EnableWindow(entry, TRUE);
+	}
+
+	void Win32Window::_restoreModalWindows()
+	{
+		FrameVector<HWND> windowsToDisable;
+		HWND bringToFrontHwnd = 0;
+
+		{
+			BS_LOCK_MUTEX(sWindowsMutex)
+
+			if (!sModalWindowStack.empty())
+			{
+				Win32Window* curModalWindow = sModalWindowStack.back();
+				bringToFrontHwnd = curModalWindow->m->hWnd;
+
+				for (auto& window : sAllWindows)
+				{
+					if (window != curModalWindow)
+						windowsToDisable.push_back(window->m->hWnd);
+				}
+			}
+		}
+
+		for (auto& entry : windowsToDisable)
+			EnableWindow(entry, FALSE);
+
+		if (bringToFrontHwnd != nullptr)
+			BringWindowToTop(bringToFrontHwnd);
+	}
 }

+ 3 - 3
SBansheeEditor/Source/BsScriptBrowseDialog.cpp

@@ -23,7 +23,7 @@ namespace BansheeEngine
 		FileDialogType type = (FileDialogType)((UINT32)FileDialogType::OpenFile | (UINT32)FileDialogType::Multiselect);
 
 		Vector<Path> paths;
-		if (PlatformUtility::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
+		if (Platform::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
 		{
 			MonoArray* pathArray = mono_array_new(MonoManager::instance().getDomain(),
 				mono_get_string_class(), (UINT32)paths.size());
@@ -53,7 +53,7 @@ namespace BansheeEngine
 		FileDialogType type = FileDialogType::OpenFolder;
 
 		Vector<Path> paths;
-		if (PlatformUtility::openBrowseDialog(type, defaultFolderNative, L"", paths))
+		if (Platform::openBrowseDialog(type, defaultFolderNative, L"", paths))
 		{
 			if (paths.size() > 0)
 				*outPath = MonoUtil::wstringToMono(paths[0].toWString());
@@ -77,7 +77,7 @@ namespace BansheeEngine
 		FileDialogType type = FileDialogType::Save;
 
 		Vector<Path> paths;
-		if (PlatformUtility::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
+		if (Platform::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
 		{
 			if (paths.size() > 0)
 				*outPath = MonoUtil::wstringToMono(paths[0].toWString());