瀏覽代碼

Major RenderTarget refactor to separate sim and core thread functionality
OpenGL fix for VAO management to solve memory corruption

Marko Pintera 11 年之前
父節點
當前提交
492ad2cac2
共有 68 個文件被更改,包括 2375 次插入1424 次删除
  1. 3 0
      BansheeCore/Include/BsCorePrerequisites.h
  2. 12 7
      BansheeCore/Include/BsCoreThreadAccessor.h
  3. 69 18
      BansheeCore/Include/BsMultiRenderTexture.h
  4. 180 51
      BansheeCore/Include/BsRenderTarget.h
  5. 86 27
      BansheeCore/Include/BsRenderTexture.h
  6. 116 60
      BansheeCore/Include/BsRenderWindow.h
  7. 3 3
      BansheeCore/Include/BsRenderWindowManager.h
  8. 4 0
      BansheeCore/Include/BsTexture.h
  9. 12 0
      BansheeCore/Include/BsViewport.h
  10. 9 9
      BansheeCore/Include/Win32/BsPlatformImpl.h
  11. 65 16
      BansheeCore/Source/BsCoreThreadAccessor.cpp
  12. 6 1
      BansheeCore/Source/BsMesh.cpp
  13. 4 0
      BansheeCore/Source/BsMeshHeap.cpp
  14. 74 42
      BansheeCore/Source/BsMultiRenderTexture.cpp
  15. 1 1
      BansheeCore/Source/BsRenderSystem.cpp
  16. 60 5
      BansheeCore/Source/BsRenderTarget.cpp
  17. 100 67
      BansheeCore/Source/BsRenderTexture.cpp
  18. 67 27
      BansheeCore/Source/BsRenderWindow.cpp
  19. 8 8
      BansheeCore/Source/BsRenderWindowManager.cpp
  20. 4 0
      BansheeCore/Source/BsTexture.cpp
  21. 6 6
      BansheeCore/Source/BsViewport.cpp
  22. 14 14
      BansheeCore/Source/Win32/BsPlatformImpl.cpp
  23. 10 10
      BansheeCore/Source/Win32/BsPlatformWndProc.cpp
  24. 33 9
      BansheeD3D11RenderSystem/Include/BsD3D11MultiRenderTexture.h
  25. 35 8
      BansheeD3D11RenderSystem/Include/BsD3D11RenderTexture.h
  26. 93 56
      BansheeD3D11RenderSystem/Include/BsD3D11RenderWindow.h
  27. 15 4
      BansheeD3D11RenderSystem/Source/BsD3D11MultiRenderTexture.cpp
  28. 14 10
      BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp
  29. 16 10
      BansheeD3D11RenderSystem/Source/BsD3D11RenderTexture.cpp
  30. 208 158
      BansheeD3D11RenderSystem/Source/BsD3D11RenderWindow.cpp
  31. 1 1
      BansheeD3D11RenderSystem/Source/BsD3D11RenderWindowManager.cpp
  32. 18 18
      BansheeD3D9RenderSystem/Include/BsD3D9Device.h
  33. 3 3
      BansheeD3D9RenderSystem/Include/BsD3D9DeviceManager.h
  34. 33 14
      BansheeD3D9RenderSystem/Include/BsD3D9MultiRenderTexture.h
  35. 1 0
      BansheeD3D9RenderSystem/Include/BsD3D9Prerequisites.h
  36. 1 1
      BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h
  37. 37 15
      BansheeD3D9RenderSystem/Include/BsD3D9RenderTexture.h
  38. 92 64
      BansheeD3D9RenderSystem/Include/BsD3D9RenderWindow.h
  39. 46 43
      BansheeD3D9RenderSystem/Source/BsD3D9Device.cpp
  40. 5 5
      BansheeD3D9RenderSystem/Source/BsD3D9DeviceManager.cpp
  41. 20 17
      BansheeD3D9RenderSystem/Source/BsD3D9MultiRenderTexture.cpp
  42. 30 25
      BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp
  43. 24 18
      BansheeD3D9RenderSystem/Source/BsD3D9RenderTexture.cpp
  44. 209 175
      BansheeD3D9RenderSystem/Source/BsD3D9RenderWindow.cpp
  45. 1 1
      BansheeD3D9RenderSystem/Source/BsD3D9RenderWindowManager.cpp
  46. 4 4
      BansheeEditor/Source/BsEditorWindowBase.cpp
  47. 1 1
      BansheeEditor/Source/BsGUIResourceTreeView.cpp
  48. 1 1
      BansheeEditor/Source/BsGUIWindowFrameWidget.cpp
  49. 2 1
      BansheeEditor/Source/BsSceneEditorWidget.cpp
  50. 1 1
      BansheeEditorExec/BsEditorExec.cpp
  51. 3 2
      BansheeEngine/Source/BsGUIManager.cpp
  52. 5 4
      BansheeEngine/Source/BsGUIViewport.cpp
  53. 33 13
      BansheeGLRenderSystem/Include/BsGLMultiRenderTexture.h
  54. 36 14
      BansheeGLRenderSystem/Include/BsGLRenderTexture.h
  55. 1 1
      BansheeGLRenderSystem/Include/BsGLVertexArrayObjectManager.h
  56. 0 1
      BansheeGLRenderSystem/Include/BsWin32VideoModeInfo.h
  57. 87 53
      BansheeGLRenderSystem/Include/BsWin32Window.h
  58. 24 28
      BansheeGLRenderSystem/Source/BsGLMultiRenderTexture.cpp
  59. 21 16
      BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp
  60. 23 25
      BansheeGLRenderSystem/Source/BsGLRenderTexture.cpp
  61. 24 11
      BansheeGLRenderSystem/Source/BsGLVertexArrayObjectManager.cpp
  62. 3 3
      BansheeGLRenderSystem/Source/BsWin32GLSupport.cpp
  63. 0 5
      BansheeGLRenderSystem/Source/BsWin32VideoModeInfo.cpp
  64. 213 183
      BansheeGLRenderSystem/Source/BsWin32Window.cpp
  65. 2 1
      BansheeRenderer/Source/BsBansheeRenderer.cpp
  66. 6 0
      BansheeUtility/Include/BsThreadPool.h
  67. 18 6
      BansheeUtility/Source/BsThreadPool.cpp
  68. 19 23
      SceneView.txt

+ 3 - 0
BansheeCore/Include/BsCorePrerequisites.h

@@ -81,6 +81,7 @@ namespace BansheeEngine
     class RenderTexture;
     class RenderTexture;
 	class MultiRenderTexture;
 	class MultiRenderTexture;
     class RenderWindow;
     class RenderWindow;
+	class RenderWindowCore;
     struct RenderOpMesh;
     struct RenderOpMesh;
     class StringInterface;
     class StringInterface;
     class SamplerState;
     class SamplerState;
@@ -134,6 +135,7 @@ namespace BansheeEngine
 	struct MaterialProxyPass;
 	struct MaterialProxyPass;
 	struct MeshProxy;
 	struct MeshProxy;
 	struct ShaderProxy;
 	struct ShaderProxy;
+	class ViewportProxy;
 	class DrawList;
 	class DrawList;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
@@ -235,6 +237,7 @@ namespace BansheeEngine
 	typedef std::shared_ptr<MaterialProxy> MaterialProxyPtr;
 	typedef std::shared_ptr<MaterialProxy> MaterialProxyPtr;
 	typedef std::shared_ptr<MeshProxy> MeshProxyPtr;
 	typedef std::shared_ptr<MeshProxy> MeshProxyPtr;
 	typedef std::shared_ptr<ShaderProxy> ShaderProxyPtr;
 	typedef std::shared_ptr<ShaderProxy> ShaderProxyPtr;
+	typedef std::shared_ptr<ViewportProxy> ViewportProxyPtr;
 	typedef std::shared_ptr<GpuParamDesc> GpuParamDescPtr;
 	typedef std::shared_ptr<GpuParamDesc> GpuParamDescPtr;
 	typedef std::shared_ptr<ResourceMetaData> ResourceMetaDataPtr;
 	typedef std::shared_ptr<ResourceMetaData> ResourceMetaDataPtr;
 }
 }

+ 12 - 7
BansheeCore/Include/BsCoreThreadAccessor.h

@@ -119,37 +119,42 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Resize the provided window to specified width and height in pixels.
 		 * @brief	Resize the provided window to specified width and height in pixels.
 		 */
 		 */
-		void resizeWindow(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height);
+		void resizeWindow(const RenderWindowPtr& renderWindow, UINT32 width, UINT32 height);
 
 
 		/**
 		/**
 		 * @brief	Move the provided window to specified screen coordinates.
 		 * @brief	Move the provided window to specified screen coordinates.
 		 */
 		 */
-		void moveWindow(RenderWindowPtr& renderWindow, INT32 left, INT32 top);
+		void moveWindow(const RenderWindowPtr& renderWindow, INT32 left, INT32 top);
 
 
 		/**
 		/**
 		 * @brief	Hide the provided window. (Does not destroy it, just hides it).
 		 * @brief	Hide the provided window. (Does not destroy it, just hides it).
 		 */
 		 */
-		void hideWindow(RenderWindowPtr& renderWindow);
+		void hideWindow(const RenderWindowPtr& renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Shows a previously hidden window.
 		 * @brief	Shows a previously hidden window.
 		 */
 		 */
-		void showWindow(RenderWindowPtr& renderWindow);
+		void showWindow(const RenderWindowPtr& renderWindow);
 
 
 		/**
 		/**
 		 * @copydoc RenderWindow::setFullscreen(UINT32, UINT32, float, UINT32)
 		 * @copydoc RenderWindow::setFullscreen(UINT32, UINT32, float, UINT32)
 		 */
 		 */
-		void setFullscreen(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0);
+		void setFullscreen(const RenderWindowPtr& renderWindow, UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0);
 
 
 		/**
 		/**
 		 * @copydoc RenderWindow::setFullscreen(const VideoMode&)
 		 * @copydoc RenderWindow::setFullscreen(const VideoMode&)
 		 */
 		 */
-		void setFullscreen(RenderWindowPtr& renderWindow, const VideoMode& mode);
+		void setFullscreen(const RenderWindowPtr& renderWindow, const VideoMode& mode);
 
 
 		/**
 		/**
 		 * @copydoc RenderWindow::setWindowed
 		 * @copydoc RenderWindow::setWindowed
 		 */
 		 */
-		void setWindowed(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height);
+		void setWindowed(const RenderWindowPtr& renderWindow, UINT32 width, UINT32 height);
+
+		/**
+		 * @copydoc RenderTargetcore::setPriority
+		 */
+		void setPriority(const RenderTargetPtr& renderTarget, UINT32 priority);
 
 
 		/**
 		/**
 		* @brief	Queues a new generic command that will be added to the command queue.
 		* @brief	Queues a new generic command that will be added to the command queue.

+ 69 - 18
BansheeCore/Include/BsMultiRenderTexture.h

@@ -16,14 +16,63 @@ namespace BansheeEngine
 		RENDER_SURFACE_DESC depthStencilSurface;
 		RENDER_SURFACE_DESC depthStencilSurface;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains various properties that describe a render texture.
+	 */
+	class BS_CORE_EXPORT MultiRenderTextureProperties : public RenderTargetProperties
+	{
+	public:
+		virtual ~MultiRenderTextureProperties() { }
+
+	private:
+		friend class MultiRenderTextureCore;
+		friend class MultiRenderTexture;
+	};
+
+	/**
+	 * @brief	Object representing multiple render textures. You may bind this to the pipeline
+	 *			in order to render to all or some of the textures at once.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT MultiRenderTextureCore : public RenderTargetCore
+	{
+	public:
+		virtual ~MultiRenderTextureCore();
+
+	protected:
+		MultiRenderTextureCore(MultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc);
+
+		/**
+		 * @copydoc	RenderTargetCore::getNonCore
+		 */
+		MultiRenderTexture* getNonCore() const;
+
+	private:
+		/**
+		 * @brief	Checks that all render surfaces and depth/stencil surface match. If they do not match
+		 *			an exception is thrown.
+		 */
+		void throwIfBuffersDontMatch() const;
+
+		// TODO - Not implemented
+		virtual void copyToMemory(PixelData &dst, FrameBuffer buffer = FB_AUTO);
+
+	protected:
+		Vector<TextureViewPtr> mColorSurfaces;
+		TextureViewPtr mDepthStencilSurface;
+	};
+
 	/**
 	/**
 	 * @brief	Object representing multiple render textures. You may bind this to the pipeline
 	 * @brief	Object representing multiple render textures. You may bind this to the pipeline
 	 *			in order to render to all or some of the textures at once.
 	 *			in order to render to all or some of the textures at once.
+	 *
+	 * @note	Sim thread only.
 	 */
 	 */
 	class BS_CORE_EXPORT MultiRenderTexture : public RenderTarget
 	class BS_CORE_EXPORT MultiRenderTexture : public RenderTarget
 	{
 	{
 	public:
 	public:
-		virtual ~MultiRenderTexture();
+		virtual ~MultiRenderTexture() { }
 
 
 		/**
 		/**
 		 * @copydoc	RenderTarget::initialize
 		 * @copydoc	RenderTarget::initialize
@@ -31,35 +80,37 @@ namespace BansheeEngine
 		void initialize(const MULTI_RENDER_TEXTURE_DESC& desc);
 		void initialize(const MULTI_RENDER_TEXTURE_DESC& desc);
 
 
 		/**
 		/**
-		 * @copydoc RenderTarget::isWindow.
+		 * @copydoc	RenderTexture::requiresTextureFlipping
+		 */
+		virtual bool requiresTextureFlipping() const { return false; }
+
+		/**
+		 * @brief	Returns properties that describe the render texture.
 		 */
 		 */
-		bool isWindow() const { return true; }
+		const MultiRenderTextureProperties& getProperties() const;
 
 
 		/**
 		/**
-		 * @copydoc RenderTarget::requiresTextureFlipping.
+		 * @brief	Retrieves a core implementation of a render texture usable only from the
+		 *			core thread.
+		 *
+		 * @note	Core thread only.
 		 */
 		 */
-		bool requiresTextureFlipping() const { return false; }
+		MultiRenderTextureCore* getCore() const;
 
 
 	protected:
 	protected:
-		MultiRenderTexture();
+		MultiRenderTexture() { }
 
 
 		/**
 		/**
-		 * @copydoc RenderTarget::destroy_internal()
+		 * @copydoc	RenderTexture::createCore
 		 */
 		 */
-		virtual void destroy_internal();
+		virtual RenderTargetCore* createCore();
 
 
-	private:
 		/**
 		/**
-		 * @brief	Checks that all render surfaces and depth/stencil surface match. If they do not match
-		 *			an exception is thrown.
+		 * @brief	Creates a core implementation of a render texture. This implementation
+		 *			is to be used on the core thread only.
 		 */
 		 */
-		void throwIfBuffersDontMatch() const;
+		virtual MultiRenderTextureCore* createCore(MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc) = 0;
 
 
-		// TODO - Not implemented
-		virtual void copyToMemory(PixelData &dst, FrameBuffer buffer = FB_AUTO);
-
-	protected:
-		Vector<TextureViewPtr> mColorSurfaces;
-		TextureViewPtr mDepthStencilSurface;
+		MULTI_RENDER_TEXTURE_DESC mDesc;
 	};
 	};
 }
 }

+ 180 - 51
BansheeCore/Include/BsRenderTarget.h

@@ -22,25 +22,12 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/**
 	/**
-	 * @brief	Render target is a frame buffer or a texture that the render
-	 *			system renders to.
-	 *
-	 * @note	Thread safe, except where noted otherwise.
+	 * @brief	Contains various properties that describe a render target.
 	 */
 	 */
-    class BS_CORE_EXPORT RenderTarget : public CoreObject
-    {
-    public:
-		/**
-		 * @brief	Frame buffer type when double-buffering is used.
-		 */
-		enum FrameBuffer
-		{
-			FB_FRONT,
-			FB_BACK,
-			FB_AUTO
-		};
-
-        virtual ~RenderTarget();
+	class BS_CORE_EXPORT RenderTargetProperties
+	{
+	public:
+		virtual ~RenderTargetProperties() { }
 
 
 		/**
 		/**
 		 * @brief	Returns a name of the render target, used for easier identification.
 		 * @brief	Returns a name of the render target, used for easier identification.
@@ -49,11 +36,15 @@ namespace BansheeEngine
 
 
 		/**
 		/**
 		 * @brief	Returns width of the render target, in pixels.
 		 * @brief	Returns width of the render target, in pixels.
+		 * 
+		 * @note	Sim thread only.
 		 */
 		 */
         UINT32 getWidth() const { return mWidth; }
         UINT32 getWidth() const { return mWidth; }
 
 
 		/**
 		/**
 		 * @brief	Returns height of the render target, in pixels.
 		 * @brief	Returns height of the render target, in pixels.
+		 *
+		 * @note	Sim thread only.
 		 */
 		 */
         UINT32 getHeight() const { return mHeight; }
         UINT32 getHeight() const { return mHeight; }
 
 
@@ -77,17 +68,18 @@ namespace BansheeEngine
 		bool getVSync() const { return mVSync; }
 		bool getVSync() const { return mVSync; }
 
 
 		/**
 		/**
-		 * @brief	Queries the render target for a custom attribute. This may be anything and is
-		 *			implementation specific.
-		 *
-		 * @note	Core thread only.
+		 * @brief	Returns how often should the frame be presented in respect to
+		 *			display device refresh rate. Normal value is 1 where it will
+		 *			match the refresh rate. Higher values will decrease the frame
+		 *			rate (e.g. present interval of 2 on 60Hz refresh rate will display
+		 *			at most 30 frames per second).
 		 */
 		 */
-		virtual void getCustomAttribute(const String& name, void* pData) const;
+		UINT32 getVSyncInterval() const { return mVSyncInterval; }
 
 
 		/**
 		/**
-		 * @brief	Returns true if the render target is a render window.
+		 * @brief	Returns true if pixels written to the render target will be gamma corrected.
 		 */
 		 */
-		virtual bool isWindow() const = 0;
+		bool isHwGammaEnabled() const { return mHwGamma; }
 
 
 		/**
 		/**
 		 * @brief	Returns true if the render target can be used for rendering.
 		 * @brief	Returns true if the render target can be used for rendering.
@@ -97,39 +89,89 @@ namespace BansheeEngine
 		bool isActive() const { return mActive; }
 		bool isActive() const { return mActive; }
 
 
 		/**
 		/**
-		 * @brief	Returns true if pixels written to the render target will be gamma corrected.
+		 * @brief	Returns render target priority. Targets with higher priority will be 
+		 *			rendered before ones with lower priority.
 		 */
 		 */
-		bool isHwGammaEnabled() const { return mHwGamma; }
+		INT32 getPriority() const { return mPriority; }
 
 
 		/**
 		/**
-		 * @brief	Makes the render target active or inactive. (e.g. for a window, it will hide or restore the window).
-		 *
-		 * @note	Core thread only.
+		 * @brief	Returns true if the render target is a render window.
 		 */
 		 */
-		virtual void setActive(bool state) { mActive = state; }
+		bool isWindow() const { return mIsWindow; }
 
 
 		/**
 		/**
-		 * @brief	Returns render target priority. Targets with higher priority will be 
-		 *			rendered before ones with lower priority.
+		 * @brief	Does the texture need to be vertically flipped because of different screen space coordinate systems.
+		 *			(i.e. is origin top left or bottom left. Engine default is top left.)
 		 */
 		 */
-		INT32 getPriority() const { return mPriority; }
+		bool requiresTextureFlipping() const { return mRequiresTextureFlipping; }
+
+	protected:
+		friend class RenderTargetCore;
+		friend class RenderTarget;
+
+		String mName;
+
+		UINT32 mWidth = 0;
+		UINT32 mHeight = 0;
+		UINT32 mColorDepth = 32;
+
+		INT32 mPriority = 0;
+		UINT32 mVSyncInterval = 1;
+
+		bool mActive = true;
+		bool mHwGamma = false;
+		bool mVSync = false;
+		bool mRequiresTextureFlipping = false;
+		bool mIsWindow = false;
+
+		UINT32 mMultisampleCount = 0;
+		String mMultisampleHint;
+	};
+
+	/**
+	 * @brief	Provides access to internal render target implementation usable only from the core thread.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT RenderTargetCore
+	{
+	public:
+		/**
+		 * @brief	Frame buffer type when double-buffering is used.
+		 */
+		enum FrameBuffer
+		{
+			FB_FRONT,
+			FB_BACK,
+			FB_AUTO
+		};
+
+		RenderTargetCore(RenderTarget* parent, RenderTargetProperties* properties);
+		virtual ~RenderTargetCore();
+
+		/**
+		 * @brief	Makes the render target active or inactive. (e.g. for a window, it will hide or restore the window).
+		 *
+		 * @note	Core thread only.
+		 */
+		virtual void setActive(bool state) { mProperties->mActive = state; markCoreDirty(); }
 
 
 		/**
 		/**
 		 * @brief	Sets a priority that determines in which orders the render targets the processed.
 		 * @brief	Sets a priority that determines in which orders the render targets the processed.
 		 * 			
 		 * 			
 		 * @param	priority	The priority. Higher value means the target will be rendered sooner.
 		 * @param	priority	The priority. Higher value means the target will be rendered sooner.
 		 */
 		 */
-		void setPriority(INT32 priority) { mPriority = priority; }
+		void setPriority(INT32 priority) { mProperties->mPriority = priority; markCoreDirty(); }
 
 
-        /**
-         * @brief	Swaps the frame buffers to display the next frame.
-         * 			
+		/**
+		 * @brief	Swaps the frame buffers to display the next frame.
+		 *
 		 * @note	Core thread only.
 		 * @note	Core thread only.
-         */
+		 */
 		virtual void swapBuffers() {};
 		virtual void swapBuffers() {};
 
 
 		/**
 		/**
-		 * @brief	Copy data from the render target into the provided pixel buffer. 
+		 * @brief	Copy data from the render target into the provided pixel buffer.
 		 *
 		 *
 		 * @param	dst		Destination buffer to copy the data to. Caller must ensure the buffer is of adequate size.
 		 * @param	dst		Destination buffer to copy the data to. Caller must ensure the buffer is of adequate size.
 		 * @param	buffer	Which buffer is data taken from. This is irrelevant for single buffer render targets.
 		 * @param	buffer	Which buffer is data taken from. This is irrelevant for single buffer render targets.
@@ -138,33 +180,120 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual void copyToMemory(PixelData &dst, FrameBuffer buffer = FB_AUTO) = 0;
 		virtual void copyToMemory(PixelData &dst, FrameBuffer buffer = FB_AUTO) = 0;
 
 
+		/**
+		 * @brief	Queries the render target for a custom attribute. This may be anything and is
+		 *			implementation specific.
+		 *
+		 * @note	Core thread only.
+		 */
+		virtual void getCustomAttribute(const String& name, void* pData) const;
+
+		/**
+		 * @brief	Returns properties that describe the render target.
+		 */
+		const RenderTargetProperties& getProperties() const;
+
+		/**
+		 * @brief	Returns the non core version of the render target.
+		 */
+		RenderTarget* getNonCore() const { return mParent; }
+
+		/**
+		 * @brief	Returns true if this object was modified and the sim thread version requires an update.
+		 */
+		bool _isCoreDirty() const { return mCoreDirty; }
+
+		/**
+		 * @brief	Marks the object as clean. Usually called after the sim thread version was updated.
+		 */
+		void _markCoreClean() { mCoreDirty = false; }
+
+	protected:
+		friend class RenderTarget;
+
+		/**
+		 * @brief	Marks this object as modified. Signals the system that the sim thread verison
+		 *			of the object needs an update.
+		 */
+		void markCoreDirty() { mCoreDirty = true; }
+
+		RenderTargetProperties* mProperties;
+		RenderTarget* mParent;
+
+	private:
+		bool mCoreDirty = true;
+	};
+
+	/**
+	 * @brief	Render target is a frame buffer or a texture that the render
+	 *			system renders to.
+	 *
+	 * @note	Sim thread unless noted otherwise. Retrieve core implementation from getCore() 
+	 *			for core thread only functionality.
+	 */
+    class BS_CORE_EXPORT RenderTarget : public CoreObject
+    {
+    public:
+        virtual ~RenderTarget();
+
 		/**
 		/**
 		 * @brief	Does the texture need to be vertically flipped because of different screen space coordinate systems.
 		 * @brief	Does the texture need to be vertically flipped because of different screen space coordinate systems.
 		 *			(i.e. is origin top left or bottom left. Engine default is top left.)
 		 *			(i.e. is origin top left or bottom left. Engine default is top left.)
 		 */
 		 */
 		virtual bool requiresTextureFlipping() const = 0;
 		virtual bool requiresTextureFlipping() const = 0;
 
 
+		/**
+		 * @brief	Queries the render target for a custom attribute. This may be anything and is
+		 *			implementation specific.
+		 */
+		virtual void getCustomAttribute(const String& name, void* pData) const;
+
+		/**
+		 * @brief	Returns properties that describe the render target.
+		 *
+		 * @note	Sim thread only.
+		 */
+		const RenderTargetProperties& getProperties() const;
+
+		/**
+		 * @brief	Retrieves a core implementation of a render target usable only from the
+		 *			core thread.
+		 */
+		RenderTargetCore* getCore() const;
+
 		/**
 		/**
 		 * @brief	Event that gets triggered whenever the render target is resized.
 		 * @brief	Event that gets triggered whenever the render target is resized.
 		 *
 		 *
 		 * @note	Sim thread only.
 		 * @note	Sim thread only.
 		 */
 		 */
 		mutable Event<void()> onResized;
 		mutable Event<void()> onResized;
+
     protected:
     protected:
 		RenderTarget();
 		RenderTarget();
 
 
-        String mName;
+		/**
+		 * @brief	Creates a new instance of render target properties used for storing
+		 *			render target data and providing easy access to it.
+		 */
+		virtual RenderTargetProperties* createProperties() const = 0;
 
 
-        UINT32 mWidth;
-        UINT32 mHeight;
-        UINT32 mColorDepth;
-		
-		INT32 mPriority;
+		/**
+		 * @brief	Creates a core implementation of a render target. This implementation
+		 *			is to be used on the core thread only.
+		 */
+		virtual RenderTargetCore* createCore() = 0;
 
 
-        bool mActive;
-		bool mHwGamma;
-		bool mVSync;
-		UINT32 mMultisampleCount;
-		String mMultisampleHint;
+		/**
+		 * @copydoc	CoreObject::initialize_internal
+		 */
+		virtual void initialize_internal();
+
+		/**
+		 * @copydoc	CoreObject::destroy_internal
+		 */
+		virtual void destroy_internal();
+
+		RenderTargetCore* mCore;
+		RenderTargetProperties* mProperties;
     };
     };
 }
 }

+ 86 - 27
BansheeCore/Include/BsRenderTexture.h

@@ -15,16 +15,70 @@ namespace BansheeEngine
 		RENDER_SURFACE_DESC depthStencilSurface;
 		RENDER_SURFACE_DESC depthStencilSurface;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains various properties that describe a render texture.
+	 */
+	class BS_CORE_EXPORT RenderTextureProperties : public RenderTargetProperties
+	{
+	public:
+		virtual ~RenderTextureProperties() { }
+
+	private:
+		friend class RenderTextureCore;
+		friend class RenderTexture;
+	};
+
+	/**
+	 * @brief	Provides access to internal render texture implementation usable only from the core thread.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT RenderTextureCore : public RenderTargetCore
+	{
+	public:
+		RenderTextureCore(RenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc);
+		virtual ~RenderTextureCore();
+
+		/**
+		 * @copydoc	RenderTargetCore::copyToMemory
+		 */
+		virtual void copyToMemory(PixelData &dst, FrameBuffer buffer = FB_AUTO);
+
+		/**
+		 * @brief	Returns properties that describe the render texture.
+		 */
+		const RenderTextureProperties& getProperties() const { return *static_cast<RenderTextureProperties*>(mProperties); }
+
+		/**
+		 * @copydoc	RenderTargetCore::getNonCore
+		 */
+		RenderTexture* getNonCore() const;
+
+	private:
+		/**
+		 * @brief	Throws an exception of the color and depth/stencil buffers aren't compatible.
+		 */
+		void throwIfBuffersDontMatch() const;
+
+	protected:
+		friend class RenderTexture;
+
+		TextureViewPtr mColorSurface;
+		TextureViewPtr mDepthStencilSurface;
+	};
+
 	/**
 	/**
 	 * @brief	Render target specialization that allows you to render into a texture you may
 	 * @brief	Render target specialization that allows you to render into a texture you may
 	 *			later bind in further render operations.
 	 *			later bind in further render operations.
 	 *
 	 *
-	 * @note	Thread safe, except where noted otherwise.
+	 * @note	Sim thread only. Retrieve core implementation from getCore()
+	 *			for core thread only functionality.
 	 */
 	 */
     class BS_CORE_EXPORT RenderTexture : public RenderTarget
     class BS_CORE_EXPORT RenderTexture : public RenderTarget
     {
     {
 	public:
 	public:
-		virtual ~RenderTexture();
+		virtual ~RenderTexture() { }
 
 
 		/**
 		/**
 		 * @brief	Creates a new render texture with color and optionally depth/stencil surfaces.
 		 * @brief	Creates a new render texture with color and optionally depth/stencil surfaces.
@@ -44,14 +98,9 @@ namespace BansheeEngine
 			const String& multisampleHint = "", bool createDepth = true, PixelFormat depthStencilFormat = PF_D24S8);
 			const String& multisampleHint = "", bool createDepth = true, PixelFormat depthStencilFormat = PF_D24S8);
 
 
 		/**
 		/**
-		 * @copydoc RenderTarget::isWindow.
+		 * @copydoc	RenderTexture::requiresTextureFlipping
 		 */
 		 */
-		bool isWindow() const { return false; }
-
-		/**
-		 * @copydoc RenderTarget::requiresTextureFlipping.
-		 */
-		bool requiresTextureFlipping() const { return false; }
+		virtual bool requiresTextureFlipping() const { return false; }
 
 
 		/**
 		/**
 		 * @brief	Returns a color surface texture you may bind as an input to an GPU program.
 		 * @brief	Returns a color surface texture you may bind as an input to an GPU program.
@@ -61,42 +110,52 @@ namespace BansheeEngine
 		const HTexture& getBindableColorTexture() const { return mBindableColorTex; }
 		const HTexture& getBindableColorTexture() const { return mBindableColorTex; }
 
 
 		/**
 		/**
-		* @brief	Returns a depth/stencil surface texture you may bind as an input to an GPU program.
-		*
-		* @note		Be aware that you cannot bind a render texture for reading and writing at the same time.
-		*/
+		 * @brief	Returns a depth/stencil surface texture you may bind as an input to an GPU program.
+		 *
+		 * @note		Be aware that you cannot bind a render texture for reading and writing at the same time.
+		 */
 		const HTexture& getBindableDepthStencilTexture() const { return mBindableDepthStencilTex; }
 		const HTexture& getBindableDepthStencilTexture() const { return mBindableDepthStencilTex; }
 
 
+		/**
+		 * @brief	Returns properties that describe the render texture.
+		 */
+		const RenderTextureProperties& getProperties() const;
+
+		/**
+		 * @brief	Retrieves a core implementation of a render texture usable only from the
+		 *			core thread.
+		 *
+		 * @note	Core thread only.
+		 */
+		RenderTextureCore* getCore() const;
+
 	protected:
 	protected:
 		friend class TextureManager;
 		friend class TextureManager;
 
 
-		RenderTexture();
+		RenderTexture() { }
 
 
 		/**
 		/**
 		 * @copydoc	RenderTarget::initialize
 		 * @copydoc	RenderTarget::initialize
 		 */
 		 */
-		void initialize(const RENDER_TEXTURE_DESC& desc);
+		virtual void initialize(const RENDER_TEXTURE_DESC& desc);
 
 
 		/**
 		/**
-		 * @copydoc RenderTarget::destroy_internal()
-		 */
-		virtual void destroy_internal();
-	private:
-		/**
-		 * @brief	Throws an exception of the color and depth/stencil buffers aren't compatible.
+		 * @copydoc	RenderTexture::createCore
 		 */
 		 */
-		void throwIfBuffersDontMatch() const;
+		virtual RenderTargetCore* createCore();
 
 
 		/**
 		/**
-		 * @copydoc	RenderTarget::copyToMemory
+		 * @brief	Creates a core implementation of a render texture. This implementation
+		 *			is to be used on the core thread only.
 		 */
 		 */
-		virtual void copyToMemory(PixelData &dst, FrameBuffer buffer = FB_AUTO);
+		virtual RenderTextureCore* createCore(RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc) = 0;
 
 
 	protected:
 	protected:
-		TextureViewPtr mColorSurface;
-		TextureViewPtr mDepthStencilSurface;
-
 		HTexture mBindableColorTex;
 		HTexture mBindableColorTex;
 		HTexture mBindableDepthStencilTex;
 		HTexture mBindableDepthStencilTex;
+
+		RENDER_SURFACE_DESC mColorSurfaceDesc;
+		RENDER_SURFACE_DESC mDepthStencilSurfaceDesc;
 	};
 	};
 }
 }

+ 116 - 60
BansheeCore/Include/BsRenderWindow.h

@@ -52,15 +52,66 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/**
 	/**
-	 * @brief	Render target specialization that allows you to render into window
-	 *			frame buffer(s).
+	 * @brief	Contains various properties that describe a render window.
+	 */
+	class BS_CORE_EXPORT RenderWindowProperties : public RenderTargetProperties
+	{
+	public:
+		virtual ~RenderWindowProperties() { }
+
+		/**
+		 * @brief	Gets the horizontal origin of the window in pixels.
+		 */
+		INT32 getLeft() const { return mLeft; }
+
+		/**
+		 * @brief	Gets the vertical origin of the window in pixels.
+		 */
+		INT32 getTop() const { return mTop; }
+
+		/**
+		 * @brief	Indicates whether the window currently has keyboard focus.
+		 */
+		bool hasFocus() const { return mHasFocus; }
+
+		/**
+		 * @brief	Returns true if window is running in fullscreen mode.
+		 */
+		bool isFullScreen() const { return mIsFullScreen; }
+
+		/**
+		 * @brief	Returns true if the window is modal (blocks interaction with
+		 *			any non-modal window until closed).
+		 */
+		bool isModal() const { return mIsModal; }
+
+		/**
+		 * @brief	Returns true if the window is hidden.
+		 */
+		bool isHidden() const { return mHidden; }
+
+	protected:
+		friend class RenderWindowCore;
+		friend class RenderWindow;
+
+		bool mIsFullScreen = false;
+		INT32 mLeft = 0;
+		INT32 mTop = 0;
+		bool mHasFocus = false;
+		bool mHidden = false;
+		bool mIsModal = false;
+	};
+
+	/**
+	 * @brief	Provides access to internal render window implementation usable only from the core thread.
 	 *
 	 *
-	 * @note	Thread safe, except where noted otherwise.
+	 * @note	Core thread only.
 	 */
 	 */
-    class BS_CORE_EXPORT RenderWindow : public RenderTarget
-    {
-    public:
-		virtual ~RenderWindow();
+	class BS_CORE_EXPORT RenderWindowCore : public RenderTargetCore
+	{
+	public:
+		RenderWindowCore(RenderWindow* parent, RenderWindowProperties* properties);
+		virtual ~RenderWindowCore() { }
 
 
 		/** 
 		/** 
 		 * @brief	Switches the window to fullscreen mode. Child windows cannot go into fullscreen mode.
 		 * @brief	Switches the window to fullscreen mode. Child windows cannot go into fullscreen mode.
@@ -116,49 +167,62 @@ namespace BansheeEngine
         virtual void move(INT32 left, INT32 top) = 0;
         virtual void move(INT32 left, INT32 top) = 0;
 
 
 		/**
 		/**
-		 * @copydoc RenderTarget::isWindow.
+		 * @brief	Returns properties that describe the render texture.
 		 */
 		 */
-		bool isWindow() const { return true; }
+		const RenderWindowProperties& getProperties() const { return *static_cast<RenderWindowProperties*>(mProperties); }
 
 
-        /**
-         * @brief	Indicates whether the window is visible (not minimized or obscured).
-         */
-        virtual bool isVisible() const { return true; }
+		/**
+		 * @copydoc	RenderTargetCore::getNonCore
+		 */
+		RenderWindow* getNonCore() const;
 
 
-        /** 
-        * @copydoc RenderTarget::isActive
-		*/
-        virtual bool isActive() const { return mActive && isVisible(); }
+	protected:
+		friend class RenderWindow;
+		friend class RenderWindowManager;
 
 
-        /** 
-        * @brief	Indicates whether the window has been closed by the user.
-		*/
-        virtual bool isClosed() const = 0;
-        
-        /** 
-        * @brief	Returns true if window is running in fullscreen mode.
-		*/
-        virtual bool isFullScreen() const;
+		/**
+		 * @brief	Called when window is moved or resized.
+		 *
+		 * @note	Core thread.
+		 */
+		virtual void _windowMovedOrResized();
 
 
 		/**
 		/**
-		 * @brief	Returns true if the window is modal.
+		 * @brief	Called when window has received focus.
+		 *
+		 * @note	Core thread.
 		 */
 		 */
-		bool isModal() const { return mDesc.modal; }
+		virtual void _windowFocusReceived();
 
 
 		/**
 		/**
-		 * @brief	Gets the horizontal origin of the window in pixels.
+		 * @brief	Called when window has lost focus.
+		 *
+		 * @note	Core thread.
 		 */
 		 */
-		INT32 getLeft() const { return mLeft; }
+		virtual void _windowFocusLost();
+	};
+
+	/**
+	 * @brief	Render target specialization that allows you to render into window
+	 *			frame buffer(s).
+	 *
+	 * @note	Sim thread only. Retrieve core implementation from getCore()
+	 *			for core thread only functionality.
+	 */
+    class BS_CORE_EXPORT RenderWindow : public RenderTarget
+    {
+    public:
+		virtual ~RenderWindow() { }
 
 
 		/**
 		/**
-		 * @brief	Gets the vertical origin of the window in pixels.
+		 * @copydoc	RenderTarget::initialize
 		 */
 		 */
-		INT32 getTop() const { return mTop; }
+		virtual void initialize(const RENDER_WINDOW_DESC& desc);
 
 
 		/**
 		/**
-		 * @brief	Indicates whether the window currently has keyboard focus.
+		 * @copydoc	RenderTarget::destroy
 		 */
 		 */
-		bool hasFocus() const { return mHasFocus; }
+		virtual void destroy();	
 
 
 		/**
 		/**
 		 * @brief	Converts screen position into window local position.
 		 * @brief	Converts screen position into window local position.
@@ -171,9 +235,17 @@ namespace BansheeEngine
 		virtual Vector2I windowToScreenPos(const Vector2I& windowPos) const = 0;
 		virtual Vector2I windowToScreenPos(const Vector2I& windowPos) const = 0;
 
 
 		/**
 		/**
-		 * @copydoc	RenderTarget::destroy
+		 * @brief	Returns properties that describe the render window.
+		 */
+		const RenderWindowProperties& getProperties() const;
+
+		/**
+		 * @brief	Retrieves a core implementation of a render window usable only from the
+		 *			core thread.
+		 *
+		 * @note	Core thread only.
 		 */
 		 */
-		virtual void destroy();
+		RenderWindowCore* getCore() const;
 
 
 		/**
 		/**
 		 * @brief	Creates a new render window using the specified options. Optionally
 		 * @brief	Creates a new render window using the specified options. Optionally
@@ -184,36 +256,20 @@ namespace BansheeEngine
     protected:
     protected:
 		friend class RenderWindowManager;
 		friend class RenderWindowManager;
 
 
-        RenderWindow(const RENDER_WINDOW_DESC& desc);
-
-		/**
-         * @brief	Called when window is moved or resized.
-		 *
-		 * @note	Core thread.
-         */
-        virtual void _windowMovedOrResized();
+		RenderWindow() { }
 
 
 		/**
 		/**
-         * @brief	Called when window has received focus.
-		 *
-		 * @note	Core thread.
-         */
-		virtual void _windowFocusReceived();
+		 * @copydoc	RenderWindow::createCore
+		 */
+		virtual RenderTargetCore* createCore();
 
 
 		/**
 		/**
-         * @brief	Called when window has lost focus.
-		 *
-		 * @note	Core thread.
-         */
-		virtual void _windowFocusLost();
+		 * @brief	Creates a core implementation of a render window. This implementation
+		 *			is to be used on the core thread only.
+		 */
+		virtual RenderWindowCore* createCore(RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc) = 0;
         
         
 	protected:
 	protected:
-		bool mIsFullScreen;
-		INT32 mLeft;
-		INT32 mTop;
-		bool mHasFocus;
-		bool mHidden;
-
 		RENDER_WINDOW_DESC mDesc;
 		RENDER_WINDOW_DESC mDesc;
     };
     };
 }
 }

+ 3 - 3
BansheeCore/Include/BsRenderWindowManager.h

@@ -60,17 +60,17 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Called by the core thread when window receives focus.
 		 * @brief	Called by the core thread when window receives focus.
 		 */
 		 */
-		void windowFocusReceived(RenderWindow* window);
+		void windowFocusReceived(RenderWindowCore* window);
 
 
 		/**
 		/**
 		 * @brief	Called by the core thread when window loses focus.
 		 * @brief	Called by the core thread when window loses focus.
 		 */
 		 */
-		void windowFocusLost(RenderWindow* window);
+		void windowFocusLost(RenderWindowCore* window);
 
 
 		/**
 		/**
 		 * @brief	Called by the core thread when window is moved or resized.
 		 * @brief	Called by the core thread when window is moved or resized.
 		 */
 		 */
-		void windowMovedOrResized(RenderWindow* window);
+		void windowMovedOrResized(RenderWindowCore* window);
 
 
 	protected:
 	protected:
 		BS_MUTEX(mWindowMutex);
 		BS_MUTEX(mWindowMutex);

+ 4 - 0
BansheeCore/Include/BsTexture.h

@@ -259,11 +259,15 @@ namespace BansheeEngine
 		 * @brief	Requests a texture view for the specified mip and array ranges. Returns an existing view of one for
 		 * @brief	Requests a texture view for the specified mip and array ranges. Returns an existing view of one for
 		 *			the specified ranges already exists, otherwise creates a new one. You must release all views
 		 *			the specified ranges already exists, otherwise creates a new one. You must release all views
 		 *			by calling "releaseView" when done.
 		 *			by calling "releaseView" when done.
+		 *
+		 * @note	Core thread only.
 		 */
 		 */
 		static TextureViewPtr requestView(TexturePtr texture, UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage);
 		static TextureViewPtr requestView(TexturePtr texture, UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage);
 
 
 		/**
 		/**
 		 * @brief	Releases the view. View won't actually get destroyed until all references to it are released.
 		 * @brief	Releases the view. View won't actually get destroyed until all references to it are released.
+		 *
+		 * @note	Core thread only.
 		 */
 		 */
 		static void releaseView(TextureViewPtr view);
 		static void releaseView(TextureViewPtr view);
 
 

+ 12 - 0
BansheeCore/Include/BsViewport.h

@@ -12,6 +12,8 @@ namespace BansheeEngine
 	 * @brief	Viewport provides you with a way to render to only a part of a 
 	 * @brief	Viewport provides you with a way to render to only a part of a 
 	 * 			RenderTarget. It also allows you to set up color/depth/stencil
 	 * 			RenderTarget. It also allows you to set up color/depth/stencil
 	 * 			clear values for that specific region.
 	 * 			clear values for that specific region.
+	 *
+	 * @note	Thread safe unless noted otherwise.
 	 */
 	 */
 	class BS_CORE_EXPORT Viewport
 	class BS_CORE_EXPORT Viewport
     {
     {
@@ -58,21 +60,29 @@ namespace BansheeEngine
 
 
         /**
         /**
          * @brief	Gets the actual x coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
          * @brief	Gets the actual x coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
+		 *
+		 * @note	Sim thread only.
          */
          */
 		INT32 getX() const;
 		INT32 getX() const;
 
 
         /**
         /**
          * @brief	Gets the actual y coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
          * @brief	Gets the actual y coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
+		 *
+		 * @note	Sim thread only.
          */
          */
 		INT32 getY() const;
 		INT32 getY() const;
 
 
 		/**
 		/**
          * @brief	Gets the actual width coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
          * @brief	Gets the actual width coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
+		 *
+		 * @note	Sim thread only.
          */
          */
 		INT32 getWidth() const;
 		INT32 getWidth() const;
 
 
 		/**
 		/**
          * @brief	Gets the actual height coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
          * @brief	Gets the actual height coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
+		 *
+		 * @note	Sim thread only.
          */
          */
 		INT32 getHeight() const;
 		INT32 getHeight() const;
                
                
@@ -85,6 +95,8 @@ namespace BansheeEngine
 
 
 		/**
 		/**
 		 * @brief	Returns actual area of the viewport, in pixels.
 		 * @brief	Returns actual area of the viewport, in pixels.
+		 *
+		 * @note	Sim thread only.
 		 */
 		 */
 		RectI getArea() const;
 		RectI getArea() const;
 
 

+ 9 - 9
BansheeCore/Include/Win32/BsPlatformImpl.h

@@ -326,21 +326,21 @@ namespace BansheeEngine
 		 * 			
 		 * 			
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		static Event<void(RenderWindow*)> onWindowFocusReceived;
+		static Event<void(RenderWindowCore*)> onWindowFocusReceived;
 
 
 		/**
 		/**
 		 * @brief	Triggered whenever a window loses focus.
 		 * @brief	Triggered whenever a window loses focus.
 		 * 			
 		 * 			
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		static Event<void(RenderWindow*)> onWindowFocusLost;
+		static Event<void(RenderWindowCore*)> onWindowFocusLost;
 
 
 		/**
 		/**
 		 * @brief	Triggered whenever a window gets moved or resized.
 		 * @brief	Triggered whenever a window gets moved or resized.
 		 * 			
 		 * 			
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		static Event<void(RenderWindow*)> onWindowMovedOrResized;
+		static Event<void(RenderWindowCore*)> onWindowMovedOrResized;
 
 
 		/**
 		/**
 		 * @brief	Triggered whenever mouse capture state for the window is changed
 		 * @brief	Triggered whenever mouse capture state for the window is changed
@@ -353,11 +353,11 @@ namespace BansheeEngine
 		static bool mIsCursorHidden;
 		static bool mIsCursorHidden;
 		static NativeCursorData mCursor;
 		static NativeCursorData mCursor;
 		static bool mUsingCustomCursor;
 		static bool mUsingCustomCursor;
-		static Map<const RenderWindow*, WindowNonClientAreaData> mNonClientAreas;
+		static Map<const RenderWindowCore*, WindowNonClientAreaData> mNonClientAreas;
 
 
 		static bool mIsTrackingMouse;
 		static bool mIsTrackingMouse;
-		static Vector<RenderWindow*> mMouseLeftWindows;
-		static Stack<RenderWindow*> mModalWindowStack;
+		static Vector<RenderWindowCore*> mMouseLeftWindows;
+		static Stack<RenderWindowCore*> mModalWindowStack;
 
 
 		static NativeDropTargetData mDropTargets;
 		static NativeDropTargetData mDropTargets;
 
 
@@ -369,8 +369,8 @@ namespace BansheeEngine
 		static void win32ShowCursor();
 		static void win32ShowCursor();
 		static void win32HideCursor();
 		static void win32HideCursor();
 
 
-		static void windowFocusReceived(RenderWindow* window);
-		static void windowFocusLost(RenderWindow* window);
-		static void windowMovedOrResized(RenderWindow* window);
+		static void windowFocusReceived(RenderWindowCore* window);
+		static void windowFocusLost(RenderWindowCore* window);
+		static void windowMovedOrResized(RenderWindowCore* window);
 	};
 	};
 }
 }

+ 65 - 16
BansheeCore/Source/BsCoreThreadAccessor.cpp

@@ -161,44 +161,93 @@ namespace BansheeEngine
 			resource, subresourceIdx, data, std::placeholders::_1));
 			resource, subresourceIdx, data, std::placeholders::_1));
 	}
 	}
 
 
-	void CoreThreadAccessorBase::resizeWindow(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height)
+	void CoreThreadAccessorBase::resizeWindow(const RenderWindowPtr& renderWindow, UINT32 width, UINT32 height)
 	{
 	{
-		mCommandQueue->queue(std::bind(&RenderWindow::resize, renderWindow.get(), width, height));
+		std::function<void(RenderWindowPtr, UINT32, UINT32)> resizeFunc = 
+			[](RenderWindowPtr renderWindow, UINT32 width, UINT32 height)
+		{
+			renderWindow->getCore()->resize(width, height);
+		};
+
+		mCommandQueue->queue(std::bind(resizeFunc, renderWindow, width, height));
 	}
 	}
 
 
-	void CoreThreadAccessorBase::moveWindow(RenderWindowPtr& renderWindow, INT32 left, INT32 top)
+	void CoreThreadAccessorBase::moveWindow(const RenderWindowPtr& renderWindow, INT32 left, INT32 top)
 	{
 	{
-		mCommandQueue->queue(std::bind(&RenderWindow::move, renderWindow.get(), left, top));
+		std::function<void(RenderWindowPtr, INT32, INT32)> moveFunc =
+			[](RenderWindowPtr renderWindow, INT32 left, INT32 top)
+		{
+			renderWindow->getCore()->move(left, top);
+		};
+
+		mCommandQueue->queue(std::bind(moveFunc, renderWindow, left, top));
 	}
 	}
 
 
-	void CoreThreadAccessorBase::hideWindow(RenderWindowPtr& renderWindow)
+	void CoreThreadAccessorBase::hideWindow(const RenderWindowPtr& renderWindow)
 	{
 	{
-		mCommandQueue->queue(std::bind(&RenderWindow::setHidden, renderWindow.get(), true));
+		std::function<void(RenderWindowPtr)> hideFunc =
+			[](RenderWindowPtr renderWindow)
+		{
+			renderWindow->getCore()->setHidden(true);
+		};
+
+		mCommandQueue->queue(std::bind(hideFunc, renderWindow));
 	}
 	}
 
 
-	void CoreThreadAccessorBase::showWindow(RenderWindowPtr& renderWindow)
+	void CoreThreadAccessorBase::showWindow(const RenderWindowPtr& renderWindow)
 	{
 	{
-		mCommandQueue->queue(std::bind(&RenderWindow::setHidden, renderWindow.get(), false));
+		std::function<void(RenderWindowPtr)> showFunc =
+			[](RenderWindowPtr renderWindow)
+		{
+			renderWindow->getCore()->setHidden(false);
+		};
+
+		mCommandQueue->queue(std::bind(showFunc, renderWindow));
 	}
 	}
 
 
-	void CoreThreadAccessorBase::setFullscreen(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height, 
+	void CoreThreadAccessorBase::setFullscreen(const RenderWindowPtr& renderWindow, UINT32 width, UINT32 height,
 		float refreshRate, UINT32 monitorIdx)
 		float refreshRate, UINT32 monitorIdx)
 	{
 	{
-		void(RenderWindow::*funcPtr)(UINT32, UINT32, float, UINT32) = &RenderWindow::setFullscreen;
+		std::function<void(RenderWindowPtr, UINT32, UINT32, float, UINT32)> fullscreenFunc =
+			[](RenderWindowPtr renderWindow, UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
+		{
+			renderWindow->getCore()->setFullscreen(width, height, refreshRate, monitorIdx);
+		};
 
 
-		mCommandQueue->queue(std::bind(funcPtr, renderWindow.get(), width, height, refreshRate, monitorIdx));
+		mCommandQueue->queue(std::bind(fullscreenFunc, renderWindow, width, height, refreshRate, monitorIdx));
 	}
 	}
 
 
-	void CoreThreadAccessorBase::setFullscreen(RenderWindowPtr& renderWindow, const VideoMode& mode)
+	void CoreThreadAccessorBase::setFullscreen(const RenderWindowPtr& renderWindow, const VideoMode& mode)
 	{
 	{
-		void(RenderWindow::*funcPtr)(const VideoMode&) = &RenderWindow::setFullscreen;
+		std::function<void(RenderWindowPtr, const VideoMode&)> fullscreenFunc =
+			[](RenderWindowPtr renderWindow, const VideoMode& mode)
+		{
+			renderWindow->getCore()->setFullscreen(mode);
+		};
 
 
-		mCommandQueue->queue(std::bind(funcPtr, renderWindow.get(), std::cref(mode)));
+		mCommandQueue->queue(std::bind(fullscreenFunc, renderWindow, std::cref(mode)));
 	}
 	}
 
 
-	void CoreThreadAccessorBase::setWindowed(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height)
+	void CoreThreadAccessorBase::setWindowed(const RenderWindowPtr& renderWindow, UINT32 width, UINT32 height)
 	{
 	{
-		mCommandQueue->queue(std::bind(&RenderWindow::setWindowed, renderWindow.get(), width, height));
+		std::function<void(RenderWindowPtr, UINT32, UINT32)> windowedFunc =
+			[](RenderWindowPtr renderWindow, UINT32 width, UINT32 height)
+		{
+			renderWindow->getCore()->setWindowed(width, height);
+		};
+
+		mCommandQueue->queue(std::bind(windowedFunc, renderWindow, width, height));
+	}
+
+	void CoreThreadAccessorBase::setPriority(const RenderTargetPtr& renderTarget, UINT32 priority)
+	{
+		std::function<void(RenderTargetPtr, UINT32)> windowedFunc =
+			[](RenderTargetPtr renderTarget, UINT32 priority)
+		{
+			renderTarget->getCore()->setPriority(priority);
+		};
+
+		mCommandQueue->queue(std::bind(windowedFunc, renderTarget, priority));
 	}
 	}
 
 
 	AsyncOp CoreThreadAccessorBase::queueReturnCommand(std::function<void(AsyncOp&)> commandCallback)
 	AsyncOp CoreThreadAccessorBase::queueReturnCommand(std::function<void(AsyncOp&)> commandCallback)

+ 6 - 1
BansheeCore/Source/BsMesh.cpp

@@ -55,7 +55,7 @@ namespace BansheeEngine
 
 
 	Mesh::~Mesh()
 	Mesh::~Mesh()
 	{
 	{
-
+		
 	}
 	}
 
 
 	void Mesh::_writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
 	void Mesh::_writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
@@ -320,6 +320,11 @@ namespace BansheeEngine
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
+		mVertexData = nullptr;
+		mIndexBuffer = nullptr;
+		mVertexDesc = nullptr;
+		mTempInitialMeshData = nullptr;
+
 		MeshBase::destroy_internal();
 		MeshBase::destroy_internal();
 	}
 	}
 
 

+ 4 - 0
BansheeCore/Source/BsMeshHeap.cpp

@@ -61,6 +61,10 @@ namespace BansheeEngine
 		if(mCPUIndexData != nullptr)
 		if(mCPUIndexData != nullptr)
 			bs_free(mCPUIndexData);
 			bs_free(mCPUIndexData);
 
 
+		mVertexData = nullptr;
+		mIndexBuffer = nullptr;
+		mVertexDesc = nullptr;
+
 		CoreObject::destroy_internal();
 		CoreObject::destroy_internal();
 	}
 	}
 
 

+ 74 - 42
BansheeCore/Source/BsMultiRenderTexture.cpp

@@ -2,29 +2,22 @@
 #include "BsTexture.h"
 #include "BsTexture.h"
 #include "BsException.h"
 #include "BsException.h"
 #include "BsDebug.h"
 #include "BsDebug.h"
+#include "BsCoreThread.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	MultiRenderTexture::MultiRenderTexture()
+	MultiRenderTextureCore::MultiRenderTextureCore(MultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
+		:RenderTargetCore(parent, properties)
 	{
 	{
 		mColorSurfaces.resize(BS_MAX_MULTIPLE_RENDER_TARGETS);
 		mColorSurfaces.resize(BS_MAX_MULTIPLE_RENDER_TARGETS);
-	}
-
-	MultiRenderTexture::~MultiRenderTexture()
-	{
-
-	}
 
 
-	void MultiRenderTexture::initialize(const MULTI_RENDER_TEXTURE_DESC& desc)
-	{
-		bool colorSurfacePropertiesSet = false;
-		for(size_t i = 0; i < desc.colorSurfaces.size(); i++)
+		for (size_t i = 0; i < desc.colorSurfaces.size(); i++)
 		{
 		{
-			if(desc.colorSurfaces[i].texture != nullptr)
+			if (desc.colorSurfaces[i].texture != nullptr)
 			{
 			{
-				if(i >= BS_MAX_MULTIPLE_RENDER_TARGETS)
+				if (i >= BS_MAX_MULTIPLE_RENDER_TARGETS)
 				{
 				{
-					LOGWRN("Render texture index is larger than the maximum number of supported render targets. Index: " + toString((int)i) + 
+					LOGWRN("Render texture index is larger than the maximum number of supported render targets. Index: " + toString((int)i) +
 						". Max. number of render targets: " + toString(BS_MAX_MULTIPLE_RENDER_TARGETS));
 						". Max. number of render targets: " + toString(BS_MAX_MULTIPLE_RENDER_TARGETS));
 
 
 					continue;
 					continue;
@@ -32,58 +25,41 @@ namespace BansheeEngine
 
 
 				TexturePtr texture = desc.colorSurfaces[i].texture;
 				TexturePtr texture = desc.colorSurfaces[i].texture;
 
 
-				if(texture->getUsage() != TU_RENDERTARGET)
+				if (texture->getUsage() != TU_RENDERTARGET)
 					BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 					BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 
 
-				mColorSurfaces[i] = Texture::requestView(texture, desc.colorSurfaces[i].mipLevel, 1, 
+				mColorSurfaces[i] = Texture::requestView(texture, desc.colorSurfaces[i].mipLevel, 1,
 					desc.colorSurfaces[i].face, desc.colorSurfaces[i].numFaces, GVU_RENDERTARGET);
 					desc.colorSurfaces[i].face, desc.colorSurfaces[i].numFaces, GVU_RENDERTARGET);
-
-				if(!colorSurfacePropertiesSet)
-				{
-					mWidth = texture->getWidth();
-					mHeight = texture->getWidth();
-					mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texture->getFormat());
-					mActive = true;
-					mHwGamma = texture->isHardwareGammaEnabled();
-					mMultisampleCount = texture->getMultisampleCount();
-					mMultisampleHint = texture->getMultisampleHint();
-
-					colorSurfacePropertiesSet = true;
-				}
 			}
 			}
 		}
 		}
 
 
-		if(desc.depthStencilSurface.texture != nullptr)
+		if (desc.depthStencilSurface.texture != nullptr)
 		{
 		{
 			TexturePtr texture = desc.depthStencilSurface.texture;
 			TexturePtr texture = desc.depthStencilSurface.texture;
 
 
-			if(texture->getUsage() != TU_DEPTHSTENCIL)
+			if (texture->getUsage() != TU_DEPTHSTENCIL)
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 
 
-			mDepthStencilSurface = Texture::requestView(texture, desc.depthStencilSurface.mipLevel, 1, 
+			mDepthStencilSurface = Texture::requestView(texture, desc.depthStencilSurface.mipLevel, 1,
 				desc.depthStencilSurface.face, desc.depthStencilSurface.numFaces, GVU_DEPTHSTENCIL);
 				desc.depthStencilSurface.face, desc.depthStencilSurface.numFaces, GVU_DEPTHSTENCIL);
 		}
 		}
 
 
 		throwIfBuffersDontMatch();
 		throwIfBuffersDontMatch();
-
-		RenderTarget::initialize();
 	}
 	}
 
 
-	void MultiRenderTexture::destroy_internal()
+	MultiRenderTextureCore::~MultiRenderTextureCore()
 	{
 	{
-		for(auto iter = mColorSurfaces.begin(); iter != mColorSurfaces.end(); ++iter)
+		for (auto iter = mColorSurfaces.begin(); iter != mColorSurfaces.end(); ++iter)
 		{
 		{
-			if(*iter != nullptr)
+			if (*iter != nullptr)
 				Texture::releaseView(*iter);
 				Texture::releaseView(*iter);
 		}
 		}
 
 
-		if(mDepthStencilSurface != nullptr)
+		if (mDepthStencilSurface != nullptr)
 			Texture::releaseView(mDepthStencilSurface);
 			Texture::releaseView(mDepthStencilSurface);
-
-		RenderTarget::destroy_internal();
 	}
 	}
 
 
-	void MultiRenderTexture::throwIfBuffersDontMatch() const
+	void MultiRenderTextureCore::throwIfBuffersDontMatch() const
 	{
 	{
 		TextureViewPtr firstSurfaceDesc = nullptr;
 		TextureViewPtr firstSurfaceDesc = nullptr;
 		for(size_t i = 0; i < mColorSurfaces.size(); i++)
 		for(size_t i = 0; i < mColorSurfaces.size(); i++)
@@ -146,8 +122,64 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void MultiRenderTexture::copyToMemory(PixelData &dst, FrameBuffer buffer)
+	void MultiRenderTextureCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
 	{
 	{
 		throw std::exception("The method or operation is not implemented.");
 		throw std::exception("The method or operation is not implemented.");
 	}
 	}
+
+	MultiRenderTexture* MultiRenderTextureCore::getNonCore() const
+	{
+		return static_cast<MultiRenderTexture*>(mParent);
+	}
+
+	void MultiRenderTexture::initialize(const MULTI_RENDER_TEXTURE_DESC& desc)
+	{
+		mDesc = desc;
+
+		mProperties = createProperties();
+		MultiRenderTextureProperties* properties = static_cast<MultiRenderTextureProperties*>(mProperties);
+		for (size_t i = 0; i < desc.colorSurfaces.size(); i++)
+		{
+			TexturePtr texture = desc.colorSurfaces[i].texture;
+
+			if (texture != nullptr)
+			{
+				properties->mWidth = texture->getWidth();
+				properties->mHeight = texture->getWidth();
+				properties->mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texture->getFormat());
+				properties->mActive = true;
+				properties->mHwGamma = texture->isHardwareGammaEnabled();
+				properties->mMultisampleCount = texture->getMultisampleCount();
+				properties->mMultisampleHint = texture->getMultisampleHint();
+				properties->mIsWindow = false;
+				properties->mRequiresTextureFlipping = requiresTextureFlipping();
+
+				break;
+			}
+		}
+
+		RenderTarget::initialize();
+	}
+
+	const MultiRenderTextureProperties& MultiRenderTexture::getProperties() const
+	{
+		THROW_IF_CORE_THREAD;
+
+		return static_cast<const MultiRenderTextureProperties&>(RenderTarget::getProperties());
+	}
+
+	MultiRenderTextureCore* MultiRenderTexture::getCore() const
+	{
+		return static_cast<MultiRenderTextureCore*>(mCore);
+	}
+
+	RenderTargetCore* MultiRenderTexture::createCore()
+	{
+		MultiRenderTextureProperties* coreProperties = bs_new<MultiRenderTextureProperties>();
+		MultiRenderTextureProperties* myProperties = static_cast<MultiRenderTextureProperties*>(mProperties);
+
+		*coreProperties = *myProperties;
+
+		return createCore(coreProperties, mDesc);
+	}
 }
 }

+ 1 - 1
BansheeCore/Source/BsRenderSystem.cpp

@@ -271,7 +271,7 @@ namespace BansheeEngine {
 
 
 		if (target->isInitialized())
 		if (target->isInitialized())
 		{
 		{
-			target->swapBuffers();
+			target->getCore()->swapBuffers();
 
 
 			BS_INC_RENDER_STAT(NumPresents);
 			BS_INC_RENDER_STAT(NumPresents);
 		}
 		}

+ 60 - 5
BansheeCore/Source/BsRenderTarget.cpp

@@ -2,21 +2,76 @@
 #include "BsViewport.h"
 #include "BsViewport.h"
 #include "BsException.h"
 #include "BsException.h"
 #include "BsRenderSystem.h"
 #include "BsRenderSystem.h"
+#include "BsCoreThread.h"
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
+	RenderTargetCore::RenderTargetCore(RenderTarget* parent, RenderTargetProperties* properties)
+		:mProperties(properties), mParent(parent)
+	{
+
+	}
+
+	RenderTargetCore::~RenderTargetCore()
+	{
+		bs_delete(mProperties);
+	}
+
+	void RenderTargetCore::getCustomAttribute(const String& name, void* pData) const
+	{
+		BS_EXCEPT(InvalidParametersException, "Attribute not found.");
+	}
+
+	const RenderTargetProperties& RenderTargetCore::getProperties() const 
+	{ 
+		THROW_IF_NOT_CORE_THREAD;
+
+		return *mProperties; 
+	}
+
     RenderTarget::RenderTarget()
     RenderTarget::RenderTarget()
-		:mActive(true), mHwGamma(false), mVSync(false), mMultisampleCount(0),
-		mWidth(0), mHeight(0), mColorDepth(0), mPriority(0)
+		:mCore(nullptr), mProperties(nullptr)
     {
     {
     }
     }
 
 
     RenderTarget::~RenderTarget()
     RenderTarget::~RenderTarget()
     {
     {
+		bs_delete(mProperties);
     }
     }
 
 
+	const RenderTargetProperties& RenderTarget::getProperties() const
+	{
+		THROW_IF_CORE_THREAD;
+
+		// DEBUG ONLY
+		if (mCore != nullptr)
+			*mProperties = *mCore->mProperties;
+
+		return *mProperties;
+	}
+
+	RenderTargetCore* RenderTarget::getCore() const
+	{
+		return mCore;
+	}
+
+	void RenderTarget::initialize_internal()
+	{
+		CoreObject::initialize_internal();
+
+		mCore = createCore();
+	}
+
+	void RenderTarget::destroy_internal()
+	{
+		bs_delete(mCore);
+		mCore = nullptr;
+
+		CoreObject::destroy_internal();
+	}
+
 	void RenderTarget::getCustomAttribute(const String& name, void* pData) const
 	void RenderTarget::getCustomAttribute(const String& name, void* pData) const
-    {
-        BS_EXCEPT(InvalidParametersException, "Attribute not found.");
-    }
+	{
+		BS_EXCEPT(InvalidParametersException, "Attribute not found.");
+	}
 }        
 }        

+ 100 - 67
BansheeCore/Source/BsRenderTexture.cpp

@@ -4,69 +4,34 @@
 #include "BsTexture.h"
 #include "BsTexture.h"
 #include "BsTextureManager.h"
 #include "BsTextureManager.h"
 #include "BsResources.h"
 #include "BsResources.h"
+#include "BsCoreThread.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	RenderTexture::RenderTexture()
-		:mColorSurface(nullptr), mDepthStencilSurface(nullptr)
+	RenderTextureCore::RenderTextureCore(RenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+		const RENDER_SURFACE_DESC& depthStencilSurfaceDesc)
+		:RenderTargetCore(parent, properties), mColorSurface(nullptr), mDepthStencilSurface(nullptr)
 	{
 	{
-
-	}
-
-	RenderTexture::~RenderTexture()
-	{
-
-	}
-
-	RenderTexturePtr RenderTexture::create(TextureType textureType, UINT32 width, UINT32 height, 
-		PixelFormat format, bool hwGamma, UINT32 multisampleCount, const String& multisampleHint, 
-		bool createDepth, PixelFormat depthStencilFormat)
-	{
-		return TextureManager::instance().createRenderTexture(textureType, width, height, format, hwGamma, 
-			multisampleCount, multisampleHint, createDepth, depthStencilFormat);
-	}
-
-	void RenderTexture::destroy_internal()
-	{
-		if(mColorSurface != nullptr)
-			Texture::releaseView(mColorSurface);
-
-		if(mDepthStencilSurface != nullptr)
-			Texture::releaseView(mDepthStencilSurface);
-
-		RenderTarget::destroy_internal();
-	}
-
-	void RenderTexture::initialize(const RENDER_TEXTURE_DESC& desc)
-	{
-		if(desc.colorSurface.texture != nullptr)
+		if (colorSurfaceDesc.texture != nullptr)
 		{
 		{
-			TexturePtr texture = desc.colorSurface.texture;
+			TexturePtr texture = colorSurfaceDesc.texture;
 
 
-			if(texture->getUsage() != TU_RENDERTARGET)
+			if (texture->getUsage() != TU_RENDERTARGET)
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 
 
-			mColorSurface = Texture::requestView(texture, desc.colorSurface.mipLevel, 1, 
-				desc.colorSurface.face, desc.colorSurface.numFaces, GVU_RENDERTARGET);
-
-			mWidth = texture->getWidth();
-			mHeight = texture->getHeight();
-			mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texture->getFormat());
-			mActive = true;
-			mHwGamma = texture->isHardwareGammaEnabled();
-			mMultisampleCount = texture->getMultisampleCount();
-			mMultisampleHint = texture->getMultisampleHint();
+			mColorSurface = Texture::requestView(texture, colorSurfaceDesc.mipLevel, 1,
+				colorSurfaceDesc.face, colorSurfaceDesc.numFaces, GVU_RENDERTARGET);
 		}
 		}
 
 
-		if(desc.depthStencilSurface.texture != nullptr)
+		if (depthStencilSurfaceDesc.texture != nullptr)
 		{
 		{
-			TexturePtr texture = desc.depthStencilSurface.texture;
+			TexturePtr texture = depthStencilSurfaceDesc.texture;
 
 
-			if(texture->getUsage() != TU_DEPTHSTENCIL)
+			if (texture->getUsage() != TU_DEPTHSTENCIL)
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 
 
-			mDepthStencilSurface = Texture::requestView(texture, desc.depthStencilSurface.mipLevel, 1, 
-				desc.depthStencilSurface.face, desc.depthStencilSurface.numFaces, GVU_DEPTHSTENCIL);
+			mDepthStencilSurface = Texture::requestView(texture, depthStencilSurfaceDesc.mipLevel, 1,
+				depthStencilSurfaceDesc.face, depthStencilSurfaceDesc.numFaces, GVU_DEPTHSTENCIL);
 		}
 		}
 
 
 		throwIfBuffersDontMatch();
 		throwIfBuffersDontMatch();
@@ -74,39 +39,38 @@ namespace BansheeEngine
 		assert(mColorSurface != nullptr);
 		assert(mColorSurface != nullptr);
 		assert(mColorSurface->getTexture() != nullptr);
 		assert(mColorSurface->getTexture() != nullptr);
 
 
-		if(mColorSurface->getTexture()->getTextureType() != TEX_TYPE_2D)
+		if (mColorSurface->getTexture()->getTextureType() != TEX_TYPE_2D)
 			BS_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
 			BS_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
 
 
-		if((mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) > mColorSurface->getTexture()->getNumFaces())
+		if ((mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) > mColorSurface->getTexture()->getNumFaces())
 		{
 		{
-			BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " + 
-				toString(mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) + 
+			BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " +
+				toString(mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) +
 				". Max num faces: " + toString(mColorSurface->getTexture()->getNumFaces()));
 				". Max num faces: " + toString(mColorSurface->getTexture()->getNumFaces()));
 		}
 		}
 
 
-		if(mColorSurface->getMostDetailedMip() > mColorSurface->getTexture()->getNumMipmaps())
+		if (mColorSurface->getMostDetailedMip() > mColorSurface->getTexture()->getNumMipmaps())
 		{
 		{
-			BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " + 
+			BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " +
 				toString(mColorSurface->getMostDetailedMip()) + ". Max num mipmaps: " + toString(mColorSurface->getTexture()->getNumMipmaps()));
 				toString(mColorSurface->getMostDetailedMip()) + ". Max num mipmaps: " + toString(mColorSurface->getTexture()->getNumMipmaps()));
 		}
 		}
+	}
 
 
-		RenderTarget::initialize();
-
-		// Create non-persistent resource handles for the used textures (we only need them because a lot of the code accepts only handles,
-		// since they're non persistent they don't really have any benefit over shared pointers)
-		if(mColorSurface != nullptr)
-			mBindableColorTex = gResources()._createResourceHandle(mColorSurface->getTexture());
+	RenderTextureCore::~RenderTextureCore()
+	{
+		if (mColorSurface != nullptr)
+			Texture::releaseView(mColorSurface);
 
 
-		if(mDepthStencilSurface != nullptr)
-			mBindableDepthStencilTex = gResources()._createResourceHandle(mDepthStencilSurface->getTexture());
+		if (mDepthStencilSurface != nullptr)
+			Texture::releaseView(mDepthStencilSurface);
 	}
 	}
 
 
-	void RenderTexture::throwIfBuffersDontMatch() const
+	void RenderTextureCore::throwIfBuffersDontMatch() const
 	{
 	{
-		if(mColorSurface == nullptr || mDepthStencilSurface == nullptr)
+		if (mColorSurface == nullptr || mDepthStencilSurface == nullptr)
 			return;
 			return;
 
 
-		if(mColorSurface->getTexture()->getWidth() != mDepthStencilSurface->getTexture()->getWidth() ||
+		if (mColorSurface->getTexture()->getWidth() != mDepthStencilSurface->getTexture()->getWidth() ||
 			mColorSurface->getTexture()->getHeight() != mDepthStencilSurface->getTexture()->getHeight() ||
 			mColorSurface->getTexture()->getHeight() != mDepthStencilSurface->getTexture()->getHeight() ||
 			mColorSurface->getTexture()->getMultisampleCount() != mDepthStencilSurface->getTexture()->getMultisampleCount() ||
 			mColorSurface->getTexture()->getMultisampleCount() != mDepthStencilSurface->getTexture()->getMultisampleCount() ||
 			mColorSurface->getTexture()->getMultisampleHint() != mDepthStencilSurface->getTexture()->getMultisampleHint())
 			mColorSurface->getTexture()->getMultisampleHint() != mDepthStencilSurface->getTexture()->getMultisampleHint())
@@ -120,8 +84,77 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void RenderTexture::copyToMemory(PixelData &dst, FrameBuffer buffer)
+	void RenderTextureCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
 	{
 	{
 		throw std::exception("The method or operation is not implemented.");
 		throw std::exception("The method or operation is not implemented.");
 	}
 	}
+
+	RenderTexture* RenderTextureCore::getNonCore() const
+	{
+		return static_cast<RenderTexture*>(mParent);
+	}
+
+	RenderTexturePtr RenderTexture::create(TextureType textureType, UINT32 width, UINT32 height, 
+		PixelFormat format, bool hwGamma, UINT32 multisampleCount, const String& multisampleHint, 
+		bool createDepth, PixelFormat depthStencilFormat)
+	{
+		return TextureManager::instance().createRenderTexture(textureType, width, height, format, hwGamma, 
+			multisampleCount, multisampleHint, createDepth, depthStencilFormat);
+	}
+
+	const RenderTextureProperties& RenderTexture::getProperties() const 
+	{ 
+		THROW_IF_CORE_THREAD;
+
+		return static_cast<const RenderTextureProperties&>(RenderTarget::getProperties()); 
+	}
+
+	RenderTextureCore* RenderTexture::getCore() const 
+	{ 
+		return static_cast<RenderTextureCore*>(mCore); 
+	}
+
+	void RenderTexture::initialize(const RENDER_TEXTURE_DESC& desc)
+	{
+		mColorSurfaceDesc = desc.colorSurface;
+		mDepthStencilSurfaceDesc = desc.depthStencilSurface;
+
+		TexturePtr texture = desc.colorSurface.texture;
+
+		mProperties = createProperties();
+		RenderTextureProperties* properties = static_cast<RenderTextureProperties*>(mProperties);
+		if (texture != nullptr)
+		{
+			properties->mWidth = texture->getWidth();
+			properties->mHeight = texture->getHeight();
+			properties->mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texture->getFormat());
+			properties->mHwGamma = texture->isHardwareGammaEnabled();
+			properties->mMultisampleCount = texture->getMultisampleCount();
+			properties->mMultisampleHint = texture->getMultisampleHint();
+		}
+
+		properties->mActive = true;
+		properties->mIsWindow = false;
+		properties->mRequiresTextureFlipping = requiresTextureFlipping();
+
+		// Create non-persistent resource handles for the used textures (we only need them because a lot of the code accepts only handles,
+		// since they're non persistent they don't really have any benefit over shared pointers)
+		if (desc.colorSurface.texture != nullptr)
+			mBindableColorTex = gResources()._createResourceHandle(desc.colorSurface.texture);
+
+		if (desc.depthStencilSurface.texture != nullptr)
+			mBindableDepthStencilTex = gResources()._createResourceHandle(desc.depthStencilSurface.texture);
+
+		RenderTarget::initialize();
+	}
+
+	RenderTargetCore* RenderTexture::createCore()
+	{
+		RenderTextureProperties* coreProperties = bs_new<RenderTextureProperties>();
+		RenderTextureProperties* myProperties = static_cast<RenderTextureProperties*>(mProperties);
+
+		*coreProperties = *myProperties;
+
+		return createCore(coreProperties, mColorSurfaceDesc, mDepthStencilSurfaceDesc);
+	}
 }
 }

+ 67 - 27
BansheeCore/Source/BsRenderWindow.cpp

@@ -6,52 +6,70 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-    RenderWindow::RenderWindow(const RENDER_WINDOW_DESC& desc)
-		: RenderTarget(), mIsFullScreen(false), mDesc(desc), mHasFocus(false), mLeft(0), mTop(0), mHidden(false)
-    {
-		mWidth = desc.videoMode.getWidth();
-		mHeight = desc.videoMode.getHeight();
-		mHwGamma = desc.gamma;
-		mVSync = desc.vsync;
-		mMultisampleCount = desc.multisampleCount;
-		mLeft = desc.left; 
-		mTop = desc.top;
-		mIsFullScreen = desc.fullscreen;
-		mHidden = desc.hidden;
-    }
-
-	RenderWindow::~RenderWindow() 
+	RenderWindowCore::RenderWindowCore(RenderWindow* parent, RenderWindowProperties* properties)
+		:RenderTargetCore(parent, properties)
 	{
 	{
-		
+
 	}
 	}
 
 
-	void RenderWindow::setHidden(bool hidden)
+	void RenderWindowCore::setHidden(bool hidden)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 	}
 	}
 
 
-    bool RenderWindow::isFullScreen(void) const
-    {
-        return mIsFullScreen;
-    }
-
-	void RenderWindow::_windowMovedOrResized()
+	void RenderWindowCore::_windowMovedOrResized()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 	}
 	}
 
 
-	void RenderWindow::_windowFocusReceived()
+	void RenderWindowCore::_windowFocusReceived()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		mHasFocus = true;
+		RenderWindowProperties* properties = static_cast<RenderWindowProperties*>(mProperties);
+		properties->mHasFocus = true;
+
+		markCoreDirty();
 	}
 	}
 
 
-	void RenderWindow::_windowFocusLost()
+	void RenderWindowCore::_windowFocusLost()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		mHasFocus = false;
+		RenderWindowProperties* properties = static_cast<RenderWindowProperties*>(mProperties);
+		properties->mHasFocus = false;
+
+		markCoreDirty();
+	}
+
+	RenderWindow* RenderWindowCore::getNonCore() const 
+	{ 
+		return static_cast<RenderWindow*>(mParent); 
+	}
+
+	void RenderWindow::initialize(const RENDER_WINDOW_DESC& desc)
+	{
+		mDesc = desc;
+
+		mProperties = createProperties();
+		RenderWindowProperties* properties = static_cast<RenderWindowProperties*>(mProperties);
+
+		properties->mWidth = desc.videoMode.getWidth();
+		properties->mHeight = desc.videoMode.getHeight();
+		properties->mHwGamma = desc.gamma;
+		properties->mVSync = desc.vsync;
+		properties->mVSyncInterval = desc.vsyncInterval;
+		properties->mMultisampleCount = desc.multisampleCount;
+		properties->mMultisampleHint = desc.multisampleHint;
+		properties->mLeft = desc.left;
+		properties->mTop = desc.top;
+		properties->mIsFullScreen = desc.fullscreen;
+		properties->mHidden = desc.hidden;
+		properties->mIsModal = desc.modal;
+		properties->mIsWindow = true;
+		properties->mRequiresTextureFlipping = requiresTextureFlipping();
+
+		RenderTarget::initialize();
 	}
 	}
 
 
 	void RenderWindow::destroy()
 	void RenderWindow::destroy()
@@ -63,6 +81,28 @@ namespace BansheeEngine
 		RenderTarget::destroy();
 		RenderTarget::destroy();
 	}
 	}
 
 
+	const RenderWindowProperties& RenderWindow::getProperties() const
+	{
+		THROW_IF_CORE_THREAD;
+
+		return static_cast<const RenderWindowProperties&>(RenderTarget::getProperties());
+	}
+
+	RenderWindowCore* RenderWindow::getCore() const
+	{
+		return static_cast<RenderWindowCore*>(mCore);
+	}
+
+	RenderTargetCore* RenderWindow::createCore()
+	{
+		RenderWindowProperties* coreProperties = bs_new<RenderWindowProperties>();
+		RenderWindowProperties* myProperties = static_cast<RenderWindowProperties*>(mProperties);
+
+		*coreProperties = *myProperties;
+
+		return createCore(coreProperties, mDesc);
+	}
+
 	RenderWindowPtr RenderWindow::create(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow)
 	RenderWindowPtr RenderWindow::create(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow)
 	{
 	{
 		return RenderWindowManager::instance().create(desc, parentWindow);
 		return RenderWindowManager::instance().create(desc, parentWindow);

+ 8 - 8
BansheeCore/Source/BsRenderWindowManager.cpp

@@ -17,7 +17,7 @@ namespace BansheeEngine
 	{
 	{
 		RenderWindowPtr renderWindow = createImpl(desc, parentWindow);
 		RenderWindowPtr renderWindow = createImpl(desc, parentWindow);
 		renderWindow->_setThisPtr(renderWindow);
 		renderWindow->_setThisPtr(renderWindow);
-		renderWindow->initialize();
+		renderWindow->initialize(desc);
 
 
 		{
 		{
 			BS_LOCK_MUTEX(mWindowMutex);
 			BS_LOCK_MUTEX(mWindowMutex);
@@ -47,15 +47,15 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void RenderWindowManager::windowFocusReceived(RenderWindow* window)
+	void RenderWindowManager::windowFocusReceived(RenderWindowCore* window)
 	{
 	{
 		window->_windowFocusReceived();
 		window->_windowFocusReceived();
 
 
 		BS_LOCK_MUTEX(mWindowMutex);
 		BS_LOCK_MUTEX(mWindowMutex);
-		mNewWindowInFocus = window;
+		mNewWindowInFocus = window->getNonCore();
 	}
 	}
 
 
-	void RenderWindowManager::windowFocusLost(RenderWindow* window)
+	void RenderWindowManager::windowFocusLost(RenderWindowCore* window)
 	{
 	{
 		window->_windowFocusLost();
 		window->_windowFocusLost();
 
 
@@ -63,13 +63,13 @@ namespace BansheeEngine
 		mNewWindowInFocus = nullptr;
 		mNewWindowInFocus = nullptr;
 	}
 	}
 
 
-	void RenderWindowManager::windowMovedOrResized(RenderWindow* window)
+	void RenderWindowManager::windowMovedOrResized(RenderWindowCore* window)
 	{
 	{
 		bool isValidWindow = false;
 		bool isValidWindow = false;
 		{
 		{
 			BS_LOCK_MUTEX(mWindowMutex);
 			BS_LOCK_MUTEX(mWindowMutex);
 
 
-			isValidWindow = std::find(begin(mCreatedWindows), end(mCreatedWindows), window) != mCreatedWindows.end();
+			isValidWindow = std::find(begin(mCreatedWindows), end(mCreatedWindows), window->getNonCore()) != mCreatedWindows.end();
 		}
 		}
 
 
 		if(!isValidWindow)
 		if(!isValidWindow)
@@ -79,10 +79,10 @@ namespace BansheeEngine
 
 
 		BS_LOCK_MUTEX(mWindowMutex);
 		BS_LOCK_MUTEX(mWindowMutex);
 
 
-		auto iterFind = std::find(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows), window);
+		auto iterFind = std::find(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows), window->getNonCore());
 
 
 		if(iterFind == end(mMovedOrResizedWindows))
 		if(iterFind == end(mMovedOrResizedWindows))
-			mMovedOrResizedWindows.push_back(window);
+			mMovedOrResizedWindows.push_back(window->getNonCore());
 	}
 	}
 
 
 	void RenderWindowManager::_update()
 	void RenderWindowManager::_update()

+ 4 - 0
BansheeCore/Source/BsTexture.cpp

@@ -222,6 +222,8 @@ namespace BansheeEngine
 
 
 	TextureViewPtr Texture::requestView(TexturePtr texture, UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage)
 	TextureViewPtr Texture::requestView(TexturePtr texture, UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage)
 	{
 	{
+		THROW_IF_NOT_CORE_THREAD;
+
 		assert(texture != nullptr);
 		assert(texture != nullptr);
 
 
 		TEXTURE_VIEW_DESC key;
 		TEXTURE_VIEW_DESC key;
@@ -247,6 +249,8 @@ namespace BansheeEngine
 
 
 	void Texture::releaseView(TextureViewPtr view)
 	void Texture::releaseView(TextureViewPtr view)
 	{
 	{
+		THROW_IF_NOT_CORE_THREAD;
+
 		assert(view != nullptr);
 		assert(view != nullptr);
 
 
 		TexturePtr texture = view->getTexture();
 		TexturePtr texture = view->getTexture();

+ 6 - 6
BansheeCore/Source/BsViewport.cpp

@@ -39,8 +39,8 @@ namespace BansheeEngine
 
 
 	RectI Viewport::getArea() const
 	RectI Viewport::getArea() const
 	{
 	{
-		float width = (float)mTarget->getWidth();
-		float height = (float)mTarget->getHeight();
+		float width = (float)mTarget->getProperties().getWidth();
+		float height = (float)mTarget->getProperties().getHeight();
 		
 		
 		RectI area;
 		RectI area;
 		area.x = (int)(mNormArea.x * width);
 		area.x = (int)(mNormArea.x * width);
@@ -71,22 +71,22 @@ namespace BansheeEngine
 
 
 	INT32 Viewport::getX() const 
 	INT32 Viewport::getX() const 
 	{ 
 	{ 
-		return (INT32)(mNormArea.x * mTarget->getWidth());
+		return (INT32)(mNormArea.x * mTarget->getProperties().getWidth());
 	}
 	}
 
 
 	INT32 Viewport::getY() const 
 	INT32 Viewport::getY() const 
 	{ 
 	{ 
-		return (INT32)(mNormArea.y * mTarget->getHeight());
+		return (INT32)(mNormArea.y * mTarget->getProperties().getHeight());
 	}
 	}
 
 
 	INT32 Viewport::getWidth() const 
 	INT32 Viewport::getWidth() const 
 	{ 
 	{ 
-		return (INT32)(mNormArea.width * mTarget->getWidth());
+		return (INT32)(mNormArea.width * mTarget->getProperties().getWidth());
 	}
 	}
 
 
 	INT32 Viewport::getHeight() const 
 	INT32 Viewport::getHeight() const 
 	{ 
 	{ 
-		return (INT32)(mNormArea.height * mTarget->getHeight());
+		return (INT32)(mNormArea.height * mTarget->getProperties().getHeight());
 	}
 	}
 
 
 	Viewport Viewport::clone()
 	Viewport Viewport::clone()

+ 14 - 14
BansheeCore/Source/Win32/BsPlatformImpl.cpp

@@ -19,16 +19,16 @@ namespace BansheeEngine
 	Event<void(float)> Platform::onMouseWheelScrolled;
 	Event<void(float)> Platform::onMouseWheelScrolled;
 	Event<void(UINT32)> Platform::onCharInput;
 	Event<void(UINT32)> Platform::onCharInput;
 
 
-	Event<void(RenderWindow*)> Platform::onWindowFocusReceived;
-	Event<void(RenderWindow*)> Platform::onWindowFocusLost;
-	Event<void(RenderWindow*)> Platform::onWindowMovedOrResized;
+	Event<void(RenderWindowCore*)> Platform::onWindowFocusReceived;
+	Event<void(RenderWindowCore*)> Platform::onWindowFocusLost;
+	Event<void(RenderWindowCore*)> Platform::onWindowMovedOrResized;
 	Event<void()> Platform::onMouseCaptureChanged;
 	Event<void()> Platform::onMouseCaptureChanged;
 
 
-	Map<const RenderWindow*, WindowNonClientAreaData> Platform::mNonClientAreas;
+	Map<const RenderWindowCore*, WindowNonClientAreaData> Platform::mNonClientAreas;
 	bool Platform::mIsTrackingMouse = false;
 	bool Platform::mIsTrackingMouse = false;
-	Vector<RenderWindow*> Platform::mMouseLeftWindows;
+	Vector<RenderWindowCore*> Platform::mMouseLeftWindows;
 
 
-	Stack<RenderWindow*> Platform::mModalWindowStack;
+	Stack<RenderWindowCore*> Platform::mModalWindowStack;
 
 
 	NativeDropTargetData Platform::mDropTargets;
 	NativeDropTargetData Platform::mDropTargets;
 
 
@@ -263,21 +263,21 @@ namespace BansheeEngine
 	{
 	{
 		BS_LOCK_MUTEX(mSync);
 		BS_LOCK_MUTEX(mSync);
 
 
-		mNonClientAreas[&window].moveAreas = nonClientAreas;
+		mNonClientAreas[window.getCore()].moveAreas = nonClientAreas;
 	}
 	}
 
 
 	void Platform::setResizeNonClientAreas(const RenderWindow& window, const Vector<NonClientResizeArea>& nonClientAreas)
 	void Platform::setResizeNonClientAreas(const RenderWindow& window, const Vector<NonClientResizeArea>& nonClientAreas)
 	{
 	{
 		BS_LOCK_MUTEX(mSync);
 		BS_LOCK_MUTEX(mSync);
 
 
-		mNonClientAreas[&window].resizeAreas = nonClientAreas;
+		mNonClientAreas[window.getCore()].resizeAreas = nonClientAreas;
 	}
 	}
 
 
 	void Platform::resetNonClientAreas(const RenderWindow& window)
 	void Platform::resetNonClientAreas(const RenderWindow& window)
 	{
 	{
 		BS_LOCK_MUTEX(mSync);
 		BS_LOCK_MUTEX(mSync);
 
 
-		auto iterFind = mNonClientAreas.find(&window);
+		auto iterFind = mNonClientAreas.find(window.getCore());
 
 
 		if(iterFind != end(mNonClientAreas))
 		if(iterFind != end(mNonClientAreas))
 			mNonClientAreas.erase(iterFind);
 			mNonClientAreas.erase(iterFind);
@@ -453,7 +453,7 @@ namespace BansheeEngine
 
 
 	void Platform::_update()
 	void Platform::_update()
 	{
 	{
-		Vector<RenderWindow*> windowsCopy;
+		Vector<RenderWindowCore*> windowsCopy;
 		{
 		{
 			BS_LOCK_MUTEX(mSync);
 			BS_LOCK_MUTEX(mSync);
 
 
@@ -464,7 +464,7 @@ namespace BansheeEngine
 		for(auto& window : windowsCopy)
 		for(auto& window : windowsCopy)
 		{
 		{
 			if(!onMouseLeftWindow.empty())
 			if(!onMouseLeftWindow.empty())
-				onMouseLeftWindow(window);
+				onMouseLeftWindow(window->getNonCore());
 		}
 		}
 
 
 		for(auto& dropTarget : mDropTargets.data->dropTargetsPerWindow)
 		for(auto& dropTarget : mDropTargets.data->dropTargetsPerWindow)
@@ -525,19 +525,19 @@ namespace BansheeEngine
 		mRequiresShutDown = true;
 		mRequiresShutDown = true;
 	}
 	}
 
 
-	void Platform::windowFocusReceived(RenderWindow* window)
+	void Platform::windowFocusReceived(RenderWindowCore* window)
 	{
 	{
 		if(!onWindowFocusReceived.empty())
 		if(!onWindowFocusReceived.empty())
 			onWindowFocusReceived(window);
 			onWindowFocusReceived(window);
 	}
 	}
 
 
-	void Platform::windowFocusLost(RenderWindow* window)
+	void Platform::windowFocusLost(RenderWindowCore* window)
 	{
 	{
 		if(!onWindowFocusLost.empty())
 		if(!onWindowFocusLost.empty())
 			onWindowFocusLost(window);
 			onWindowFocusLost(window);
 	}
 	}
 	
 	
-	void Platform::windowMovedOrResized(RenderWindow* window)
+	void Platform::windowMovedOrResized(RenderWindowCore* window)
 	{
 	{
 		if(!onWindowMovedOrResized.empty())
 		if(!onWindowMovedOrResized.empty())
 			onWindowMovedOrResized(window);
 			onWindowMovedOrResized(window);

+ 10 - 10
BansheeCore/Source/Win32/BsPlatformWndProc.cpp

@@ -16,12 +16,12 @@ namespace BansheeEngine
 		{	// Store pointer to Win32Window in user data area
 		{	// Store pointer to Win32Window in user data area
 			SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
 			SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
 
 
-			RenderWindow* newWindow = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-			if(newWindow->isModal())
+			RenderWindowCore* newWindow = (RenderWindowCore*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+			if(newWindow->getProperties().isModal())
 			{
 			{
 				if(!mModalWindowStack.empty())
 				if(!mModalWindowStack.empty())
 				{
 				{
-					RenderWindow* curModalWindow = mModalWindowStack.top();
+					RenderWindowCore* curModalWindow = mModalWindowStack.top();
 
 
 					HWND curHwnd;
 					HWND curHwnd;
 					curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
 					curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
@@ -32,7 +32,7 @@ namespace BansheeEngine
 					Vector<RenderWindow*> renderWindows = RenderWindowManager::instance().getRenderWindows();
 					Vector<RenderWindow*> renderWindows = RenderWindowManager::instance().getRenderWindows();
 					for(auto& renderWindow : renderWindows)
 					for(auto& renderWindow : renderWindows)
 					{
 					{
-						if(renderWindow == newWindow)
+						if(renderWindow->getCore() == newWindow)
 							continue;
 							continue;
 
 
 						HWND curHwnd;
 						HWND curHwnd;
@@ -49,7 +49,7 @@ namespace BansheeEngine
 
 
 		// look up window instance
 		// look up window instance
 		// note: it is possible to get a WM_SIZE before WM_CREATE
 		// note: it is possible to get a WM_SIZE before WM_CREATE
-		RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+		RenderWindowCore* win = (RenderWindowCore*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
 		if (!win)
 		if (!win)
 			return DefWindowProc(hWnd, uMsg, wParam, lParam);
 			return DefWindowProc(hWnd, uMsg, wParam, lParam);
 
 
@@ -74,11 +74,11 @@ namespace BansheeEngine
 					}
 					}
 					else // Possibly some other window was closed somehow, see if it was modal and remove from stack if it is
 					else // Possibly some other window was closed somehow, see if it was modal and remove from stack if it is
 					{
 					{
-						Stack<RenderWindow*> newStack;
+						Stack<RenderWindowCore*> newStack;
 
 
 						while(!mModalWindowStack.empty())
 						while(!mModalWindowStack.empty())
 						{
 						{
-							RenderWindow* curWindow = mModalWindowStack.top();
+							RenderWindowCore* curWindow = mModalWindowStack.top();
 							mModalWindowStack.pop();
 							mModalWindowStack.pop();
 
 
 							if(curWindow == win)
 							if(curWindow == win)
@@ -92,7 +92,7 @@ namespace BansheeEngine
 
 
 					if(!mModalWindowStack.empty()) // Enable next modal window
 					if(!mModalWindowStack.empty()) // Enable next modal window
 					{
 					{
-						RenderWindow* curModalWindow = mModalWindowStack.top();
+						RenderWindowCore* curModalWindow = mModalWindowStack.top();
 
 
 						HWND curHwnd;
 						HWND curHwnd;
 						curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
 						curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
@@ -117,14 +117,14 @@ namespace BansheeEngine
 			}
 			}
 		case WM_SETFOCUS:
 		case WM_SETFOCUS:
 			{
 			{
-				if(!win->hasFocus())
+				if (!win->getProperties().hasFocus())
 					windowFocusReceived(win);
 					windowFocusReceived(win);
 
 
 				break;
 				break;
 			}
 			}
 		case WM_KILLFOCUS:
 		case WM_KILLFOCUS:
 			{
 			{
-				if(win->hasFocus())
+				if (win->getProperties().hasFocus())
 					windowFocusLost(win);
 					windowFocusLost(win);
 
 
 				break;
 				break;

+ 33 - 9
BansheeD3D11RenderSystem/Include/BsD3D11MultiRenderTexture.h

@@ -5,26 +5,50 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	class D3D11MultiRenderTexture;
+
+	/**
+	 * @brief	DirectX 11 implementation of a render texture with multiple color surfaces.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_D3D11_EXPORT D3D11MultiRenderTextureCore : public MultiRenderTextureCore
+	{
+	public:
+		D3D11MultiRenderTextureCore(D3D11MultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc);
+		virtual ~D3D11MultiRenderTextureCore();
+		
+		/**
+		 * @copydoc	MultiRenderTextureCore::getCustomAttribute
+		 */
+		void getCustomAttribute(const String& name, void* pData) const;
+	protected:
+		friend class D3D11MultiRenderTexture;
+	};
+
 	/**
 	/**
 	 * @brief	DirectX 11 implementation of a render texture with multiple color surfaces.
 	 * @brief	DirectX 11 implementation of a render texture with multiple color surfaces.
+	 *
+	 * @note	Sim thread only.
 	 */
 	 */
 	class BS_D3D11_EXPORT D3D11MultiRenderTexture : public MultiRenderTexture
 	class BS_D3D11_EXPORT D3D11MultiRenderTexture : public MultiRenderTexture
 	{
 	{
 	public:
 	public:
-		virtual ~D3D11MultiRenderTexture();
+		virtual ~D3D11MultiRenderTexture() { }
+
+	protected:
+		friend class D3D11TextureManager;
+
+		D3D11MultiRenderTexture() { }
 
 
 		/**
 		/**
-		 * @copydoc	MultiRenderTexture::requiresTextureFlipping
+		 * @copydoc	MultiRenderTexture::createProperties
 		 */
 		 */
-		bool requiresTextureFlipping() const { return false; }
+		virtual RenderTargetProperties* createProperties() const;
 
 
 		/**
 		/**
-		 * @copydoc	MultiRenderTexture::getCustomAttribute
+		 * @copydoc	MultiRenderTexture::createCore
 		 */
 		 */
-		void getCustomAttribute(const String& name, void* pData) const;
-	protected:
-		friend class D3D11TextureManager;
-
-		D3D11MultiRenderTexture();
+		virtual MultiRenderTextureCore* createCore(MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc);
 	};
 	};
 }
 }

+ 35 - 8
BansheeD3D11RenderSystem/Include/BsD3D11RenderTexture.h

@@ -6,27 +6,54 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	class D3D11RenderTexture;
+
 	/**
 	/**
 	 * @brief	DirectX 11 implementation of a render texture.
 	 * @brief	DirectX 11 implementation of a render texture.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-	class D3D11RenderTexture : public RenderTexture
+	class D3D11RenderTextureCore : public RenderTextureCore
 	{
 	{
 	public:
 	public:
-		virtual ~D3D11RenderTexture();
+		D3D11RenderTextureCore(D3D11RenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc);
 
 
-		/**
-		 * @copydoc	RenderTexture::requiresTextureFlipping
-		 */
-		bool requiresTextureFlipping() const { return false; }
+		virtual ~D3D11RenderTextureCore() { }
 
 
 		/**
 		/**
-		 * @copydoc	RenderTexture::getCustomAttribute
+		 * @copydoc	RenderTextureCore::getCustomAttribute
 		 */
 		 */
 		void getCustomAttribute(const String& name, void* pData) const;
 		void getCustomAttribute(const String& name, void* pData) const;
 
 
+	protected:
+		friend class D3D11RenderTexture;
+	};
+
+	/**
+	 * @brief	DirectX 11 implementation of a render texture.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class D3D11RenderTexture : public RenderTexture
+	{
+	public:
+		virtual ~D3D11RenderTexture() { }
+
 	protected:
 	protected:
 		friend class D3D11TextureManager;
 		friend class D3D11TextureManager;
 
 
-		D3D11RenderTexture();
+		D3D11RenderTexture() { }
+
+		/**
+		 * @copydoc	RenderTexture::createProperties
+		 */
+		virtual RenderTargetProperties* createProperties() const;
+
+		/**
+		 * @copydoc	RenderTexture::createCore
+		 */
+		virtual RenderTextureCore* createCore(RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc);
 	};
 	};
 }
 }

+ 93 - 56
BansheeD3D11RenderSystem/Include/BsD3D11RenderWindow.h

@@ -5,91 +5,89 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	class D3D11RenderWindow;
+
+	/**
+	 * @brief	Contains various properties that describe a render window.
+	 */
+	class BS_D3D11_EXPORT D3D11RenderWindowProperties : public RenderWindowProperties
+	{
+	public:
+		virtual ~D3D11RenderWindowProperties() { }
+
+	private:
+		friend class D3D11RenderWindowCore;
+		friend class D3D11RenderWindow;
+	};
+
 	/**
 	/**
 	 * @brief	Render window implementation for Windows and DirectX 11.
 	 * @brief	Render window implementation for Windows and DirectX 11.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-	class BS_D3D11_EXPORT D3D11RenderWindow : public RenderWindow
+	class BS_D3D11_EXPORT D3D11RenderWindowCore : public RenderWindowCore
 	{
 	{
 	public:
 	public:
-		~D3D11RenderWindow();
+		/**
+		 * @copydoc	RenderWindowCore::RenderWindowCore
+		 */
+		D3D11RenderWindowCore(D3D11RenderWindow* parent, RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc,
+			D3D11Device& device, IDXGIFactory* DXGIFactory);
+
+		~D3D11RenderWindowCore();
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::move
+		 * @copydoc RenderWindowCore::move
 		 */
 		 */
 		void move(INT32 left, INT32 top);
 		void move(INT32 left, INT32 top);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::resize
+		 * @copydoc RenderWindowCore::resize
 		 */
 		 */
 		void resize(UINT32 width, UINT32 height);
 		void resize(UINT32 width, UINT32 height);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setHidden
+		 * @copydoc RenderWindowCore::setHidden
 		 */
 		 */
 		void setHidden(bool hidden);
 		void setHidden(bool hidden);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setActive
+		 * @copydoc RenderWindowCore::setActive
 		 */
 		 */
 		void setActive(bool state);
 		void setActive(bool state);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::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);
 		void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setFullscreen(const VideoMode&)
+		 * @copydoc RenderWindowCore::setFullscreen(const VideoMode&)
 		 */
 		 */
 		void setFullscreen(const VideoMode& mode);
 		void setFullscreen(const VideoMode& mode);
 
 
 		/**
 		/**
-		* @copydoc RenderWindow::setWindowed
+		* @copydoc RenderWindowCore::setWindowed
 		*/
 		*/
 		void setWindowed(UINT32 width, UINT32 height);
 		void setWindowed(UINT32 width, UINT32 height);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::copyContentsToMemory
+		 * @copydoc RenderWindowCore::copyContentsToMemory
 		 */
 		 */
 		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::swapBuffers
+		 * @copydoc RenderWindowCore::swapBuffers
 		 */
 		 */
 		void swapBuffers();
 		void swapBuffers();
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::isClosed
-		 */
-		bool isClosed() const { return mClosed; }
-
-		/**
-		 * @copydoc RenderWindow::isHidden
-		 */
-		bool isHidden() const { return mHidden; }
-
-		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
-		Vector2I screenToWindowPos(const Vector2I& screenPos) const;
-
-		/**
-		 * @copydoc RenderWindow::windowToScreenPos
-		 */
-		Vector2I windowToScreenPos(const Vector2I& windowPos) const;
-
-		/**
-		 * @copydoc RenderWindow::getCustomAttribute
+		 * @copydoc RenderWindowCore::getCustomAttribute
 		 */
 		 */
 		void getCustomAttribute(const String& name, void* pData) const;
 		void getCustomAttribute(const String& name, void* pData) const;
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::requiresTextureFlipping
-		 */
-		bool requiresTextureFlipping() const { return false; }
-
-		/**
-		 * @copydoc	RenderWindow::_windowMovedOrResized
+		 * @copydoc	RenderWindowCore::_windowMovedOrResized
 		 */
 		 */
 		void _windowMovedOrResized();
 		void _windowMovedOrResized();
 
 
@@ -104,12 +102,7 @@ namespace BansheeEngine
 		HWND _getWindowHandle() const { return mHWnd; }
 		HWND _getWindowHandle() const { return mHWnd; }
 
 
 	protected:
 	protected:
-		friend class D3D11RenderWindowManager;
-
-		/**
-		 * @copydoc	RenderWindow::RenderWindow
-		 */
-		D3D11RenderWindow(const RENDER_WINDOW_DESC& desc, D3D11Device& device, IDXGIFactory* DXGIFactory);
+		friend class D3D11RenderWindow;
 
 
 		/**
 		/**
 		 * @brief	Creates internal resources dependent on window size.
 		 * @brief	Creates internal resources dependent on window size.
@@ -135,27 +128,15 @@ namespace BansheeEngine
 		 * @brief	Resizes all buffers attached to the swap chain to the specified size.
 		 * @brief	Resizes all buffers attached to the swap chain to the specified size.
 		 */
 		 */
 		void resizeSwapChainBuffers(UINT32 width, UINT32 height);
 		void resizeSwapChainBuffers(UINT32 width, UINT32 height);
-		
-		/**
-		 * @copydoc RenderWindow::initialize_internal
-		 */
-		void initialize_internal();
 
 
-		/**
-		 * @copydoc RenderWindow::destroy_internal
-		 */
-		void destroy_internal();
 	protected:
 	protected:
 		D3D11Device& mDevice;
 		D3D11Device& mDevice;
 		IDXGIFactory* mDXGIFactory;
 		IDXGIFactory* mDXGIFactory;
 		bool mIsExternal;
 		bool mIsExternal;
 		bool mSizing;
 		bool mSizing;
-		bool mClosed;
 		bool mIsChild;
 		bool mIsChild;
 
 
 		DXGI_SAMPLE_DESC mMultisampleType;
 		DXGI_SAMPLE_DESC mMultisampleType;
-		bool mVSync;
-		UINT32 mVSyncInterval;
 		UINT32 mRefreshRateNumerator;
 		UINT32 mRefreshRateNumerator;
 		UINT32 mRefreshRateDenominator;
 		UINT32 mRefreshRateDenominator;
 
 
@@ -169,4 +150,60 @@ namespace BansheeEngine
 
 
 		HWND mHWnd;
 		HWND mHWnd;
 	};
 	};
+
+	/**
+	 * @brief	Render window implementation for Windows and DirectX 11.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_D3D11_EXPORT D3D11RenderWindow : public RenderWindow
+	{
+	public:
+		~D3D11RenderWindow() { }
+
+		/**
+		 * @copydoc RenderWindow::requiresTextureFlipping
+		 */
+		bool requiresTextureFlipping() const { return false; }
+
+		/**
+		 * @copydoc RenderWindow::getCustomAttribute
+		 */
+		void getCustomAttribute(const String& name, void* pData) const;
+
+		/**
+		 * @copydoc RenderWindow::screenToWindowPos
+		 */
+		Vector2I screenToWindowPos(const Vector2I& screenPos) const;
+
+		/**
+		 * @copydoc RenderWindow::windowToScreenPos
+		 */
+		Vector2I windowToScreenPos(const Vector2I& windowPos) const;
+
+	protected:
+		friend class D3D11RenderWindowManager;
+
+		D3D11RenderWindow(D3D11Device& device, IDXGIFactory* DXGIFactory);
+
+		/**
+		 * @copydoc	RenderWindow::initialize_internal
+		 */
+		virtual void initialize_internal();
+
+		/**
+		 * @copydoc	RenderWindow::createProperties
+		 */
+		virtual RenderTargetProperties* createProperties() const;
+
+		/**
+		 * @copydoc	RenderWindow::createCore
+		 */
+		virtual RenderWindowCore* createCore(RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc);
+
+	private:
+		D3D11Device& mDevice;
+		IDXGIFactory* mDXGIFactory;
+		HWND mHWnd;
+	};
 }
 }

+ 15 - 4
BansheeD3D11RenderSystem/Source/BsD3D11MultiRenderTexture.cpp

@@ -5,18 +5,19 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D11MultiRenderTexture::D3D11MultiRenderTexture()
-		:MultiRenderTexture()
+	D3D11MultiRenderTextureCore::D3D11MultiRenderTextureCore(D3D11MultiRenderTexture* parent, 
+		MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
+		:MultiRenderTextureCore(parent, properties, desc)
 	{
 	{
 
 
 	}
 	}
 
 
-	D3D11MultiRenderTexture::~D3D11MultiRenderTexture()
+	D3D11MultiRenderTextureCore::~D3D11MultiRenderTextureCore()
 	{
 	{
 
 
 	}
 	}
 
 
-	void D3D11MultiRenderTexture::getCustomAttribute(const String& name, void* pData) const
+	void D3D11MultiRenderTextureCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name == "RTV")
 		if(name == "RTV")
 		{
 		{
@@ -38,4 +39,14 @@ namespace BansheeEngine
 			return;
 			return;
 		}
 		}
 	}
 	}
+
+	RenderTargetProperties* D3D11MultiRenderTexture::createProperties() const
+	{
+		return bs_new<MultiRenderTextureProperties>();
+	}
+
+	MultiRenderTextureCore* D3D11MultiRenderTexture::createCore(MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
+	{
+		return bs_new<D3D11MultiRenderTextureCore>(this, properties, desc);
+	}
 }
 }

+ 14 - 10
BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp

@@ -320,16 +320,18 @@ namespace BansheeEngine
 		RenderTargetPtr target = vp.getTarget();
 		RenderTargetPtr target = vp.getTarget();
 		setRenderTarget(target);
 		setRenderTarget(target);
 
 
+		const RenderTargetProperties& rtProps = target->getCore()->getProperties();
+
 		// Set viewport dimensions
 		// Set viewport dimensions
-		mViewport.TopLeftX = (FLOAT)vp.getX();
-		mViewport.TopLeftY = (FLOAT)vp.getY();
-		mViewport.Width = (FLOAT)vp.getWidth();
-		mViewport.Height = (FLOAT)vp.getHeight();
+		mViewport.TopLeftX = (FLOAT)(rtProps.getWidth() * vp.getNormalizedX());
+		mViewport.TopLeftY = (FLOAT)(rtProps.getHeight() * vp.getNormalizedY());
+		mViewport.Width = (FLOAT)(rtProps.getWidth() * vp.getNormalizedWidth());
+		mViewport.Height = (FLOAT)(rtProps.getHeight() * vp.getNormalizedHeight());
 
 
 		if (target->requiresTextureFlipping())
 		if (target->requiresTextureFlipping())
 		{
 		{
 			// Convert "top-left" to "bottom-left"
 			// Convert "top-left" to "bottom-left"
-			mViewport.TopLeftY = target->getHeight() - mViewport.Height - mViewport.TopLeftY;
+			mViewport.TopLeftY = target->getCore()->getProperties().getHeight() - mViewport.Height - mViewport.TopLeftY;
 		}
 		}
 
 
 		mViewport.MinDepth = 0.0f;
 		mViewport.MinDepth = 0.0f;
@@ -617,10 +619,12 @@ namespace BansheeEngine
 		if(mActiveRenderTarget == nullptr)
 		if(mActiveRenderTarget == nullptr)
 			return;
 			return;
 
 
+		const RenderTargetProperties& rtProps = mActiveRenderTarget->getCore()->getProperties();
+
 		RectI clearArea((int)mViewport.TopLeftX, (int)mViewport.TopLeftY, (int)mViewport.Width, (int)mViewport.Height);
 		RectI clearArea((int)mViewport.TopLeftX, (int)mViewport.TopLeftY, (int)mViewport.Width, (int)mViewport.Height);
 
 
 		bool clearEntireTarget = clearArea.width == 0 || clearArea.height == 0;
 		bool clearEntireTarget = clearArea.width == 0 || clearArea.height == 0;
-		clearEntireTarget |= (clearArea.x == 0 && clearArea.y == 0 && clearArea.width == mActiveRenderTarget->getWidth() && clearArea.height == mActiveRenderTarget->getHeight());
+		clearEntireTarget |= (clearArea.x == 0 && clearArea.y == 0 && clearArea.width == rtProps.getWidth() && clearArea.height == rtProps.getHeight());
 
 
 		if (!clearEntireTarget)
 		if (!clearEntireTarget)
 		{
 		{
@@ -646,7 +650,7 @@ namespace BansheeEngine
 			ID3D11RenderTargetView** views = bs_newN<ID3D11RenderTargetView*, ScratchAlloc>(maxRenderTargets);
 			ID3D11RenderTargetView** views = bs_newN<ID3D11RenderTargetView*, ScratchAlloc>(maxRenderTargets);
 			memset(views, 0, sizeof(ID3D11RenderTargetView*) * maxRenderTargets);
 			memset(views, 0, sizeof(ID3D11RenderTargetView*) * maxRenderTargets);
 
 
-			mActiveRenderTarget->getCustomAttribute("RTV", views);
+			mActiveRenderTarget->getCore()->getCustomAttribute("RTV", views);
 			if (!views[0])
 			if (!views[0])
 			{
 			{
 				bs_deleteN<ScratchAlloc>(views, maxRenderTargets);
 				bs_deleteN<ScratchAlloc>(views, maxRenderTargets);
@@ -672,7 +676,7 @@ namespace BansheeEngine
 		if((buffers & FBT_DEPTH) != 0 || (buffers & FBT_STENCIL) != 0)
 		if((buffers & FBT_DEPTH) != 0 || (buffers & FBT_STENCIL) != 0)
 		{
 		{
 			ID3D11DepthStencilView* depthStencilView = nullptr;
 			ID3D11DepthStencilView* depthStencilView = nullptr;
-			mActiveRenderTarget->getCustomAttribute("DSV", &depthStencilView);
+			mActiveRenderTarget->getCore()->getCustomAttribute("DSV", &depthStencilView);
 
 
 			D3D11_CLEAR_FLAG clearFlag;
 			D3D11_CLEAR_FLAG clearFlag;
 
 
@@ -700,7 +704,7 @@ namespace BansheeEngine
 		UINT32 maxRenderTargets = mCurrentCapabilities->getNumMultiRenderTargets();
 		UINT32 maxRenderTargets = mCurrentCapabilities->getNumMultiRenderTargets();
 		ID3D11RenderTargetView** views = bs_newN<ID3D11RenderTargetView*, ScratchAlloc>(maxRenderTargets);
 		ID3D11RenderTargetView** views = bs_newN<ID3D11RenderTargetView*, ScratchAlloc>(maxRenderTargets);
 		memset(views, 0, sizeof(ID3D11RenderTargetView*) * maxRenderTargets);
 		memset(views, 0, sizeof(ID3D11RenderTargetView*) * maxRenderTargets);
-		target->getCustomAttribute("RTV", views);
+		target->getCore()->getCustomAttribute("RTV", views);
 		if (!views[0])
 		if (!views[0])
 		{
 		{
 			bs_deleteN<ScratchAlloc>(views, maxRenderTargets);
 			bs_deleteN<ScratchAlloc>(views, maxRenderTargets);
@@ -709,7 +713,7 @@ namespace BansheeEngine
 
 
 		// Retrieve depth stencil
 		// Retrieve depth stencil
 		ID3D11DepthStencilView* depthStencilView = nullptr;
 		ID3D11DepthStencilView* depthStencilView = nullptr;
-		target->getCustomAttribute("DSV", &depthStencilView);
+		target->getCore()->getCustomAttribute("DSV", &depthStencilView);
 
 
 		// Bind render targets
 		// Bind render targets
 		mDevice->getImmediateContext()->OMSetRenderTargets(maxRenderTargets, views, depthStencilView);
 		mDevice->getImmediateContext()->OMSetRenderTargets(maxRenderTargets, views, depthStencilView);

+ 16 - 10
BansheeD3D11RenderSystem/Source/BsD3D11RenderTexture.cpp

@@ -9,17 +9,12 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D11RenderTexture::D3D11RenderTexture()
-		:RenderTexture()
-	{
-
-	}
-
-	D3D11RenderTexture::~D3D11RenderTexture()
-	{
-	}
+	D3D11RenderTextureCore::D3D11RenderTextureCore(D3D11RenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+		const RENDER_SURFACE_DESC& depthStencilSurfaceDesc)
+		:RenderTextureCore(parent, properties, colorSurfaceDesc, depthStencilSurfaceDesc)
+	{ }
 
 
-	void D3D11RenderTexture::getCustomAttribute(const String& name, void* pData) const
+	void D3D11RenderTextureCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name == "RTV")
 		if(name == "RTV")
 		{
 		{
@@ -37,4 +32,15 @@ namespace BansheeEngine
 			return;
 			return;
 		}
 		}
 	}
 	}
+
+	RenderTargetProperties* D3D11RenderTexture::createProperties() const
+	{
+		return bs_new<RenderTextureProperties>();
+	}
+
+	RenderTextureCore* D3D11RenderTexture::createCore(RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+		const RENDER_SURFACE_DESC& depthStencilSurfaceDesc)
+	{
+		return bs_new<D3D11RenderTextureCore>(this, properties, colorSurfaceDesc, depthStencilSurfaceDesc);
+	}
 }
 }

+ 208 - 158
BansheeD3D11RenderSystem/Source/BsD3D11RenderWindow.cpp

@@ -15,56 +15,45 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D11RenderWindow::D3D11RenderWindow(const RENDER_WINDOW_DESC& desc,D3D11Device& device, IDXGIFactory* DXGIFactory)
-		: RenderWindow(desc), mDevice(device), mDXGIFactory(DXGIFactory), mIsExternal(false), mSizing(false), 
-		mClosed(false), mRenderTargetView(nullptr), mBackBuffer(nullptr), mSwapChain(nullptr), mHWnd(0), 
+	D3D11RenderWindowCore::D3D11RenderWindowCore(D3D11RenderWindow* parent, RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc, D3D11Device& device, IDXGIFactory* DXGIFactory)
+		: RenderWindowCore(parent, properties), mDevice(device), mDXGIFactory(DXGIFactory), mIsExternal(false), mSizing(false),
+		 mRenderTargetView(nullptr), mBackBuffer(nullptr), mSwapChain(nullptr), mHWnd(0), 
 		mDepthStencilView(nullptr), mIsChild(false), mRefreshRateNumerator(0), mRefreshRateDenominator(0)
 		mDepthStencilView(nullptr), mIsChild(false), mRefreshRateNumerator(0), mRefreshRateDenominator(0)
 	{
 	{
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
-	}
 
 
-	D3D11RenderWindow::~D3D11RenderWindow()
-	{
-	}
+		D3D11RenderWindowProperties* props = static_cast<D3D11RenderWindowProperties*>(mProperties);
 
 
-	void D3D11RenderWindow::initialize_internal()
-	{
 		mMultisampleType.Count = 1;
 		mMultisampleType.Count = 1;
 		mMultisampleType.Quality = 0;
 		mMultisampleType.Quality = 0;
-		mMultisampleCount = 0;
-		mMultisampleHint = "";
-		mVSync = false;
-		mVSyncInterval = 1;
 		HWND parentHWnd = 0;
 		HWND parentHWnd = 0;
 		HWND externalHandle = 0;
 		HWND externalHandle = 0;
-		
+
 
 
 		NameValuePairList::const_iterator opt;
 		NameValuePairList::const_iterator opt;
-		opt = mDesc.platformSpecific.find("parentWindowHandle");
-		if(opt != mDesc.platformSpecific.end())
+		opt = desc.platformSpecific.find("parentWindowHandle");
+		if (opt != desc.platformSpecific.end())
 			parentHWnd = (HWND)parseUnsignedInt(opt->second);
 			parentHWnd = (HWND)parseUnsignedInt(opt->second);
 
 
-		opt = mDesc.platformSpecific.find("externalWindowHandle");
-		if(opt != mDesc.platformSpecific.end())
+		opt = desc.platformSpecific.find("externalWindowHandle");
+		if (opt != desc.platformSpecific.end())
 			externalHandle = (HWND)parseUnsignedInt(opt->second);
 			externalHandle = (HWND)parseUnsignedInt(opt->second);
 
 
-		mName = mDesc.title;
+		props->mName = desc.title;
 		mIsChild = parentHWnd != 0;
 		mIsChild = parentHWnd != 0;
-		mIsFullScreen = mDesc.fullscreen && !mIsChild;
-		mColorDepth = 32;
-		mWidth = mHeight = mLeft = mTop = 0;
+		props->mIsFullScreen = desc.fullscreen && !mIsChild;
+		props->mColorDepth = 32;
 
 
-		mActive = true;
-		mClosed = false;
+		props->mActive = true;
 
 
-		if (mDesc.videoMode.isCustom())
+		if (desc.videoMode.isCustom())
 		{
 		{
-			mRefreshRateNumerator = Math::roundToInt(mDesc.videoMode.getRefreshRate());
+			mRefreshRateNumerator = Math::roundToInt(desc.videoMode.getRefreshRate());
 			mRefreshRateDenominator = 1;
 			mRefreshRateDenominator = 1;
 		}
 		}
 		else
 		else
 		{
 		{
-			const D3D11VideoMode& d3d11videoMode = static_cast<const D3D11VideoMode&>(mDesc.videoMode);
+			const D3D11VideoMode& d3d11videoMode = static_cast<const D3D11VideoMode&>(desc.videoMode);
 			mRefreshRateNumerator = d3d11videoMode.getRefreshRateNumerator();
 			mRefreshRateNumerator = d3d11videoMode.getRefreshRateNumerator();
 			mRefreshRateDenominator = d3d11videoMode.getRefreshRateDenominator();
 			mRefreshRateDenominator = d3d11videoMode.getRefreshRateDenominator();
 		}
 		}
@@ -76,7 +65,7 @@ namespace BansheeEngine
 		UINT32 numOutputs = videoModeInfo.getNumOutputs();
 		UINT32 numOutputs = videoModeInfo.getNumOutputs();
 		if (numOutputs > 0)
 		if (numOutputs > 0)
 		{
 		{
-			UINT32 actualMonitorIdx = std::min(mDesc.videoMode.getOutputIdx(), numOutputs - 1);
+			UINT32 actualMonitorIdx = std::min(desc.videoMode.getOutputIdx(), numOutputs - 1);
 			outputInfo = static_cast<const D3D11VideoOutputInfo*>(&videoModeInfo.getOutputInfo(actualMonitorIdx));
 			outputInfo = static_cast<const D3D11VideoOutputInfo*>(&videoModeInfo.getOutputInfo(actualMonitorIdx));
 
 
 			DXGI_OUTPUT_DESC desc;
 			DXGI_OUTPUT_DESC desc;
@@ -87,7 +76,7 @@ namespace BansheeEngine
 
 
 		if (!externalHandle)
 		if (!externalHandle)
 		{
 		{
-			DWORD dwStyle = (mHidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN;
+			DWORD dwStyle = (getProperties().isHidden() ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN;
 			DWORD dwStyleEx = 0;
 			DWORD dwStyleEx = 0;
 			RECT rc;
 			RECT rc;
 			MONITORINFO monitorInfo;
 			MONITORINFO monitorInfo;
@@ -98,8 +87,8 @@ namespace BansheeEngine
 				POINT windowAnchorPoint;
 				POINT windowAnchorPoint;
 
 
 				// Fill in anchor point.
 				// Fill in anchor point.
-				windowAnchorPoint.x = mDesc.left;
-				windowAnchorPoint.y = mDesc.top;
+				windowAnchorPoint.x = desc.left;
+				windowAnchorPoint.y = desc.top;
 
 
 				// Get the nearest monitor to this window.
 				// Get the nearest monitor to this window.
 				hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY);
 				hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY);
@@ -110,23 +99,22 @@ namespace BansheeEngine
 			monitorInfo.cbSize = sizeof(MONITORINFO);
 			monitorInfo.cbSize = sizeof(MONITORINFO);
 			GetMonitorInfo(hMonitor, &monitorInfo);
 			GetMonitorInfo(hMonitor, &monitorInfo);
 
 
-
 			unsigned int winWidth, winHeight;
 			unsigned int winWidth, winHeight;
-			winWidth = mDesc.videoMode.getWidth();
-			winHeight = mDesc.videoMode.getHeight();
+			winWidth = desc.videoMode.getWidth();
+			winHeight = desc.videoMode.getHeight();
 
 
-			UINT32 left = mDesc.left;
-			UINT32 top = mDesc.top;
+			UINT32 left = desc.left;
+			UINT32 top = desc.top;
 
 
 			// No specified top left -> Center the window in the middle of the monitor
 			// No specified top left -> Center the window in the middle of the monitor
 			if (left == -1 || top == -1)
 			if (left == -1 || top == -1)
-			{				
-				int screenw = monitorInfo.rcWork.right  - monitorInfo.rcWork.left;
+			{
+				int screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
 				int screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 				int screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 
 
 				// clamp window dimensions to screen size
 				// clamp window dimensions to screen size
-				int outerw = (int(winWidth) < screenw)? int(winWidth) : screenw;
-				int outerh = (int(winHeight) < screenh)? int(winHeight) : screenh;
+				int outerw = (int(winWidth) < screenw) ? int(winWidth) : screenw;
+				int outerh = (int(winHeight) < screenh) ? int(winHeight) : screenh;
 
 
 				if (left == -1)
 				if (left == -1)
 					left = monitorInfo.rcWork.left + (screenw - outerw) / 2;
 					left = monitorInfo.rcWork.left + (screenw - outerw) / 2;
@@ -144,62 +132,63 @@ namespace BansheeEngine
 				top += monitorInfo.rcWork.top;
 				top += monitorInfo.rcWork.top;
 			}
 			}
 
 
-			mWidth = mDesc.videoMode.getWidth();
-			mHeight = mDesc.videoMode.getHeight();
-			mTop = top;
-			mLeft = left;
+			props->mWidth = desc.videoMode.getWidth();
+			props->mHeight = desc.videoMode.getHeight();
+			props->mTop = top;
+			props->mLeft = left;
 
 
-			if (!mDesc.fullscreen)
+			if (!desc.fullscreen)
 			{
 			{
 				if (parentHWnd)
 				if (parentHWnd)
 				{
 				{
-					if(mDesc.toolWindow)
+					if (desc.toolWindow)
 						dwStyleEx = WS_EX_TOOLWINDOW;
 						dwStyleEx = WS_EX_TOOLWINDOW;
 					else
 					else
 						dwStyle |= WS_CHILD;
 						dwStyle |= WS_CHILD;
 				}
 				}
 
 
-				if (!parentHWnd || mDesc.toolWindow)
+				if (!parentHWnd || desc.toolWindow)
 				{
 				{
-					if (mDesc.border == WindowBorder::None)
+					if (desc.border == WindowBorder::None)
 						dwStyle |= WS_POPUP;
 						dwStyle |= WS_POPUP;
-					else if (mDesc.border == WindowBorder::Fixed)
+					else if (desc.border == WindowBorder::Fixed)
 						dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
 						dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
 						WS_SYSMENU | WS_MINIMIZEBOX;
 						WS_SYSMENU | WS_MINIMIZEBOX;
 					else
 					else
 						dwStyle |= WS_OVERLAPPEDWINDOW;
 						dwStyle |= WS_OVERLAPPEDWINDOW;
 				}
 				}
 
 
-				if (!mDesc.outerDimensions)
+				if (!desc.outerDimensions)
 				{
 				{
 					// Calculate window dimensions required
 					// Calculate window dimensions required
 					// to get the requested client area
 					// to get the requested client area
-					SetRect(&rc, 0, 0, mWidth, mHeight);
+					SetRect(&rc, 0, 0, props->mWidth, props->mHeight);
 					AdjustWindowRect(&rc, dwStyle, false);
 					AdjustWindowRect(&rc, dwStyle, false);
-					mWidth = rc.right - rc.left;
-					mHeight = rc.bottom - rc.top;
+					props->mWidth = rc.right - rc.left;
+					props->mHeight = rc.bottom - rc.top;
 
 
 					// Clamp width and height to the desktop dimensions
 					// Clamp width and height to the desktop dimensions
 					int screenw = GetSystemMetrics(SM_CXSCREEN);
 					int screenw = GetSystemMetrics(SM_CXSCREEN);
 					int screenh = GetSystemMetrics(SM_CYSCREEN);
 					int screenh = GetSystemMetrics(SM_CYSCREEN);
-					if ((int)mWidth > screenw)
-						mWidth = screenw;
-					if ((int)mHeight > screenh)
-						mHeight = screenh;
-					if (mLeft < 0)
-						mLeft = (screenw - mWidth) / 2;
-					if (mTop < 0)
-						mTop = (screenh - mHeight) / 2;
+					if ((int)props->mWidth > screenw)
+						props->mWidth = screenw;
+					if ((int)props->mHeight > screenh)
+						props->mHeight = screenh;
+					if (props->mLeft < 0)
+						props->mLeft = (screenw - props->mWidth) / 2;
+					if (props->mTop < 0)
+						props->mTop = (screenh - props->mHeight) / 2;
 				}
 				}
 			}
 			}
 			else
 			else
 			{
 			{
 				dwStyle |= WS_POPUP;
 				dwStyle |= WS_POPUP;
-				mTop = mLeft = 0;
+				props->mTop = 0;
+				props->mLeft = 0;
 			}
 			}
 
 
 			UINT classStyle = 0;
 			UINT classStyle = 0;
-			if (mDesc.enableDoubleClick)
+			if (desc.enableDoubleClick)
 				classStyle |= CS_DBLCLKS;
 				classStyle |= CS_DBLCLKS;
 
 
 			HINSTANCE hInst = NULL;
 			HINSTANCE hInst = NULL;
@@ -208,15 +197,15 @@ namespace BansheeEngine
 			// Allow 4 bytes of window data for D3D11RenderWindow pointer
 			// Allow 4 bytes of window data for D3D11RenderWindow pointer
 			WNDCLASS wc = { classStyle, PlatformWndProc::_win32WndProc, 0, 0, hInst,
 			WNDCLASS wc = { classStyle, PlatformWndProc::_win32WndProc, 0, 0, hInst,
 				LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
 				LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
-				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "D3D11Wnd" };	
+				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "D3D11Wnd" };
 
 
 			RegisterClass(&wc);
 			RegisterClass(&wc);
 
 
 			// Create our main window
 			// Create our main window
 			// Pass pointer to self
 			// Pass pointer to self
 			mIsExternal = false;
 			mIsExternal = false;
-			mHWnd = CreateWindowEx(dwStyleEx, "D3D11Wnd", mDesc.title.c_str(), dwStyle,
-				mLeft, mTop, mWidth, mHeight, parentHWnd, 0, hInst, this);
+			mHWnd = CreateWindowEx(dwStyleEx, "D3D11Wnd", desc.title.c_str(), dwStyle,
+				props->mLeft, props->mTop, props->mWidth, props->mHeight, parentHWnd, 0, hInst, this);
 		}
 		}
 		else
 		else
 		{
 		{
@@ -226,16 +215,16 @@ namespace BansheeEngine
 
 
 		RECT rc;
 		RECT rc;
 		GetWindowRect(mHWnd, &rc);
 		GetWindowRect(mHWnd, &rc);
-		mTop = rc.top;
-		mLeft = rc.left;
+		props->mTop = rc.top;
+		props->mLeft = rc.left;
 
 
 		GetClientRect(mHWnd, &rc);
 		GetClientRect(mHWnd, &rc);
-		mWidth = rc.right;
-		mHeight = rc.bottom;
+		props->mWidth = rc.right;
+		props->mHeight = rc.bottom;
 
 
 		createSwapChain();
 		createSwapChain();
 
 
-		if (mIsFullScreen)
+		if (getProperties().isFullScreen())
 		{
 		{
 			if (outputInfo != nullptr)
 			if (outputInfo != nullptr)
 				mSwapChain->SetFullscreenState(true, outputInfo->getDXGIOutput());
 				mSwapChain->SetFullscreenState(true, outputInfo->getDXGIOutput());
@@ -245,15 +234,15 @@ namespace BansheeEngine
 
 
 		createSizeDependedD3DResources();
 		createSizeDependedD3DResources();
 		mDXGIFactory->MakeWindowAssociation(mHWnd, NULL);
 		mDXGIFactory->MakeWindowAssociation(mHWnd, NULL);
-		setHidden(mHidden);
-
-		RenderWindow::initialize_internal();
+		setHidden(getProperties().isHidden());
 	}
 	}
 
 
-	void D3D11RenderWindow::destroy_internal()
+	D3D11RenderWindowCore::~D3D11RenderWindowCore()
 	{
 	{
-		mActive = false;
-		mClosed = true;
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+
+		properties->mActive = false;
+		markCoreDirty();
 
 
 		SAFE_RELEASE(mSwapChain);
 		SAFE_RELEASE(mSwapChain);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_SwapChain);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_SwapChain);
@@ -263,7 +252,7 @@ namespace BansheeEngine
 			DestroyWindow(mHWnd);
 			DestroyWindow(mHWnd);
 		}
 		}
 
 
-		if(mDepthStencilView != nullptr)
+		if (mDepthStencilView != nullptr)
 		{
 		{
 			Texture::releaseView(mDepthStencilView);
 			Texture::releaseView(mDepthStencilView);
 			mDepthStencilView = nullptr;
 			mDepthStencilView = nullptr;
@@ -272,65 +261,70 @@ namespace BansheeEngine
 		mHWnd = nullptr;
 		mHWnd = nullptr;
 
 
 		destroySizeDependedD3DResources();
 		destroySizeDependedD3DResources();
-
-		RenderWindow::destroy_internal();
 	}
 	}
 
 
-	void D3D11RenderWindow::swapBuffers()
+	void D3D11RenderWindowCore::swapBuffers()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		if(mDevice.getD3D11Device() != nullptr)
 		if(mDevice.getD3D11Device() != nullptr)
 		{
 		{
-			HRESULT hr = mSwapChain->Present(mVSync ? mVSyncInterval : 0, 0);
+			HRESULT hr = mSwapChain->Present(getProperties().getVSync() ? getProperties().getVSyncInterval() : 0, 0);
 
 
 			if( FAILED(hr) )
 			if( FAILED(hr) )
 				BS_EXCEPT(RenderingAPIException, "Error Presenting surfaces");
 				BS_EXCEPT(RenderingAPIException, "Error Presenting surfaces");
 		}
 		}
 	}
 	}
 
 
-	void D3D11RenderWindow::move(INT32 top, INT32 left)
+	void D3D11RenderWindowCore::move(INT32 top, INT32 left)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd && !mIsFullScreen)
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+
+		if (mHWnd && !properties->mIsFullScreen)
 		{
 		{
-			mTop = top;
-			mLeft = left;
+			properties->mTop = top;
+			properties->mLeft = left;
 
 
-			SetWindowPos(mHWnd, 0, top, left, 0, 0,
-				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+			SetWindowPos(mHWnd, 0, top, left, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+			markCoreDirty();			
 		}
 		}
 	}
 	}
 
 
-	void D3D11RenderWindow::resize(UINT32 width, UINT32 height)
+	void D3D11RenderWindowCore::resize(UINT32 width, UINT32 height)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd && !mIsFullScreen)
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+
+		if (mHWnd && !properties->mIsFullScreen)
 		{
 		{
-			mWidth = width;
-			mHeight = height;
+			properties->mWidth = width;
+			properties->mHeight = height;
 
 
 			RECT rc = { 0, 0, width, height };
 			RECT rc = { 0, 0, width, height };
 			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
 			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
 			width = rc.right - rc.left;
 			width = rc.right - rc.left;
 			height = rc.bottom - rc.top;
 			height = rc.bottom - rc.top;
-			SetWindowPos(mHWnd, 0, 0, 0, width, height,
-				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+			SetWindowPos(mHWnd, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+			markCoreDirty();
 		}
 		}
 	}
 	}
 
 
-	void D3D11RenderWindow::setActive(bool state)
+	void D3D11RenderWindowCore::setActive(bool state)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+
 		if (mHWnd && mSwapChain)
 		if (mHWnd && mSwapChain)
 		{
 		{
 			if (state)
 			if (state)
 			{
 			{
 				ShowWindow(mHWnd, SW_RESTORE);
 				ShowWindow(mHWnd, SW_RESTORE);
-				mSwapChain->SetFullscreenState(mIsFullScreen, nullptr);
+				mSwapChain->SetFullscreenState(properties->mIsFullScreen, nullptr);
 			}
 			}
 			else
 			else
 			{
 			{
@@ -339,14 +333,16 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
-		RenderWindow::setActive(state);
+		RenderWindowCore::setActive(state);
 	}
 	}
 
 
-	void D3D11RenderWindow::setHidden(bool hidden)
+	void D3D11RenderWindowCore::setHidden(bool hidden)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		mHidden = hidden;
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+
+		properties->mHidden = hidden;
 		if (!mIsExternal)
 		if (!mIsExternal)
 		{
 		{
 			if (hidden)
 			if (hidden)
@@ -354,9 +350,11 @@ namespace BansheeEngine
 			else
 			else
 				ShowWindow(mHWnd, SW_SHOWNORMAL);
 				ShowWindow(mHWnd, SW_SHOWNORMAL);
 		}
 		}
+
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D11RenderWindow::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
+	void D3D11RenderWindowCore::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -387,15 +385,18 @@ namespace BansheeEngine
 
 
 		outputInfo.getDXGIOutput()->FindClosestMatchingMode(&modeDesc, &nearestMode, nullptr);
 		outputInfo.getDXGIOutput()->FindClosestMatchingMode(&modeDesc, &nearestMode, nullptr);
 
 
-		mIsFullScreen = true;
-		mWidth = width;
-		mHeight = height;
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+		properties->mIsFullScreen = true;
+		properties->mWidth = width;
+		properties->mHeight = height;
 
 
 		mSwapChain->ResizeTarget(&nearestMode);
 		mSwapChain->ResizeTarget(&nearestMode);
 		mSwapChain->SetFullscreenState(true, outputInfo.getDXGIOutput()); 
 		mSwapChain->SetFullscreenState(true, outputInfo.getDXGIOutput()); 
+
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D11RenderWindow::setFullscreen(const VideoMode& mode)
+	void D3D11RenderWindowCore::setFullscreen(const VideoMode& mode)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -418,42 +419,48 @@ namespace BansheeEngine
 
 
 		const D3D11VideoMode& videoMode = static_cast<const D3D11VideoMode&>(mode);
 		const D3D11VideoMode& videoMode = static_cast<const D3D11VideoMode&>(mode);
 
 
-		mIsFullScreen = true;
-		mWidth = mode.getWidth();
-		mHeight = mode.getHeight();
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+		properties->mIsFullScreen = true;
+		properties->mWidth = mode.getWidth();
+		properties->mHeight = mode.getHeight();
 
 
 		mSwapChain->ResizeTarget(&videoMode.getDXGIModeDesc());
 		mSwapChain->ResizeTarget(&videoMode.getDXGIModeDesc());
 		mSwapChain->SetFullscreenState(true, outputInfo.getDXGIOutput());
 		mSwapChain->SetFullscreenState(true, outputInfo.getDXGIOutput());
+
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D11RenderWindow::setWindowed(UINT32 width, UINT32 height)
+	void D3D11RenderWindowCore::setWindowed(UINT32 width, UINT32 height)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		mWidth = width;
-		mHeight = height;
-		mIsFullScreen = false;
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+		properties->mWidth = width;
+		properties->mHeight = height;
+		properties->mIsFullScreen = false;
 
 
 		mSwapChainDesc.Windowed = true;
 		mSwapChainDesc.Windowed = true;
 		mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
 		mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
 		mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
 		mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
-		mSwapChainDesc.BufferDesc.Width = mWidth;
-		mSwapChainDesc.BufferDesc.Height = mHeight;
+		mSwapChainDesc.BufferDesc.Width = width;
+		mSwapChainDesc.BufferDesc.Height = height;
 
 
 		DXGI_MODE_DESC modeDesc;
 		DXGI_MODE_DESC modeDesc;
 		ZeroMemory(&modeDesc, sizeof(modeDesc));
 		ZeroMemory(&modeDesc, sizeof(modeDesc));
 
 
-		modeDesc.Width = mWidth;
-		modeDesc.Height = mHeight;
+		modeDesc.Width = width;
+		modeDesc.Height = height;
 		modeDesc.RefreshRate.Numerator = 0;
 		modeDesc.RefreshRate.Numerator = 0;
 		modeDesc.RefreshRate.Denominator = 0;
 		modeDesc.RefreshRate.Denominator = 0;
 		modeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
 		modeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
 
 
 		mSwapChain->SetFullscreenState(false, nullptr);
 		mSwapChain->SetFullscreenState(false, nullptr);
 		mSwapChain->ResizeTarget(&modeDesc);
 		mSwapChain->ResizeTarget(&modeDesc);
+
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D11RenderWindow::getCustomAttribute( const String& name, void* pData ) const
+	void D3D11RenderWindowCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name == "WINDOW")
 		if(name == "WINDOW")
 		{
 		{
@@ -474,10 +481,10 @@ namespace BansheeEngine
 			return;
 			return;
 		}
 		}
 
 
-		RenderWindow::getCustomAttribute(name, pData);
+		RenderWindowCore::getCustomAttribute(name, pData);
 	}
 	}
 
 
-	void D3D11RenderWindow::copyToMemory(PixelData &dst, FrameBuffer buffer)
+	void D3D11RenderWindowCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -535,7 +542,7 @@ namespace BansheeEngine
 		mDevice.getImmediateContext()->Map(tempTexture, 0,D3D11_MAP_READ, 0, &mappedTex2D);
 		mDevice.getImmediateContext()->Map(tempTexture, 0,D3D11_MAP_READ, 0, &mappedTex2D);
 
 
 		// Copy the the texture to the dest
 		// Copy the the texture to the dest
-		PixelData src(mWidth, mHeight, 1, PF_A8B8G8R8);
+		PixelData src(getProperties().getWidth(), getProperties().getHeight(), 1, PF_A8B8G8R8);
 		src.setExternalBuffer((UINT8*)mappedTex2D.pData);
 		src.setExternalBuffer((UINT8*)mappedTex2D.pData);
 		PixelUtil::bulkPixelConversion(src, dst);
 		PixelUtil::bulkPixelConversion(src, dst);
 
 
@@ -547,27 +554,7 @@ namespace BansheeEngine
 		SAFE_RELEASE(backbuffer);
 		SAFE_RELEASE(backbuffer);
 	}
 	}
 
 
-	Vector2I D3D11RenderWindow::screenToWindowPos(const Vector2I& screenPos) const
-	{
-		POINT pos;
-		pos.x = screenPos.x;
-		pos.y = screenPos.y;
-
-		ScreenToClient(mHWnd, &pos);
-		return Vector2I(pos.x, pos.y);
-	}
-
-	Vector2I D3D11RenderWindow::windowToScreenPos(const Vector2I& windowPos) const
-	{
-		POINT pos;
-		pos.x = windowPos.x;
-		pos.y = windowPos.y;
-
-		ClientToScreen(mHWnd, &pos);
-		return Vector2I(pos.x, pos.y);
-	}
-
-	void D3D11RenderWindow::_windowMovedOrResized()
+	void D3D11RenderWindowCore::_windowMovedOrResized()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -576,8 +563,11 @@ namespace BansheeEngine
 
 
 		RECT rc;
 		RECT rc;
 		GetWindowRect(mHWnd, &rc);
 		GetWindowRect(mHWnd, &rc);
-		mTop = rc.top;
-		mLeft = rc.left;
+
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
+		properties->mTop = rc.top;
+		properties->mLeft = rc.left;
+		markCoreDirty();
 
 
 		GetClientRect(mHWnd, &rc);
 		GetClientRect(mHWnd, &rc);
 		unsigned int width = rc.right - rc.left;
 		unsigned int width = rc.right - rc.left;
@@ -591,10 +581,10 @@ namespace BansheeEngine
 
 
 		resizeSwapChainBuffers(width, height);
 		resizeSwapChainBuffers(width, height);
 
 
-		RenderWindow::_windowMovedOrResized();
+		RenderWindowCore::_windowMovedOrResized();
 	}
 	}
 
 
-	void D3D11RenderWindow::createSwapChain()
+	void D3D11RenderWindowCore::createSwapChain()
 	{
 	{
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 
 
@@ -603,11 +593,11 @@ namespace BansheeEngine
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 		DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
 		DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
 		mSwapChainDesc.OutputWindow	= mHWnd;
 		mSwapChainDesc.OutputWindow	= mHWnd;
-		mSwapChainDesc.BufferDesc.Width = mWidth;
-		mSwapChainDesc.BufferDesc.Height = mHeight;
+		mSwapChainDesc.BufferDesc.Width = getProperties().getWidth();
+		mSwapChainDesc.BufferDesc.Height = getProperties().getHeight();
 		mSwapChainDesc.BufferDesc.Format = format;
 		mSwapChainDesc.BufferDesc.Format = format;
 
 
-		if (mIsFullScreen)
+		if (getProperties().isFullScreen())
 		{
 		{
 			mSwapChainDesc.BufferDesc.RefreshRate.Numerator = mRefreshRateNumerator;
 			mSwapChainDesc.BufferDesc.RefreshRate.Numerator = mRefreshRateNumerator;
 			mSwapChainDesc.BufferDesc.RefreshRate.Denominator = mRefreshRateDenominator;
 			mSwapChainDesc.BufferDesc.RefreshRate.Denominator = mRefreshRateDenominator;
@@ -629,7 +619,7 @@ namespace BansheeEngine
 		mSwapChainDesc.Windowed	= true;
 		mSwapChainDesc.Windowed	= true;
 
 
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
-		rs->determineMultisampleSettings(mMultisampleCount, mMultisampleHint, format, &mMultisampleType);
+		rs->determineMultisampleSettings(getProperties().getMultisampleCount(), getProperties().getMultisampleHint(), format, &mMultisampleType);
 		mSwapChainDesc.SampleDesc.Count = mMultisampleType.Count;
 		mSwapChainDesc.SampleDesc.Count = mMultisampleType.Count;
 		mSwapChainDesc.SampleDesc.Quality = mMultisampleType.Quality;
 		mSwapChainDesc.SampleDesc.Quality = mMultisampleType.Quality;
 		
 		
@@ -653,7 +643,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_SwapChain);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_SwapChain);
 	}
 	}
 
 
-	void D3D11RenderWindow::createSizeDependedD3DResources()
+	void D3D11RenderWindowCore::createSizeDependedD3DResources()
 	{
 	{
 		SAFE_RELEASE(mBackBuffer);
 		SAFE_RELEASE(mBackBuffer);
 
 
@@ -670,7 +660,7 @@ namespace BansheeEngine
 		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
 		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
 
 
 		RTVDesc.Format = BBDesc.Format;
 		RTVDesc.Format = BBDesc.Format;
-		RTVDesc.ViewDimension = mMultisampleCount ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
+		RTVDesc.ViewDimension = getProperties().getMultisampleCount() ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
 		RTVDesc.Texture2D.MipSlice = 0;
 		RTVDesc.Texture2D.MipSlice = 0;
 		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
 		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
 
 
@@ -681,7 +671,8 @@ namespace BansheeEngine
 		}
 		}
 
 
 		mDepthStencilBuffer = TextureManager::instance().createTexture(TEX_TYPE_2D, 
 		mDepthStencilBuffer = TextureManager::instance().createTexture(TEX_TYPE_2D, 
-			BBDesc.Width, BBDesc.Height, 0, PF_D24S8, TU_DEPTHSTENCIL, false, mMultisampleCount, mMultisampleHint);
+			BBDesc.Width, BBDesc.Height, 0, PF_D24S8, TU_DEPTHSTENCIL, false, 
+			getProperties().getMultisampleCount(), getProperties().getMultisampleHint());
 
 
 		if(mDepthStencilView != nullptr)
 		if(mDepthStencilView != nullptr)
 		{
 		{
@@ -692,7 +683,7 @@ namespace BansheeEngine
 		mDepthStencilView = Texture::requestView(mDepthStencilBuffer, 0, 1, 0, 1, GVU_DEPTHSTENCIL);
 		mDepthStencilView = Texture::requestView(mDepthStencilBuffer, 0, 1, 0, 1, GVU_DEPTHSTENCIL);
 	}
 	}
 
 
-	void D3D11RenderWindow::destroySizeDependedD3DResources()
+	void D3D11RenderWindowCore::destroySizeDependedD3DResources()
 	{
 	{
 		SAFE_RELEASE(mBackBuffer);
 		SAFE_RELEASE(mBackBuffer);
 		SAFE_RELEASE(mRenderTargetView);
 		SAFE_RELEASE(mRenderTargetView);
@@ -700,27 +691,29 @@ namespace BansheeEngine
 		mDepthStencilBuffer = nullptr;
 		mDepthStencilBuffer = nullptr;
 	}
 	}
 
 
-	void D3D11RenderWindow::resizeSwapChainBuffers(UINT32 width, UINT32 height)
+	void D3D11RenderWindowCore::resizeSwapChainBuffers(UINT32 width, UINT32 height)
 	{
 	{
 		destroySizeDependedD3DResources();
 		destroySizeDependedD3DResources();
 
 
-		UINT Flags = mIsFullScreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
+		UINT Flags = getProperties().isFullScreen() ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
 		HRESULT hr = mSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags);
 		HRESULT hr = mSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags);
 
 
 		if(hr != S_OK)
 		if(hr != S_OK)
 			BS_EXCEPT(InternalErrorException, "Call to ResizeBuffers failed.");
 			BS_EXCEPT(InternalErrorException, "Call to ResizeBuffers failed.");
 
 
+		D3D11RenderWindowProperties* properties = static_cast<D3D11RenderWindowProperties*>(mProperties);
 		mSwapChain->GetDesc(&mSwapChainDesc);
 		mSwapChain->GetDesc(&mSwapChainDesc);
-		mWidth = mSwapChainDesc.BufferDesc.Width;
-		mHeight = mSwapChainDesc.BufferDesc.Height;
-		mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state
+		properties->mWidth = mSwapChainDesc.BufferDesc.Width;
+		properties->mHeight = mSwapChainDesc.BufferDesc.Height;
+		properties->mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state
+		markCoreDirty();
 
 
 		createSizeDependedD3DResources();
 		createSizeDependedD3DResources();
 
 
 		mDevice.getImmediateContext()->OMSetRenderTargets(0, 0, 0);
 		mDevice.getImmediateContext()->OMSetRenderTargets(0, 0, 0);
 	}
 	}
 
 
-	IDXGIDevice* D3D11RenderWindow::queryDxgiDevice()
+	IDXGIDevice* D3D11RenderWindowCore::queryDxgiDevice()
 	{
 	{
 		if (mDevice.getD3D11Device() == nullptr)
 		if (mDevice.getD3D11Device() == nullptr)
 		{
 		{
@@ -735,4 +728,61 @@ namespace BansheeEngine
 
 
 		return pDXGIDevice;
 		return pDXGIDevice;
 	}
 	}
+
+	D3D11RenderWindow::D3D11RenderWindow(D3D11Device& device, IDXGIFactory* DXGIFactory)
+		:mDevice(device), mDXGIFactory(DXGIFactory), mHWnd(0)
+	{
+
+	}
+
+	void D3D11RenderWindow::getCustomAttribute(const String& name, void* pData) const
+	{
+		THROW_IF_CORE_THREAD;
+
+		if (name == "WINDOW")
+		{
+			HWND *pWnd = (HWND*)pData;
+			*pWnd = mHWnd;
+			return;
+		}
+
+		RenderWindow::getCustomAttribute(name, pData);
+	}
+
+	Vector2I D3D11RenderWindow::screenToWindowPos(const Vector2I& screenPos) const
+	{
+		POINT pos;
+		pos.x = screenPos.x;
+		pos.y = screenPos.y;
+
+		ScreenToClient(mHWnd, &pos);
+		return Vector2I(pos.x, pos.y);
+	}
+
+	Vector2I D3D11RenderWindow::windowToScreenPos(const Vector2I& windowPos) const
+	{
+		POINT pos;
+		pos.x = windowPos.x;
+		pos.y = windowPos.y;
+
+		ClientToScreen(mHWnd, &pos);
+		return Vector2I(pos.x, pos.y);
+	}
+
+	void D3D11RenderWindow::initialize_internal()
+	{
+		RenderWindow::initialize_internal();
+
+		mCore->getCustomAttribute("WINDOW", (void*)&mHWnd);
+	}
+
+	RenderTargetProperties* D3D11RenderWindow::createProperties() const
+	{
+		return bs_new<RenderWindowProperties>();
+	}
+
+	RenderWindowCore* D3D11RenderWindow::createCore(RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc)
+	{
+		return bs_new<D3D11RenderWindowCore>(this, properties, desc, mDevice, mDXGIFactory);
+	}
 }
 }

+ 1 - 1
BansheeD3D11RenderSystem/Source/BsD3D11RenderWindowManager.cpp

@@ -24,7 +24,7 @@ namespace BansheeEngine
 		}
 		}
 
 
 		// Create the window
 		// Create the window
-		D3D11RenderWindow* renderWindow = new (bs_alloc<D3D11RenderWindow, PoolAlloc>()) D3D11RenderWindow(desc, d3d11rs->getPrimaryDevice(), d3d11rs->getDXGIFactory());
+		D3D11RenderWindow* renderWindow = new (bs_alloc<D3D11RenderWindow, PoolAlloc>()) D3D11RenderWindow(d3d11rs->getPrimaryDevice(), d3d11rs->getDXGIFactory());
 		return bs_core_ptr<D3D11RenderWindow, PoolAlloc>(renderWindow);
 		return bs_core_ptr<D3D11RenderWindow, PoolAlloc>(renderWindow);
 	}
 	}
 }
 }

+ 18 - 18
BansheeD3D9RenderSystem/Include/BsD3D9Device.h

@@ -35,12 +35,12 @@ namespace BansheeEngine
 		 * @brief	Attaches a new render window to this device. Caller must ensure
 		 * @brief	Attaches a new render window to this device. Caller must ensure
 		 *			the window is not attached to multiple devices.
 		 *			the window is not attached to multiple devices.
 		 */
 		 */
-		void attachRenderWindow(const D3D9RenderWindow* renderWindow);
+		void attachRenderWindow(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Detaches the render window from this device.
 		 * @brief	Detaches the render window from this device.
 		 */
 		 */
-		void detachRenderWindow(const D3D9RenderWindow* renderWindow);
+		void detachRenderWindow(const D3D9RenderWindowCore* renderWindow);
 	
 	
 		/**
 		/**
 		 * @brief	Acquires the device. This will cause a device reset in case present parameters changed.
 		 * @brief	Acquires the device. This will cause a device reset in case present parameters changed.
@@ -106,37 +106,37 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Validates that the window is valid for this device. Will reset device if needed.
 		 * @brief	Validates that the window is valid for this device. Will reset device if needed.
 		 */
 		 */
-		bool validate(D3D9RenderWindow* renderWindow);
+		bool validate(D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Invalidates the window so on the next call to validate, the device will be re-acquired.
 		 * @brief	Invalidates the window so on the next call to validate, the device will be re-acquired.
 		 */
 		 */
-		void invalidate(const D3D9RenderWindow* renderWindow);
+		void invalidate(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Swap back and front buffers for the specified window.
 		 * @brief	Swap back and front buffers for the specified window.
 		 */
 		 */
-		void present(const D3D9RenderWindow* renderWindow);
+		void present(const D3D9RenderWindowCore* renderWindow);
 		
 		
 		/**
 		/**
 		 * @brief	Returns internal DX9 represention of the depth/stencil buffer.
 		 * @brief	Returns internal DX9 represention of the depth/stencil buffer.
 		 */
 		 */
-		IDirect3DSurface9* getDepthBuffer(const D3D9RenderWindow* renderWindow);
+		IDirect3DSurface9* getDepthBuffer(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Returns internal DX9 represention of the backbuffer.
 		 * @brief	Returns internal DX9 represention of the backbuffer.
 		 */
 		 */
-		IDirect3DSurface9* getBackBuffer(const D3D9RenderWindow* renderWindow);
+		IDirect3DSurface9* getBackBuffer(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Sets adapter index for the specified window.
 		 * @brief	Sets adapter index for the specified window.
 		 */
 		 */
-		void setAdapterOrdinalIndex(const D3D9RenderWindow* renderWindow, UINT32 adapterOrdinalInGroupIndex);
+		void setAdapterOrdinalIndex(const D3D9RenderWindowCore* renderWindow, UINT32 adapterOrdinalInGroupIndex);
 
 
 		/**
 		/**
 		 * @brief	Copies contents of the back or depth/stencil buffer in to the provided object.
 		 * @brief	Copies contents of the back or depth/stencil buffer in to the provided object.
 		 */
 		 */
-		void copyContentsToMemory(const D3D9RenderWindow* window, PixelData &dst, RenderTarget::FrameBuffer buffer);
+		void copyContentsToMemory(const D3D9RenderWindowCore* window, PixelData &dst, RenderTargetCore::FrameBuffer buffer);
 
 
 		/**
 		/**
 		 * @brief	Resets bound pipeline states/streams to null.
 		 * @brief	Resets bound pipeline states/streams to null.
@@ -147,18 +147,18 @@ namespace BansheeEngine
 		friend class D3D9DeviceManager;
 		friend class D3D9DeviceManager;
 		friend class D3D9RenderSystem;
 		friend class D3D9RenderSystem;
 
 
-		typedef Map<const D3D9RenderWindow*, RenderWindowResources*> RenderWindowToResorucesMap;
-		typedef RenderWindowToResorucesMap::iterator				 RenderWindowToResorucesIterator;
+		typedef Map<const D3D9RenderWindowCore*, RenderWindowResources*> RenderWindowToResorucesMap;
+		typedef RenderWindowToResorucesMap::iterator RenderWindowToResorucesIterator;
 
 
 		/**
 		/**
 		 * @brief	Find iterator for the specified window in the render window resource list.
 		 * @brief	Find iterator for the specified window in the render window resource list.
 		 */
 		 */
-		RenderWindowToResorucesIterator getRenderWindowIterator(const D3D9RenderWindow* renderWindow);
+		RenderWindowToResorucesIterator getRenderWindowIterator(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Acquires the device for the provided render window.
 		 * @brief	Acquires the device for the provided render window.
 		 */
 		 */
-		bool acquire(const D3D9RenderWindow* renderWindow);
+		bool acquire(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Forcibly reset the device.
 		 * @brief	Forcibly reset the device.
@@ -209,27 +209,27 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Checks if back buffer size has changed and invalidates the window if it has.
 		 * @brief	Checks if back buffer size has changed and invalidates the window if it has.
 		 */
 		 */
-		void validateBackBufferSize(const D3D9RenderWindow* renderWindow);
+		void validateBackBufferSize(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Checks if window monitor changed and re-links the window if needed.
 		 * @brief	Checks if window monitor changed and re-links the window if needed.
 		 */
 		 */
-		bool validateDisplayMonitor(D3D9RenderWindow* renderWindow);
+		bool validateDisplayMonitor(D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Checks if device has been lost or active window invalidated and acquires the device if needed.
 		 * @brief	Checks if device has been lost or active window invalidated and acquires the device if needed.
 		 */
 		 */
-		bool validateDeviceState(const D3D9RenderWindow* renderWindow);
+		bool validateDeviceState(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Checks if the render window contains a custom swap chain.
 		 * @brief	Checks if the render window contains a custom swap chain.
 		 */
 		 */
-		bool isSwapChainWindow(const D3D9RenderWindow* renderWindow);
+		bool isSwapChainWindow(const D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Returns primary window for this device.
 		 * @brief	Returns primary window for this device.
 		 */
 		 */
-		const D3D9RenderWindow*	getPrimaryWindow();
+		const D3D9RenderWindowCore*	getPrimaryWindow();
 
 
 		/**
 		/**
 		 * @brief	Sets the shared window handle.
 		 * @brief	Sets the shared window handle.

+ 3 - 3
BansheeD3D9RenderSystem/Include/BsD3D9DeviceManager.h

@@ -49,7 +49,7 @@ namespace BansheeEngine
 		 *			assigned an existing device if a match one can be found, otherwise
 		 *			assigned an existing device if a match one can be found, otherwise
 		 *			a new device will be created.
 		 *			a new device will be created.
 		 */
 		 */
-		void linkRenderWindow(D3D9RenderWindow* renderWindow);
+		void linkRenderWindow(D3D9RenderWindowCore* renderWindow);
 
 
 		/**
 		/**
 		 * @brief	Called by the devices when they're are being destroyed.
 		 * @brief	Called by the devices when they're are being destroyed.
@@ -67,12 +67,12 @@ namespace BansheeEngine
 		 *			new device is created. Found/created device is returned, as well as a list of all render windows
 		 *			new device is created. Found/created device is returned, as well as a list of all render windows
 		 *			using that device.
 		 *			using that device.
 		 */
 		 */
-		D3D9Device*	selectDevice(D3D9RenderWindow* renderWindow, Vector<D3D9RenderWindow*>& renderWindowsGroup);
+		D3D9Device*	selectDevice(D3D9RenderWindowCore* renderWindow, Vector<D3D9RenderWindowCore*>& renderWindowsGroup);
 
 
 		/**
 		/**
 		 * @brief	Finds the driver the render window belongs to.
 		 * @brief	Finds the driver the render window belongs to.
 		 */
 		 */
-		D3D9Driver*	findDriver(D3D9RenderWindow* renderWindow);
+		D3D9Driver*	findDriver(D3D9RenderWindowCore* renderWindow);
 
 
 		Vector<D3D9Device*> mRenderDevices;
 		Vector<D3D9Device*> mRenderDevices;
 		D3D9Device*	mActiveDevice;
 		D3D9Device*	mActiveDevice;

+ 33 - 14
BansheeD3D9RenderSystem/Include/BsD3D9MultiRenderTexture.h

@@ -5,35 +5,54 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	class D3D9MultiRenderTexture;
+
 	/**
 	/**
 	 * @brief	DirectX 9 implementation of a render texture with multiple color surfaces.
 	 * @brief	DirectX 9 implementation of a render texture with multiple color surfaces.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-	class BS_D3D9_EXPORT D3D9MultiRenderTexture : public MultiRenderTexture
+	class BS_D3D9_EXPORT D3D9MultiRenderTextureCore : public MultiRenderTextureCore
 	{
 	{
 	public:
 	public:
-		virtual ~D3D9MultiRenderTexture();
-
-		/**
-		 * @copydoc	MultiRenderTexture::requiresTextureFlipping
-		 */
-		bool requiresTextureFlipping() const { return false; }
-
+		D3D9MultiRenderTextureCore(D3D9MultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc);
+		virtual ~D3D9MultiRenderTextureCore();
+		
 		/**
 		/**
-		 * @copydoc	MultiRenderTexture::getCustomAttribute
+		 * @copydoc	MultiRenderTextureCore::getCustomAttribute
 		 */
 		 */
 		void getCustomAttribute(const String& name, void* pData) const;
 		void getCustomAttribute(const String& name, void* pData) const;
 
 
+	protected:
+		friend class D3D9MultiRenderTexture;
+
+		Vector<IDirect3DSurface9*> mDX9ColorSurfaces;
+		IDirect3DSurface9* mDX9DepthStencilSurface;
+	};
+
+	/**
+	 * @brief	DirectX 9 implementation of a render texture with multiple color surfaces.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_D3D9_EXPORT D3D9MultiRenderTexture : public MultiRenderTexture
+	{
+	public:
+		virtual ~D3D9MultiRenderTexture() { }
+
 	protected:
 	protected:
 		friend class D3D9TextureManager;
 		friend class D3D9TextureManager;
 
 
-		D3D9MultiRenderTexture();
+		D3D9MultiRenderTexture() { }
 
 
 		/**
 		/**
-		 * @copydoc MultiRenderTexture::initialize_internal().
+		 * @copydoc	MultiRenderTexture::createProperties
 		 */
 		 */
-		void initialize_internal();
+		virtual RenderTargetProperties* createProperties() const;
 
 
-		Vector<IDirect3DSurface9*> mDX9ColorSurfaces;
-		IDirect3DSurface9* mDX9DepthStencilSurface;
+		/**
+		 * @copydoc	MultiRenderTexture::createCore
+		 */
+		virtual MultiRenderTextureCore* createCore(MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc);
 	};
 	};
 }
 }

+ 1 - 0
BansheeD3D9RenderSystem/Include/BsD3D9Prerequisites.h

@@ -28,6 +28,7 @@ namespace BansheeEngine
 	// Predefine classes
 	// Predefine classes
 	class D3D9RenderSystem;
 	class D3D9RenderSystem;
 	class D3D9RenderWindow;
 	class D3D9RenderWindow;
+	class D3D9RenderWindowCore;
 	class D3D9Texture;
 	class D3D9Texture;
 	class D3D9TextureManager;
 	class D3D9TextureManager;
 	class D3D9Driver;
 	class D3D9Driver;

+ 1 - 1
BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h

@@ -219,7 +219,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Register a newly open window with the render system.
 		 * @brief	Register a newly open window with the render system.
 		 */
 		 */
-		void registerWindow(RenderWindow& renderWindow);
+		void registerWindow(RenderWindowCore& renderWindow);
 
 
 	private:
 	private:
 		friend class D3D9Texture;
 		friend class D3D9Texture;

+ 37 - 15
BansheeD3D9RenderSystem/Include/BsD3D9RenderTexture.h

@@ -6,21 +6,23 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	class D3D9RenderTexture;
+
 	/**
 	/**
 	 * @brief	DirectX 9 implementation of a render texture.
 	 * @brief	DirectX 9 implementation of a render texture.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-	class BS_D3D9_EXPORT D3D9RenderTexture : public RenderTexture, public D3D9Resource
+	class BS_D3D9_EXPORT D3D9RenderTextureCore : public RenderTextureCore, public D3D9Resource
 	{
 	{
 	public:
 	public:
-		virtual ~D3D9RenderTexture();
+		D3D9RenderTextureCore(D3D9RenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc);
 
 
-		/**
-		 * @copydoc	RenderTexture::requiresTextureFlipping
-		 */
-		virtual bool requiresTextureFlipping() const { return false; }
+		virtual ~D3D9RenderTextureCore();
 
 
 		/**
 		/**
-		 * @copydoc	RenderTexture::getCustomAttribute
+		 * @copydoc	RenderTextureCore::getCustomAttribute
 		 */
 		 */
 		virtual void getCustomAttribute(const String& name, void* pData) const;
 		virtual void getCustomAttribute(const String& name, void* pData) const;
 
 
@@ -45,14 +47,7 @@ namespace BansheeEngine
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 
 
 	protected:
 	protected:
-		friend class D3D9TextureManager;
-
-		D3D9RenderTexture();
-
-		/**
-		 * @copydoc RenderTexture::initialize_internal().
-		 */
-		void initialize_internal();
+		friend class D3D9RenderTexture;
 
 
 		/**
 		/**
 		 * @brief	Initializes the internal color and depth surfaces.
 		 * @brief	Initializes the internal color and depth surfaces.
@@ -69,4 +64,31 @@ namespace BansheeEngine
 		IDirect3DSurface9* mDX9DepthStencilSurface;
 		IDirect3DSurface9* mDX9DepthStencilSurface;
 		bool mIsBindableToShader;
 		bool mIsBindableToShader;
 	};
 	};
+
+	/**
+	* @brief	DirectX 9 implementation of a render texture.
+	*
+	* @note		Sim thread only.
+	*/
+	class BS_D3D9_EXPORT D3D9RenderTexture : public RenderTexture
+	{
+	public:
+		virtual ~D3D9RenderTexture() { }
+
+	protected:
+		friend class D3D9TextureManager;
+
+		D3D9RenderTexture() { }
+
+		/**
+		 * @copydoc	RenderTexture::createProperties
+		 */
+		virtual RenderTargetProperties* createProperties() const;
+
+		/**
+		 * @copydoc	RenderTexture::createCore
+		 */
+		virtual RenderTextureCore* createCore(RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc);
+	};
 }
 }

+ 92 - 64
BansheeD3D9RenderSystem/Include/BsD3D9RenderWindow.h

@@ -6,96 +6,79 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
+	class D3D9RenderWindow;
+
+	/**
+	 * @brief	Contains various properties that describe a render window.
+	 */
+	class BS_D3D9_EXPORT D3D9RenderWindowProperties : public RenderWindowProperties
+	{
+	public:
+		virtual ~D3D9RenderWindowProperties() { }
+
+	private:
+		friend class D3D9RenderWindowCore;
+		friend class D3D9RenderWindow;
+	};
+
 	/**
 	/**
 	 * @brief	Render window implementation for Windows.
 	 * @brief	Render window implementation for Windows.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-	class BS_D3D9_EXPORT D3D9RenderWindow : public RenderWindow
+	class BS_D3D9_EXPORT D3D9RenderWindowCore : public RenderWindowCore
 	{
 	{
 	public:
 	public:
-		~D3D9RenderWindow();
+		D3D9RenderWindowCore(D3D9RenderWindow* parent, RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc, HINSTANCE instance);
+		~D3D9RenderWindowCore();
 		
 		
 		/**
 		/**
-		 * @copydoc RenderWindow::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);
 		void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setFullscreen(const VideoMode&)
+		 * @copydoc RenderWindowCore::setFullscreen(const VideoMode&)
 		 */
 		 */
 		void setFullscreen(const VideoMode& mode);
 		void setFullscreen(const VideoMode& mode);
 
 
 		/**
 		/**
-		* @copydoc RenderWindow::setWindowed
+		* @copydoc RenderWindowCore::setWindowed
 		*/
 		*/
 		void setWindowed(UINT32 width, UINT32 height);
 		void setWindowed(UINT32 width, UINT32 height);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setHidden
+		 * @copydoc RenderWindowCore::setHidden
 		 */
 		 */
 		void setHidden(bool hidden);
 		void setHidden(bool hidden);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::isActive
-		 */
-		bool isActive() const;
-
-		/**
-		 * @copydoc RenderWindow::isVisible
-		 */
-		bool isVisible() const;
-
-		/**
-		 * @copydoc RenderWindow::isClosed
-		 */
-		bool isClosed() const { return mClosed; }
-
-		/**
-		 * @copydoc RenderWindow::isVSync
-		 */
-		bool isVSync() const { return mVSync; }
-
-		/**
-		 * @copydoc RenderWindow::move
+		 * @copydoc RenderWindowCore::move
 		 */
 		 */
 		void move(INT32 left, INT32 top);
 		void move(INT32 left, INT32 top);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::resize
+		 * @copydoc RenderWindowCore::resize
 		 */
 		 */
 		void resize(UINT32 width, UINT32 height);
 		void resize(UINT32 width, UINT32 height);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::getCustomAttribute
+		 * @copydoc RenderWindowCore::getCustomAttribute
 		 */
 		 */
 		void getCustomAttribute(const String& name, void* pData) const;
 		void getCustomAttribute(const String& name, void* pData) const;
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::copyContentsToMemory
+		 * @copydoc RenderWindowCore::copyContentsToMemory
 		 */
 		 */
 		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::requiresTextureFlipping
-		 */
-		bool requiresTextureFlipping() const { return false; }
-
-		/**
-		 * @copydoc RenderWindow::swapBuffers
+		 * @copydoc RenderWindowCore::swapBuffers
 		 */
 		 */
 		void swapBuffers();
 		void swapBuffers();
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::screenToWindowPos
-		 */
-		Vector2I screenToWindowPos(const Vector2I& screenPos) const;
-
-		/**
-		 * @copydoc RenderWindow::windowToScreenPos
-		 */
-		Vector2I windowToScreenPos(const Vector2I& windowPos) const;
-
-		/**
-		 * @copydoc RenderWindow::_windowMovedOrResized
+		 * @copydoc RenderWindowCore::_windowMovedOrResized
 		 */
 		 */
 		void _windowMovedOrResized();
 		void _windowMovedOrResized();
 
 
@@ -138,28 +121,15 @@ namespace BansheeEngine
 		 * @brief	Validate the device for this window.
 		 * @brief	Validate the device for this window.
 		 */
 		 */
 		bool _validateDevice();
 		bool _validateDevice();
-
 		
 		
 	protected:
 	protected:
-		friend class D3D9RenderWindowManager;
-
-		D3D9RenderWindow(const RENDER_WINDOW_DESC& desc, HINSTANCE instance);
+		friend class D3D9RenderWindow;
 
 
 		/**
 		/**
 		 * @brief	Updates window coordinates and size from actual values provided by Windows.
 		 * @brief	Updates window coordinates and size from actual values provided by Windows.
 		 */
 		 */
 		void updateWindowRect();
 		void updateWindowRect();
 
 
-		/**
-		 * @copydoc RenderWindow::initialize_internal().
-		 */
-		void initialize_internal();
-
-		/**
-		 * @copydoc RenderWindow::destroy_internal().
-		 */
-		void destroy_internal();
-
 		/**
 		/**
 		 * @brief	Calculates window size based on provided client area size and currently set window style. 
 		 * @brief	Calculates window size based on provided client area size and currently set window style. 
 		 */	
 		 */	
@@ -171,12 +141,10 @@ namespace BansheeEngine
 		D3D9Device* mDevice;
 		D3D9Device* mDevice;
 		bool mDeviceValid;
 		bool mDeviceValid;
 		HWND mHWnd;
 		HWND mHWnd;
-		bool mIsExternal;
-		bool mClosed;		
+		bool mIsExternal;		
 		D3DMULTISAMPLE_TYPE	mMultisampleType;
 		D3DMULTISAMPLE_TYPE	mMultisampleType;
 		DWORD mMultisampleQuality;
 		DWORD mMultisampleQuality;
 		UINT mDisplayFrequency;
 		UINT mDisplayFrequency;
-		bool mVSync;
 		unsigned int mVSyncInterval;		
 		unsigned int mVSyncInterval;		
 		DWORD mStyle;	
 		DWORD mStyle;	
 		DWORD mWindowedStyle;
 		DWORD mWindowedStyle;
@@ -184,4 +152,64 @@ namespace BansheeEngine
 		bool mIsDepthBuffered;
 		bool mIsDepthBuffered;
 		bool mIsChild;
 		bool mIsChild;
 	};
 	};
+
+	/**
+	 * @brief	Render window implementation for Windows.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_D3D9_EXPORT D3D9RenderWindow : public RenderWindow
+	{
+	public:
+		~D3D9RenderWindow() { }
+
+		/**
+		 * @copydoc RenderWindow::screenToWindowPos
+		 */
+		Vector2I screenToWindowPos(const Vector2I& screenPos) const;
+
+		/**
+		 * @copydoc RenderWindow::windowToScreenPos
+		 */
+		Vector2I windowToScreenPos(const Vector2I& windowPos) const;
+
+		/**
+		 * @copydoc RenderWindow::requiresTextureFlipping
+		 */
+		bool requiresTextureFlipping() const { return false; }
+
+		/**
+		 * @copydoc RenderWindow::getCustomAttribute
+		 */
+		void getCustomAttribute(const String& name, void* pData) const;
+
+		/**
+		 * @copydoc	RenderWindow::getCore
+		 */
+		D3D9RenderWindowCore* getCore() const;
+
+	protected:
+		friend class D3D9RenderWindowManager;
+
+		D3D9RenderWindow(HINSTANCE instance);
+
+		/**
+		 * @copydoc	RenderWindow::initialize_internal
+		 */
+		virtual void initialize_internal();
+
+		/**
+		 * @copydoc	RenderWindow::createProperties
+		 */
+		virtual RenderTargetProperties* createProperties() const;
+
+		/**
+		 * @copydoc	RenderWindow::createCore
+		 */
+		virtual RenderWindowCore* createCore(RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc);
+
+	private:
+		HINSTANCE mInstance;
+		HWND mHWnd;
+	};
 }
 }

+ 46 - 43
BansheeD3D9RenderSystem/Source/BsD3D9Device.cpp

@@ -34,7 +34,7 @@ namespace BansheeEngine
 
 
 	}
 	}
 
 
-	D3D9Device::RenderWindowToResorucesIterator D3D9Device::getRenderWindowIterator(const D3D9RenderWindow* renderWindow)
+	D3D9Device::RenderWindowToResorucesIterator D3D9Device::getRenderWindowIterator(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.find(renderWindow);
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.find(renderWindow);
 
 
@@ -44,7 +44,7 @@ namespace BansheeEngine
 		return it;
 		return it;
 	}
 	}
 
 
-	void D3D9Device::attachRenderWindow(const D3D9RenderWindow* renderWindow)
+	void D3D9Device::attachRenderWindow(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.find(renderWindow);
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.find(renderWindow);
 
 
@@ -61,7 +61,7 @@ namespace BansheeEngine
 		updateRenderWindowsIndices();
 		updateRenderWindowsIndices();
 	}
 	}
 
 
-	void D3D9Device::detachRenderWindow(const D3D9RenderWindow* renderWindow)
+	void D3D9Device::detachRenderWindow(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.find(renderWindow);
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.find(renderWindow);
 
 
@@ -175,7 +175,7 @@ namespace BansheeEngine
 		}				
 		}				
 	}
 	}
 
 
-	bool D3D9Device::acquire(const D3D9RenderWindow* renderWindow)
+	bool D3D9Device::acquire(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		
 		
@@ -197,21 +197,21 @@ namespace BansheeEngine
 		renderSystem->notifyOnDeviceLost(this);
 		renderSystem->notifyOnDeviceLost(this);
 	}	
 	}	
 
 
-	IDirect3DSurface9* D3D9Device::getDepthBuffer(const D3D9RenderWindow* renderWindow)
+	IDirect3DSurface9* D3D9Device::getDepthBuffer(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);		
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);		
 
 
 		return it->second->depthBuffer;
 		return it->second->depthBuffer;
 	}
 	}
 
 
-	IDirect3DSurface9* D3D9Device::getBackBuffer(const D3D9RenderWindow* renderWindow)
+	IDirect3DSurface9* D3D9Device::getBackBuffer(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 	
 	
 		return it->second->backBuffer;		
 		return it->second->backBuffer;		
 	}
 	}
 
 
-	void D3D9Device::setAdapterOrdinalIndex(const D3D9RenderWindow* renderWindow, UINT32 adapterOrdinalInGroupIndex)
+	void D3D9Device::setAdapterOrdinalIndex(const D3D9RenderWindowCore* renderWindow, UINT32 adapterOrdinalInGroupIndex)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 
 
@@ -426,18 +426,18 @@ namespace BansheeEngine
 
 
 			while (it != mMapRenderWindowToResoruces.end())
 			while (it != mMapRenderWindowToResoruces.end())
 			{
 			{
-				const D3D9RenderWindow* renderWindow = it->first;
+				const D3D9RenderWindowCore* renderWindow = it->first;
 				RenderWindowResources* renderWindowResources = it->second;
 				RenderWindowResources* renderWindowResources = it->second;
 
 
 				// Ask the render window to build it's own parameters.
 				// Ask the render window to build it's own parameters.
 				renderWindow->_buildPresentParameters(&renderWindowResources->presentParameters);
 				renderWindow->_buildPresentParameters(&renderWindowResources->presentParameters);
 				
 				
 				// Update shared focus window handle.
 				// Update shared focus window handle.
-				if (renderWindow->isFullScreen() && renderWindowResources->presentParametersIndex == 0 && msSharedFocusWindow == NULL)
+				if (renderWindow->getProperties().isFullScreen() && renderWindowResources->presentParametersIndex == 0 && msSharedFocusWindow == NULL)
 					setSharedWindowHandle(renderWindow->_getWindowHandle());					
 					setSharedWindowHandle(renderWindow->_getWindowHandle());					
 
 
 				// This is the primary window or a full screen window that is part of multi head device.
 				// This is the primary window or a full screen window that is part of multi head device.
-				if (renderWindowResources->presentParametersIndex == 0 || renderWindow->isFullScreen())
+				if (renderWindowResources->presentParametersIndex == 0 || renderWindow->getProperties().isFullScreen())
 				{
 				{
 					mPresentationParams[renderWindowResources->presentParametersIndex] = renderWindowResources->presentParameters;
 					mPresentationParams[renderWindowResources->presentParametersIndex] = renderWindowResources->presentParameters;
 					mPresentationParamsCount++;
 					mPresentationParamsCount++;
@@ -473,7 +473,7 @@ namespace BansheeEngine
 		{
 		{
 			RenderWindowResources* renderWindowResources = resourceData.second;
 			RenderWindowResources* renderWindowResources = resourceData.second;
 
 
-			if (renderWindowResources->adapterOrdinalInGroupIndex > 0 && resourceData.first->isFullScreen())
+			if (renderWindowResources->adapterOrdinalInGroupIndex > 0 && resourceData.first->getProperties().isFullScreen())
 				return true;
 				return true;
 		}
 		}
 
 
@@ -525,7 +525,7 @@ namespace BansheeEngine
 	void D3D9Device::createD3D9Device()
 	void D3D9Device::createD3D9Device()
 	{		
 	{		
 		// Update focus window.
 		// Update focus window.
-		const D3D9RenderWindow* primaryRenderWindow = getPrimaryWindow();
+		const D3D9RenderWindowCore* primaryRenderWindow = getPrimaryWindow();
 
 
 		// Case we have to share the same focus window.
 		// Case we have to share the same focus window.
 		if (msSharedFocusWindow != NULL)
 		if (msSharedFocusWindow != NULL)
@@ -655,14 +655,14 @@ namespace BansheeEngine
 		renderWindowResources->acquired = false;
 		renderWindowResources->acquired = false;
 	}
 	}
 
 
-	void D3D9Device::invalidate(const D3D9RenderWindow* renderWindow)
+	void D3D9Device::invalidate(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 
 
 		it->second->acquired = false;		
 		it->second->acquired = false;		
 	}
 	}
 
 
-	bool D3D9Device::validate(D3D9RenderWindow* renderWindow)
+	bool D3D9Device::validate(D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		// Validate that the render window should run on this device.
 		// Validate that the render window should run on this device.
 		if (!validateDisplayMonitor(renderWindow))
 		if (!validateDisplayMonitor(renderWindow))
@@ -698,7 +698,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	bool D3D9Device::validateDeviceState(const D3D9RenderWindow* renderWindow)
+	bool D3D9Device::validateDeviceState(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);		
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);		
 		RenderWindowResources* renderWindowResources =  it->second;
 		RenderWindowResources* renderWindowResources =  it->second;
@@ -759,31 +759,33 @@ namespace BansheeEngine
 		return true;
 		return true;
 	}
 	}
 		
 		
-	void D3D9Device::validateBackBufferSize(const D3D9RenderWindow* renderWindow)
+	void D3D9Device::validateBackBufferSize(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowResources*	renderWindowResources = it->second;
 		RenderWindowResources*	renderWindowResources = it->second;
 	
 	
+		const RenderWindowProperties& props = renderWindow->getProperties();
+
 		// Case size has been changed.
 		// Case size has been changed.
-		if (renderWindow->getWidth() != renderWindowResources->presentParameters.BackBufferWidth ||
-			renderWindow->getHeight() != renderWindowResources->presentParameters.BackBufferHeight)
+		if (props.getWidth() != renderWindowResources->presentParameters.BackBufferWidth ||
+			props.getHeight() != renderWindowResources->presentParameters.BackBufferHeight)
 		{			
 		{			
-			if (renderWindow->getWidth() > 0)
-				renderWindowResources->presentParameters.BackBufferWidth = renderWindow->getWidth();
+			if (props.getWidth() > 0)
+				renderWindowResources->presentParameters.BackBufferWidth = props.getWidth();
 
 
-			if (renderWindow->getHeight() > 0)
-				renderWindowResources->presentParameters.BackBufferHeight = renderWindow->getHeight();
+			if (props.getHeight() > 0)
+				renderWindowResources->presentParameters.BackBufferHeight = props.getHeight();
 
 
 			invalidate(renderWindow);
 			invalidate(renderWindow);
 		}				
 		}				
 	}
 	}
 
 
-	bool D3D9Device::validateDisplayMonitor(D3D9RenderWindow* renderWindow)
+	bool D3D9Device::validateDisplayMonitor(D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		// Ignore full screen since it doesn't really move and it is possible 
 		// Ignore full screen since it doesn't really move and it is possible 
 		// that it created using multi-head adapter so for a subordinate the
 		// that it created using multi-head adapter so for a subordinate the
 		// native monitor handle and this device handle will be different.
 		// native monitor handle and this device handle will be different.
-		if (renderWindow->isFullScreen())
+		if (renderWindow->getProperties().isFullScreen())
 			return true;
 			return true;
 
 
 		HMONITOR	hRenderWindowMonitor = NULL;
 		HMONITOR	hRenderWindowMonitor = NULL;
@@ -813,7 +815,7 @@ namespace BansheeEngine
 		return true;
 		return true;
 	}
 	}
 
 
-	void D3D9Device::present(const D3D9RenderWindow* renderWindow)
+	void D3D9Device::present(const D3D9RenderWindowCore* renderWindow)
 	{		
 	{		
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowResources*	renderWindowResources = it->second;				
 		RenderWindowResources*	renderWindowResources = it->second;				
@@ -856,7 +858,7 @@ namespace BansheeEngine
 	void D3D9Device::acquireRenderWindowResources(RenderWindowToResorucesIterator it)
 	void D3D9Device::acquireRenderWindowResources(RenderWindowToResorucesIterator it)
 	{
 	{
 		RenderWindowResources*	renderWindowResources = it->second;
 		RenderWindowResources*	renderWindowResources = it->second;
-		const D3D9RenderWindow*	renderWindow = it->first;			
+		const D3D9RenderWindowCore*	renderWindow = it->first;
 		
 		
 		releaseRenderWindowResources(renderWindowResources);
 		releaseRenderWindowResources(renderWindowResources);
 
 
@@ -909,8 +911,8 @@ namespace BansheeEngine
 			}
 			}
 			else
 			else
 			{
 			{
-				UINT32 targetWidth  = renderWindow->getWidth();
-				UINT32 targetHeight = renderWindow->getHeight();
+				UINT32 targetWidth  = renderWindow->getProperties().getWidth();
+				UINT32 targetHeight = renderWindow->getProperties().getHeight();
 
 
 				if (targetWidth == 0)
 				if (targetWidth == 0)
 					targetWidth = 1;
 					targetWidth = 1;
@@ -942,17 +944,17 @@ namespace BansheeEngine
 		renderWindowResources->acquired = true; 
 		renderWindowResources->acquired = true; 
 	}
 	}
 
 
-	bool D3D9Device::isSwapChainWindow(const D3D9RenderWindow* renderWindow)
+	bool D3D9Device::isSwapChainWindow(const D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		
 		
-		if (it->second->presentParametersIndex == 0 || renderWindow->isFullScreen())			
+		if (it->second->presentParametersIndex == 0 || renderWindow->getProperties().isFullScreen())			
 			return false;
 			return false;
 			
 			
 		return true;
 		return true;
 	}
 	}
 
 
-	const D3D9RenderWindow* D3D9Device::getPrimaryWindow()
+	const D3D9RenderWindowCore* D3D9Device::getPrimaryWindow()
 	{		
 	{		
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
 		RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
 	
 	
@@ -996,7 +998,7 @@ namespace BansheeEngine
 			UINT32 nextPresParamIndex = 0;
 			UINT32 nextPresParamIndex = 0;
 
 
 			RenderWindowToResorucesIterator it;
 			RenderWindowToResorucesIterator it;
-			const D3D9RenderWindow* deviceFocusWindow = NULL;
+			const D3D9RenderWindowCore* deviceFocusWindow = NULL;
 
 
 			// In case a d3d9 device exists - try to keep the present parameters order
 			// In case a d3d9 device exists - try to keep the present parameters order
 			// so that the window that the device is focused on will stay the same and we
 			// so that the window that the device is focused on will stay the same and we
@@ -1032,15 +1034,17 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D9Device::copyContentsToMemory(const D3D9RenderWindow* renderWindow, 
-		PixelData &dst, RenderTarget::FrameBuffer buffer)
+	void D3D9Device::copyContentsToMemory(const D3D9RenderWindowCore* renderWindow,
+		PixelData &dst, RenderTargetCore::FrameBuffer buffer)
 	{
 	{
+		const RenderWindowProperties& props = renderWindow->getProperties();
+
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 		RenderWindowResources* resources = it->second;
 		RenderWindowResources* resources = it->second;
 		bool swapChain = isSwapChainWindow(renderWindow);
 		bool swapChain = isSwapChainWindow(renderWindow);
 
 
-		if ((dst.getLeft() < 0) || (dst.getRight() > renderWindow->getWidth()) ||
-			(dst.getTop() < 0) || (dst.getBottom() > renderWindow->getHeight()) ||
+		if ((dst.getLeft() < 0) || (dst.getRight() > props.getWidth()) ||
+			(dst.getTop() < 0) || (dst.getBottom() > props.getHeight()) ||
 			(dst.getFront() != 0) || (dst.getBack() != 1))
 			(dst.getFront() != 0) || (dst.getBack() != 1))
 		{
 		{
 			BS_EXCEPT(InvalidParametersException, "Invalid box.");
 			BS_EXCEPT(InvalidParametersException, "Invalid box.");
@@ -1053,13 +1057,12 @@ namespace BansheeEngine
 		D3DLOCKED_RECT lockedRect;
 		D3DLOCKED_RECT lockedRect;
 
 
 
 
-		if (buffer == RenderTarget::FB_AUTO)
+		if (buffer == RenderTargetCore::FB_AUTO)
 		{
 		{
-			//buffer = mIsFullScreen? FB_FRONT : FB_BACK;
-			buffer = RenderTarget::FB_FRONT;
+			buffer = RenderTargetCore::FB_FRONT;
 		}
 		}
 
 
-		if (buffer == RenderTarget::FB_FRONT)
+		if (buffer == RenderTargetCore::FB_FRONT)
 		{
 		{
 			D3DDISPLAYMODE dm;
 			D3DDISPLAYMODE dm;
 
 
@@ -1087,9 +1090,9 @@ namespace BansheeEngine
 				BS_EXCEPT(RenderingAPIException, "Can't get front buffer: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
 				BS_EXCEPT(RenderingAPIException, "Can't get front buffer: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
 			}
 			}
 
 
-			if(renderWindow->isFullScreen())
+			if (props.isFullScreen())
 			{
 			{
-				if ((dst.getLeft() == 0) && (dst.getRight() == renderWindow->getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == renderWindow->getHeight()))
+				if ((dst.getLeft() == 0) && (dst.getRight() == props.getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == props.getHeight()))
 				{
 				{
 					hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
 					hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
 				}
 				}
@@ -1199,7 +1202,7 @@ namespace BansheeEngine
 				SAFE_RELEASE(pStretchSurf);
 				SAFE_RELEASE(pStretchSurf);
 			}
 			}
 
 
-			if ((dst.getLeft() == 0) && (dst.getRight() == renderWindow->getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == renderWindow->getHeight()))
+			if ((dst.getLeft() == 0) && (dst.getRight() == props.getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == props.getHeight()))
 			{
 			{
 				hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
 				hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
 			}
 			}

+ 5 - 5
BansheeD3D9RenderSystem/Source/BsD3D9DeviceManager.cpp

@@ -75,7 +75,7 @@ namespace BansheeEngine
 		return mRenderDevices[index];
 		return mRenderDevices[index];
 	}
 	}
 
 
-	void D3D9DeviceManager::linkRenderWindow(D3D9RenderWindow* renderWindow)
+	void D3D9DeviceManager::linkRenderWindow(D3D9RenderWindowCore* renderWindow)
 	{		
 	{		
 		D3D9Device* renderDevice;
 		D3D9Device* renderDevice;
 
 
@@ -84,7 +84,7 @@ namespace BansheeEngine
 		if (renderDevice != nullptr)
 		if (renderDevice != nullptr)
 			renderDevice->detachRenderWindow(renderWindow);						
 			renderDevice->detachRenderWindow(renderWindow);						
 
 
-		Vector<D3D9RenderWindow*> renderWindowsGroup;
+		Vector<D3D9RenderWindowCore*> renderWindowsGroup;
 
 
 		// Select new device for this window.		
 		// Select new device for this window.		
 		renderDevice = selectDevice(renderWindow, renderWindowsGroup);
 		renderDevice = selectDevice(renderWindow, renderWindowsGroup);
@@ -92,7 +92,7 @@ namespace BansheeEngine
 		// Link the windows group to the new device.
 		// Link the windows group to the new device.
 		for (UINT32 i = 0; i < renderWindowsGroup.size(); ++i)
 		for (UINT32 i = 0; i < renderWindowsGroup.size(); ++i)
 		{
 		{
-			D3D9RenderWindow* currWindow = renderWindowsGroup[i];
+			D3D9RenderWindowCore* currWindow = renderWindowsGroup[i];
 
 
 			currWindow->_setDevice(renderDevice);
 			currWindow->_setDevice(renderDevice);
 			renderDevice->attachRenderWindow(currWindow);
 			renderDevice->attachRenderWindow(currWindow);
@@ -104,7 +104,7 @@ namespace BansheeEngine
 			setActiveDevice(renderDevice);		
 			setActiveDevice(renderDevice);		
 	}
 	}
 
 
-	D3D9Device* D3D9DeviceManager::selectDevice(D3D9RenderWindow* renderWindow, Vector<D3D9RenderWindow*>& renderWindowsGroup)
+	D3D9Device* D3D9DeviceManager::selectDevice(D3D9RenderWindowCore* renderWindow, Vector<D3D9RenderWindowCore*>& renderWindowsGroup)
 	{
 	{
 		D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(BansheeEngine::RenderSystem::instancePtr());
 		D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(BansheeEngine::RenderSystem::instancePtr());
 		D3D9Device*	renderDevice = nullptr;	
 		D3D9Device*	renderDevice = nullptr;	
@@ -165,7 +165,7 @@ namespace BansheeEngine
 		return renderDevice;	
 		return renderDevice;	
 	}
 	}
 
 
-	D3D9Driver* D3D9DeviceManager::findDriver(D3D9RenderWindow* renderWindow)
+	D3D9Driver* D3D9DeviceManager::findDriver(D3D9RenderWindowCore* renderWindow)
 	{
 	{
 		D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(BansheeEngine::RenderSystem::instancePtr());		
 		D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(BansheeEngine::RenderSystem::instancePtr());		
 		IDirect3D9*	direct3D9 = D3D9RenderSystem::getDirect3D9();				
 		IDirect3D9*	direct3D9 = D3D9RenderSystem::getDirect3D9();				

+ 20 - 17
BansheeD3D9RenderSystem/Source/BsD3D9MultiRenderTexture.cpp

@@ -4,24 +4,14 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D9MultiRenderTexture::D3D9MultiRenderTexture()
-		:MultiRenderTexture(), mDX9DepthStencilSurface(nullptr)
-	{
-
-	}
-
-	D3D9MultiRenderTexture::~D3D9MultiRenderTexture()
-	{
-
-	}
-
-	void D3D9MultiRenderTexture::initialize_internal()
+	D3D9MultiRenderTextureCore::D3D9MultiRenderTextureCore(D3D9MultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
+		:MultiRenderTextureCore(parent, properties, desc), mDX9DepthStencilSurface(nullptr)
 	{
 	{
 		mDX9ColorSurfaces.resize(mColorSurfaces.size());
 		mDX9ColorSurfaces.resize(mColorSurfaces.size());
 
 
-		for(size_t i = 0; i < mColorSurfaces.size(); i++)
+		for (size_t i = 0; i < mColorSurfaces.size(); i++)
 		{
 		{
-			if(mColorSurfaces[i] != nullptr)
+			if (mColorSurfaces[i] != nullptr)
 			{
 			{
 				D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurfaces[i]->getTexture().get());
 				D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurfaces[i]->getTexture().get());
 				D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 				D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
@@ -34,7 +24,7 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
-		if(mDepthStencilSurface != nullptr)
+		if (mDepthStencilSurface != nullptr)
 		{
 		{
 			D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(mDepthStencilSurface->getTexture().get());
 			D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(mDepthStencilSurface->getTexture().get());
 			D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 			D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
@@ -45,11 +35,14 @@ namespace BansheeEngine
 		{
 		{
 			mDX9DepthStencilSurface = nullptr;
 			mDX9DepthStencilSurface = nullptr;
 		}
 		}
+	}
+
+	D3D9MultiRenderTextureCore::~D3D9MultiRenderTextureCore()
+	{
 
 
-		MultiRenderTexture::initialize_internal();
 	}
 	}
 
 
-	void D3D9MultiRenderTexture::getCustomAttribute(const String& name, void* pData) const
+	void D3D9MultiRenderTextureCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name == "DDBACKBUFFER")
 		if(name == "DDBACKBUFFER")
 		{
 		{
@@ -73,4 +66,14 @@ namespace BansheeEngine
 			return;
 			return;
 		}
 		}
 	}
 	}
+
+	RenderTargetProperties* D3D9MultiRenderTexture::createProperties() const
+	{
+		return bs_new<MultiRenderTextureProperties>();
+	}
+
+	MultiRenderTextureCore* D3D9MultiRenderTexture::createCore(MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
+	{
+		return bs_new<D3D9MultiRenderTextureCore>(this, properties, desc);
+	}
 }
 }

+ 30 - 25
BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp

@@ -172,11 +172,11 @@ namespace BansheeEngine
 		msD3D9RenderSystem = NULL;
 		msD3D9RenderSystem = NULL;
 	}
 	}
 
 
-	void D3D9RenderSystem::registerWindow(RenderWindow& renderWindow)
+	void D3D9RenderSystem::registerWindow(RenderWindowCore& renderWindow)
 	{		
 	{		
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		D3D9RenderWindow* d3d9renderWindow = static_cast<D3D9RenderWindow*>(&renderWindow);
+		D3D9RenderWindowCore* d3d9renderWindow = static_cast<D3D9RenderWindowCore*>(&renderWindow);
 
 
 		String msg;
 		String msg;
 
 
@@ -1025,18 +1025,18 @@ namespace BansheeEngine
 		HRESULT hr;
 		HRESULT hr;
 
 
 		// Possibly change device if the target is a window
 		// Possibly change device if the target is a window
-		if (target->isWindow())
+		if (target->getCore()->getProperties().isWindow())
 		{
 		{
 			D3D9RenderWindow* window = static_cast<D3D9RenderWindow*>(target.get());
 			D3D9RenderWindow* window = static_cast<D3D9RenderWindow*>(target.get());
-			mDeviceManager->setActiveRenderTargetDevice(window->_getDevice());
-			window->_validateDevice();
+			mDeviceManager->setActiveRenderTargetDevice(window->getCore()->_getDevice());
+			window->getCore()->_validateDevice();
 		}
 		}
 
 
 		// Retrieve render surfaces
 		// Retrieve render surfaces
 		UINT32 maxRenderTargets = mCurrentCapabilities->getNumMultiRenderTargets();
 		UINT32 maxRenderTargets = mCurrentCapabilities->getNumMultiRenderTargets();
 		IDirect3DSurface9** pBack = bs_newN<IDirect3DSurface9*, ScratchAlloc>(maxRenderTargets);
 		IDirect3DSurface9** pBack = bs_newN<IDirect3DSurface9*, ScratchAlloc>(maxRenderTargets);
 		memset(pBack, 0, sizeof(IDirect3DSurface9*) * maxRenderTargets);
 		memset(pBack, 0, sizeof(IDirect3DSurface9*) * maxRenderTargets);
-		target->getCustomAttribute( "DDBACKBUFFER", pBack );
+		target->getCore()->getCustomAttribute("DDBACKBUFFER", pBack);
 		if (!pBack[0])
 		if (!pBack[0])
 		{
 		{
 			bs_deleteN<ScratchAlloc>(pBack, maxRenderTargets);
 			bs_deleteN<ScratchAlloc>(pBack, maxRenderTargets);
@@ -1046,7 +1046,7 @@ namespace BansheeEngine
 		IDirect3DSurface9* pDepth = NULL;
 		IDirect3DSurface9* pDepth = NULL;
 
 
 		if (!pDepth)
 		if (!pDepth)
-			target->getCustomAttribute( "D3DZBUFFER", &pDepth );
+			target->getCore()->getCustomAttribute("D3DZBUFFER", &pDepth);
 		
 		
 		// Bind render targets
 		// Bind render targets
 		for(UINT32 x = 0; x < maxRenderTargets; ++x)
 		for(UINT32 x = 0; x < maxRenderTargets; ++x)
@@ -1083,22 +1083,24 @@ namespace BansheeEngine
 		RenderTargetPtr target = vp.getTarget();
 		RenderTargetPtr target = vp.getTarget();
 		setRenderTarget(target);
 		setRenderTarget(target);
 
 
+		const RenderTargetProperties& rtProps = target->getCore()->getProperties();
+
 		setCullingMode( mCullingMode );
 		setCullingMode( mCullingMode );
 
 
-		// set viewport dimensions
-		mViewportWidth = vp.getWidth();
-		mViewportHeight = vp.getHeight();
-		mViewportLeft = vp.getX();
-		mViewportTop = vp.getY();
+		// Set viewport dimensions
+		mViewportLeft = (UINT32)(rtProps.getWidth() * vp.getNormalizedX());
+		mViewportTop = (UINT32)(rtProps.getHeight() * vp.getNormalizedY());
+		mViewportWidth = (UINT32)(rtProps.getWidth() * vp.getNormalizedWidth());
+		mViewportHeight = (UINT32)(rtProps.getHeight() * vp.getNormalizedHeight());
 
 
-		d3dvp.X = vp.getX();
-		d3dvp.Y = vp.getY();
-		d3dvp.Width = vp.getWidth();
-		d3dvp.Height = vp.getHeight();
+		d3dvp.X = mViewportLeft;
+		d3dvp.Y = mViewportTop;
+		d3dvp.Width = mViewportWidth;
+		d3dvp.Height = mViewportHeight;
 		if (target->requiresTextureFlipping())
 		if (target->requiresTextureFlipping())
 		{
 		{
 			// Convert "top-left" to "bottom-left"
 			// Convert "top-left" to "bottom-left"
-			d3dvp.Y = target->getHeight() - d3dvp.Height - d3dvp.Y;
+			d3dvp.Y = rtProps.getHeight() - d3dvp.Height - d3dvp.Y;
 		}
 		}
 
 
 		// Z-values from 0.0 to 1.0 (TODO: standardise with OpenGL)
 		// Z-values from 0.0 to 1.0 (TODO: standardise with OpenGL)
@@ -1109,7 +1111,7 @@ namespace BansheeEngine
 			BS_EXCEPT(RenderingAPIException, "Failed to set viewport.");
 			BS_EXCEPT(RenderingAPIException, "Failed to set viewport.");
 
 
 		// Set sRGB write mode
 		// Set sRGB write mode
-		setRenderState(D3DRS_SRGBWRITEENABLE, target->isHwGammaEnabled());
+		setRenderState(D3DRS_SRGBWRITEENABLE, rtProps.isHwGammaEnabled());
 	}
 	}
 
 
 	void D3D9RenderSystem::beginFrame()
 	void D3D9RenderSystem::beginFrame()
@@ -1327,7 +1329,8 @@ namespace BansheeEngine
 		if(mActiveRenderTarget == nullptr)
 		if(mActiveRenderTarget == nullptr)
 			return;
 			return;
 
 
-		RectI clearRect(0, 0, mActiveRenderTarget->getWidth(), mActiveRenderTarget->getHeight());
+		const RenderTargetProperties& rtProps = mActiveRenderTarget->getCore()->getProperties();
+		RectI clearRect(0, 0, rtProps.getWidth(), rtProps.getHeight());
 
 
 		clearArea(buffers, color, depth, stencil, clearRect);
 		clearArea(buffers, color, depth, stencil, clearRect);
 	}
 	}
@@ -1362,17 +1365,19 @@ namespace BansheeEngine
 			flags |= D3DCLEAR_STENCIL;
 			flags |= D3DCLEAR_STENCIL;
 		}
 		}
 
 
+		const RenderTargetProperties& rtProps = mActiveRenderTarget->getCore()->getProperties();
+
 		bool clearEntireTarget = clearRect.width == 0 || clearRect.height == 0;
 		bool clearEntireTarget = clearRect.width == 0 || clearRect.height == 0;
-		clearEntireTarget |= (clearRect.x == 0 && clearRect.y == 0 && clearRect.width == mActiveRenderTarget->getWidth() && clearRect.height == mActiveRenderTarget->getHeight());
+		clearEntireTarget |= (clearRect.x == 0 && clearRect.y == 0 && clearRect.width == rtProps.getWidth() && clearRect.height == rtProps.getHeight());
 
 
 		if(!clearEntireTarget)
 		if(!clearEntireTarget)
 		{
 		{
 			D3DRECT clearD3DRect;
 			D3DRECT clearD3DRect;
-			clearD3DRect.x1 = (LONG)Math::clamp(clearRect.x, 0, (INT32)mActiveRenderTarget->getWidth() - 1);
-			clearD3DRect.x2 = (LONG)Math::clamp((INT32)clearD3DRect.x1 + clearRect.width, 0, (INT32)mActiveRenderTarget->getWidth() - 1);
+			clearD3DRect.x1 = (LONG)Math::clamp(clearRect.x, 0, (INT32)rtProps.getWidth() - 1);
+			clearD3DRect.x2 = (LONG)Math::clamp((INT32)clearD3DRect.x1 + clearRect.width, 0, (INT32)rtProps.getWidth() - 1);
 
 
-			clearD3DRect.y1 = (LONG)Math::clamp(clearRect.y, 0, (INT32)mActiveRenderTarget->getHeight() - 1);
-			clearD3DRect.y2 = (LONG)Math::clamp((INT32)clearD3DRect.y1 + clearRect.height, 0, (INT32)mActiveRenderTarget->getHeight() - 1);
+			clearD3DRect.y1 = (LONG)Math::clamp(clearRect.y, 0, (INT32)rtProps.getHeight() - 1);
+			clearD3DRect.y2 = (LONG)Math::clamp((INT32)clearD3DRect.y1 + clearRect.height, 0, (INT32)rtProps.getHeight() - 1);
 
 
 			HRESULT hr;
 			HRESULT hr;
 			if(FAILED(hr = getActiveD3D9Device()->Clear(1, &clearD3DRect, flags, color.getAsBGRA(), depth, stencil)))
 			if(FAILED(hr = getActiveD3D9Device()->Clear(1, &clearD3DRect, flags, color.getAsBGRA(), depth, stencil)))
@@ -1745,7 +1750,7 @@ namespace BansheeEngine
 			D3DFMT_A16B16G16R16F, D3DFMT_R32F, D3DFMT_G32R32F, 
 			D3DFMT_A16B16G16R16F, D3DFMT_R32F, D3DFMT_G32R32F, 
 			D3DFMT_A32B32G32R32F};
 			D3DFMT_A32B32G32R32F};
 		IDirect3DSurface9* bbSurf;
 		IDirect3DSurface9* bbSurf;
-		renderWindow->getCustomAttribute("DDBACKBUFFER", &bbSurf);
+		renderWindow->getCore()->getCustomAttribute("DDBACKBUFFER", &bbSurf);
 		D3DSURFACE_DESC bbSurfDesc;
 		D3DSURFACE_DESC bbSurfDesc;
 		bbSurf->GetDesc(&bbSurfDesc);
 		bbSurf->GetDesc(&bbSurfDesc);
 
 

+ 24 - 18
BansheeD3D9RenderSystem/Source/BsD3D9RenderTexture.cpp

@@ -6,25 +6,20 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D9RenderTexture::D3D9RenderTexture()
-		:mDX9ColorSurface(nullptr), mDX9DepthStencilSurface(nullptr), mIsBindableToShader(false)
+	D3D9RenderTextureCore::D3D9RenderTextureCore(D3D9RenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+		const RENDER_SURFACE_DESC& depthStencilSurfaceDesc)
+		:RenderTextureCore(parent, properties, colorSurfaceDesc, depthStencilSurfaceDesc), mDX9ColorSurface(nullptr), 
+		mDX9DepthStencilSurface(nullptr), mIsBindableToShader(false)
 	{
 	{
-
-	}
-
-	D3D9RenderTexture::~D3D9RenderTexture()
-	{
-
+		initializeSurfaces();
 	}
 	}
 
 
-	void D3D9RenderTexture::initialize_internal()
+	D3D9RenderTextureCore::~D3D9RenderTextureCore()
 	{
 	{
-		initializeSurfaces();
 
 
-		RenderTexture::initialize_internal();
 	}
 	}
 
 
-	void D3D9RenderTexture::initializeSurfaces()
+	void D3D9RenderTextureCore::initializeSurfaces()
 	{
 	{
 		D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurface->getTexture().get());
 		D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurface->getTexture().get());
 		D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 		D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
@@ -37,14 +32,14 @@ namespace BansheeEngine
 		mDX9DepthStencilSurface = depthStencilBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
 		mDX9DepthStencilSurface = depthStencilBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
 	}
 	}
 
 
-	void D3D9RenderTexture::releaseSurfaces()
+	void D3D9RenderTextureCore::releaseSurfaces()
 	{
 	{
 		// All actual releasing happens in the color and depth textures.
 		// All actual releasing happens in the color and depth textures.
 		mDX9ColorSurface = nullptr;
 		mDX9ColorSurface = nullptr;
 		mDX9DepthStencilSurface = nullptr;
 		mDX9DepthStencilSurface = nullptr;
 	}
 	}
 
 
-	void D3D9RenderTexture::getCustomAttribute(const String& name, void* pData) const
+	void D3D9RenderTextureCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name == "DDBACKBUFFER")
 		if(name == "DDBACKBUFFER")
 		{
 		{
@@ -66,23 +61,34 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D9RenderTexture::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
+	void D3D9RenderTextureCore::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
 	{
 	{
 		initializeSurfaces();
 		initializeSurfaces();
 	}
 	}
 
 
-	void D3D9RenderTexture::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
+	void D3D9RenderTextureCore::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
 	{
 	{
 		releaseSurfaces();
 		releaseSurfaces();
 	}
 	}
 
 
-	void D3D9RenderTexture::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
+	void D3D9RenderTextureCore::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
 	{
 	{
 		releaseSurfaces();
 		releaseSurfaces();
 	}
 	}
 
 
-	void D3D9RenderTexture::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
+	void D3D9RenderTextureCore::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
 	{
 	{
 		initializeSurfaces();
 		initializeSurfaces();
 	}
 	}
+
+	RenderTargetProperties* D3D9RenderTexture::createProperties() const
+	{
+		return bs_new<RenderTextureProperties>();
+	}
+
+	RenderTextureCore* D3D9RenderTexture::createCore(RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+		const RENDER_SURFACE_DESC& depthStencilSurfaceDesc)
+	{
+		return bs_new<D3D9RenderTextureCore>(this, properties, colorSurfaceDesc, depthStencilSurfaceDesc);
+	}
 }
 }

+ 209 - 175
BansheeD3D9RenderSystem/Source/BsD3D9RenderWindow.cpp

@@ -12,44 +12,26 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D9RenderWindow::D3D9RenderWindow(const RENDER_WINDOW_DESC& desc, HINSTANCE instance)
-		: RenderWindow(desc), mInstance(instance), mIsDepthBuffered(true), mIsChild(false),
-		mStyle(0), mWindowedStyle(0), mWindowedStyleEx(0)
-	{
-		mDevice = NULL;
-		mIsFullScreen = false;		
-		mIsExternal = false;
-		mHWnd = 0;
-		mActive = false;		
-		mClosed = false;
-		mDisplayFrequency = 0;
-		mDeviceValid = false;
-	}
-
-	D3D9RenderWindow::~D3D9RenderWindow()
-	{ }
-
-	void D3D9RenderWindow::initialize_internal()
+	D3D9RenderWindowCore::D3D9RenderWindowCore(D3D9RenderWindow* parent, RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc, HINSTANCE instance)
+		: RenderWindowCore(parent, properties), mInstance(instance), mIsDepthBuffered(true), mIsChild(false),
+		mStyle(0), mWindowedStyle(0), mWindowedStyleEx(0), mDevice(nullptr), mIsExternal(false), mHWnd(0), mDisplayFrequency(0), mDeviceValid(false)
 	{
 	{
 		HINSTANCE hInst = mInstance;
 		HINSTANCE hInst = mInstance;
 
 
 		mMultisampleType = D3DMULTISAMPLE_NONE;
 		mMultisampleType = D3DMULTISAMPLE_NONE;
 		mMultisampleQuality = 0;
 		mMultisampleQuality = 0;
-		mMultisampleCount = mDesc.multisampleCount;
-		mVSync = mDesc.vsync;
-		mVSyncInterval = mDesc.vsyncInterval;
-		mDisplayFrequency = Math::roundToInt(mDesc.videoMode.getRefreshRate());
+		mDisplayFrequency = Math::roundToInt(desc.videoMode.getRefreshRate());
 
 
 		HWND parentHWnd = 0;
 		HWND parentHWnd = 0;
 		HWND externalHandle = 0;
 		HWND externalHandle = 0;
 
 
 		NameValuePairList::const_iterator opt;
 		NameValuePairList::const_iterator opt;
-		opt = mDesc.platformSpecific.find("parentWindowHandle");
-		if(opt != mDesc.platformSpecific.end())
+		opt = desc.platformSpecific.find("parentWindowHandle");
+		if (opt != desc.platformSpecific.end())
 			parentHWnd = (HWND)parseUnsignedInt(opt->second);
 			parentHWnd = (HWND)parseUnsignedInt(opt->second);
 
 
-		opt = mDesc.platformSpecific.find("externalWindowHandle");
-		if(opt != mDesc.platformSpecific.end())
+		opt = desc.platformSpecific.find("externalWindowHandle");
+		if (opt != desc.platformSpecific.end())
 			externalHandle = (HWND)parseUnsignedInt(opt->second);
 			externalHandle = (HWND)parseUnsignedInt(opt->second);
 
 
 		mIsChild = parentHWnd != 0;
 		mIsChild = parentHWnd != 0;
@@ -57,21 +39,21 @@ namespace BansheeEngine
 		mWindowedStyle = WS_VISIBLE | WS_CLIPCHILDREN;
 		mWindowedStyle = WS_VISIBLE | WS_CLIPCHILDREN;
 		mWindowedStyleEx = 0;
 		mWindowedStyleEx = 0;
 
 
-		if (!mDesc.fullscreen || mIsChild)
+		if (!desc.fullscreen || mIsChild)
 		{
 		{
 			if (parentHWnd)
 			if (parentHWnd)
 			{
 			{
-				if (mDesc.toolWindow)
+				if (desc.toolWindow)
 					mWindowedStyleEx = WS_EX_TOOLWINDOW;
 					mWindowedStyleEx = WS_EX_TOOLWINDOW;
 				else
 				else
 					mWindowedStyle |= WS_CHILD;
 					mWindowedStyle |= WS_CHILD;
 			}
 			}
 
 
-			if (!parentHWnd || mDesc.toolWindow)
+			if (!parentHWnd || desc.toolWindow)
 			{
 			{
-				if (mDesc.border == WindowBorder::None)
+				if (desc.border == WindowBorder::None)
 					mWindowedStyle |= WS_POPUP;
 					mWindowedStyle |= WS_POPUP;
-				else if (mDesc.border == WindowBorder::Fixed)
+				else if (desc.border == WindowBorder::Fixed)
 					mWindowedStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
 					mWindowedStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
 					WS_SYSMENU | WS_MINIMIZEBOX;
 					WS_SYSMENU | WS_MINIMIZEBOX;
 				else
 				else
@@ -79,6 +61,7 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
 		if (!externalHandle)
 		if (!externalHandle)
 		{
 		{
 			MONITORINFO monitorInfo;
 			MONITORINFO monitorInfo;
@@ -89,7 +72,7 @@ namespace BansheeEngine
 			UINT32 numOutputs = videoModeInfo.getNumOutputs();
 			UINT32 numOutputs = videoModeInfo.getNumOutputs();
 			if (numOutputs > 0)
 			if (numOutputs > 0)
 			{
 			{
-				UINT32 actualMonitorIdx = std::min(mDesc.videoMode.getOutputIdx(), numOutputs - 1);
+				UINT32 actualMonitorIdx = std::min(desc.videoMode.getOutputIdx(), numOutputs - 1);
 				const D3D9VideoOutputInfo& outputInfo = static_cast<const D3D9VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 				const D3D9VideoOutputInfo& outputInfo = static_cast<const D3D9VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 				hMonitor = outputInfo.getMonitorHandle();
 				hMonitor = outputInfo.getMonitorHandle();
 			}
 			}
@@ -100,8 +83,8 @@ namespace BansheeEngine
 				POINT windowAnchorPoint;
 				POINT windowAnchorPoint;
 
 
 				// Fill in anchor point.
 				// Fill in anchor point.
-				windowAnchorPoint.x = mDesc.left;
-				windowAnchorPoint.y = mDesc.top;
+				windowAnchorPoint.x = desc.left;
+				windowAnchorPoint.y = desc.top;
 
 
 				// Get the nearest monitor to this window.
 				// Get the nearest monitor to this window.
 				hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY);
 				hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY);
@@ -113,21 +96,21 @@ namespace BansheeEngine
 			GetMonitorInfo(hMonitor, &monitorInfo);
 			GetMonitorInfo(hMonitor, &monitorInfo);
 
 
 			unsigned int winWidth, winHeight;
 			unsigned int winWidth, winHeight;
-			winWidth = mDesc.videoMode.getWidth();
-			winHeight = mDesc.videoMode.getHeight();
+			winWidth = desc.videoMode.getWidth();
+			winHeight = desc.videoMode.getHeight();
 
 
-			UINT32 left = mDesc.left;
-			UINT32 top = mDesc.top;
+			UINT32 left = desc.left;
+			UINT32 top = desc.top;
 
 
 			// No specified top left -> Center the window in the middle of the monitor
 			// No specified top left -> Center the window in the middle of the monitor
 			if (left == -1 || top == -1)
 			if (left == -1 || top == -1)
-			{				
-				int screenw = monitorInfo.rcWork.right  - monitorInfo.rcWork.left;
+			{
+				int screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
 				int screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 				int screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 
 
 				// clamp window dimensions to screen size
 				// clamp window dimensions to screen size
-				int outerw = (int(winWidth) < screenw)? int(winWidth) : screenw;
-				int outerh = (int(winHeight) < screenh)? int(winHeight) : screenh;
+				int outerw = (int(winWidth) < screenw) ? int(winWidth) : screenw;
+				int outerh = (int(winHeight) < screenh) ? int(winHeight) : screenh;
 
 
 				if (left == -1)
 				if (left == -1)
 					left = monitorInfo.rcWork.left + (screenw - outerw) / 2;
 					left = monitorInfo.rcWork.left + (screenw - outerw) / 2;
@@ -145,47 +128,47 @@ namespace BansheeEngine
 				top += monitorInfo.rcWork.top;
 				top += monitorInfo.rcWork.top;
 			}
 			}
 
 
-			mWidth = mDesc.videoMode.getWidth();
-			mHeight =  mDesc.videoMode.getHeight();
-			mTop = top;
-			mLeft = left;
+			props->mWidth = desc.videoMode.getWidth();
+			props->mHeight = desc.videoMode.getHeight();
+			props->mTop = top;
+			props->mLeft = left;
 
 
 			DWORD dwStyle = 0;
 			DWORD dwStyle = 0;
 			DWORD dwStyleEx = 0;
 			DWORD dwStyleEx = 0;
-			if (mDesc.fullscreen && !mIsChild)
+			if (desc.fullscreen && !mIsChild)
 			{
 			{
 				dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_POPUP;
 				dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_POPUP;
-				mTop = monitorInfo.rcMonitor.top;
-				mLeft = monitorInfo.rcMonitor.left;		
+				props->mTop = monitorInfo.rcMonitor.top;
+				props->mLeft = monitorInfo.rcMonitor.left;
 			}
 			}
 			else
 			else
 			{
 			{
 				dwStyle = mWindowedStyle;
 				dwStyle = mWindowedStyle;
 				dwStyleEx = mWindowedStyleEx;
 				dwStyleEx = mWindowedStyleEx;
 
 
-				getAdjustedWindowSize(mDesc.videoMode.getWidth(), mDesc.videoMode.getHeight(), dwStyle, &winWidth, &winHeight);
+				getAdjustedWindowSize(desc.videoMode.getWidth(), desc.videoMode.getHeight(), dwStyle, &winWidth, &winHeight);
 
 
-				if (!mDesc.outerDimensions)
+				if (!desc.outerDimensions)
 				{
 				{
 					// Calculate window dimensions required
 					// Calculate window dimensions required
 					// to get the requested client area
 					// to get the requested client area
-					SetRect(&rc, 0, 0, mWidth, mHeight);
+					SetRect(&rc, 0, 0, props->mWidth, props->mHeight);
 					AdjustWindowRect(&rc, dwStyle, false);
 					AdjustWindowRect(&rc, dwStyle, false);
-					mWidth = rc.right - rc.left;
-					mHeight = rc.bottom - rc.top;
+					props->mWidth = rc.right - rc.left;
+					props->mHeight = rc.bottom - rc.top;
 
 
 					// Clamp window rect to the nearest display monitor.
 					// Clamp window rect to the nearest display monitor.
-					if (mLeft < monitorInfo.rcWork.left)
-						mLeft = monitorInfo.rcWork.left;		
+					if (props->mLeft < monitorInfo.rcWork.left)
+						props->mLeft = monitorInfo.rcWork.left;
 
 
-					if (mTop < monitorInfo.rcWork.top)					
-						mTop = monitorInfo.rcWork.top;					
+					if (props->mTop < monitorInfo.rcWork.top)
+						props->mTop = monitorInfo.rcWork.top;
 
 
-					if (static_cast<int>(winWidth) > monitorInfo.rcWork.right - mLeft)					
-						winWidth = monitorInfo.rcWork.right - mLeft;	
+					if (static_cast<int>(winWidth) > monitorInfo.rcWork.right - props->mLeft)
+						winWidth = monitorInfo.rcWork.right - props->mLeft;
 
 
-					if (static_cast<int>(winHeight) > monitorInfo.rcWork.bottom - mTop)					
-						winHeight = monitorInfo.rcWork.bottom - mTop;										
+					if (static_cast<int>(winHeight) > monitorInfo.rcWork.bottom - props->mTop)
+						winHeight = monitorInfo.rcWork.bottom - props->mTop;
 				}
 				}
 			}
 			}
 
 
@@ -199,8 +182,8 @@ namespace BansheeEngine
 			// Create our main window
 			// Create our main window
 			// Pass pointer to self
 			// Pass pointer to self
 			mIsExternal = false;
 			mIsExternal = false;
-			mHWnd = CreateWindowEx(dwStyleEx, "D3D9Wnd", mDesc.title.c_str(), dwStyle,
-				mLeft, mTop, winWidth, winHeight, parentHWnd, 0, hInst, this);
+			mHWnd = CreateWindowEx(dwStyleEx, "D3D9Wnd", desc.title.c_str(), dwStyle,
+				props->mLeft, props->mTop, winWidth, winHeight, parentHWnd, 0, hInst, this);
 			mStyle = dwStyle;
 			mStyle = dwStyle;
 		}
 		}
 		else
 		else
@@ -211,33 +194,29 @@ namespace BansheeEngine
 
 
 		RECT rc;
 		RECT rc;
 		GetWindowRect(mHWnd, &rc);
 		GetWindowRect(mHWnd, &rc);
-		mTop = rc.top;
-		mLeft = rc.left;
+		props->mTop = rc.top;
+		props->mLeft = rc.left;
 
 
 		GetClientRect(mHWnd, &rc);
 		GetClientRect(mHWnd, &rc);
-		mWidth = rc.right;
-		mHeight = rc.bottom;
-
-		mName = mDesc.title;
-		mIsDepthBuffered = mDesc.depthBuffer;
-		mIsFullScreen = mDesc.fullscreen && !mIsChild;
-		mColorDepth = 32;
+		props->mWidth = rc.right;
+		props->mHeight = rc.bottom;
 
 
-		mActive = true;
-		mClosed = false;
+		props->mName = desc.title;
+		mIsDepthBuffered = desc.depthBuffer;
+		props->mIsFullScreen = desc.fullscreen && !mIsChild;
+		props->mColorDepth = 32;
+		props->mActive = true;
 
 
 		D3D9RenderSystem* rs = static_cast<D3D9RenderSystem*>(RenderSystem::instancePtr());
 		D3D9RenderSystem* rs = static_cast<D3D9RenderSystem*>(RenderSystem::instancePtr());
 		rs->registerWindow(*this);
 		rs->registerWindow(*this);
-
-		RenderWindow::initialize_internal();
 	}
 	}
 
 
-	void D3D9RenderWindow::destroy_internal()
+	D3D9RenderWindowCore::~D3D9RenderWindowCore()
 	{
 	{
-		if (mDevice != NULL)
+		if (mDevice != nullptr)
 		{
 		{
 			mDevice->detachRenderWindow(this);
 			mDevice->detachRenderWindow(this);
-			mDevice = NULL;
+			mDevice = nullptr;
 		}
 		}
 
 
 		if (mHWnd && !mIsExternal)
 		if (mHWnd && !mIsExternal)
@@ -246,13 +225,14 @@ namespace BansheeEngine
 		}
 		}
 
 
 		mHWnd = 0;
 		mHWnd = 0;
-		mActive = false;
-		mClosed = true;
 
 
-		RenderWindow::destroy_internal();
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
+		props->mActive = false;
+
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D9RenderWindow::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
+	void D3D9RenderWindowCore::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -267,13 +247,14 @@ namespace BansheeEngine
 		UINT32 actualMonitorIdx = std::min(monitorIdx, numOutputs - 1);
 		UINT32 actualMonitorIdx = std::min(monitorIdx, numOutputs - 1);
 		const D3D9VideoOutputInfo& outputInfo = static_cast<const D3D9VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 		const D3D9VideoOutputInfo& outputInfo = static_cast<const D3D9VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 
 
-		bool oldFullscreen = mIsFullScreen;
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
+		bool oldFullscreen = props->mIsFullScreen;
 
 
-		mWidth = width;
-		mHeight = height;
+		props->mWidth = width;
+		props->mHeight = height;
 		mDisplayFrequency = Math::roundToInt(refreshRate);
 		mDisplayFrequency = Math::roundToInt(refreshRate);
 
 
-		mIsFullScreen = true;
+		props->mIsFullScreen = true;
 
 
 		HMONITOR hMonitor = outputInfo.getMonitorHandle();
 		HMONITOR hMonitor = outputInfo.getMonitorHandle();
 		MONITORINFO monitorInfo;
 		MONITORINFO monitorInfo;
@@ -282,35 +263,39 @@ namespace BansheeEngine
 		monitorInfo.cbSize = sizeof(MONITORINFO);
 		monitorInfo.cbSize = sizeof(MONITORINFO);
 		GetMonitorInfo(hMonitor, &monitorInfo);
 		GetMonitorInfo(hMonitor, &monitorInfo);
 
 
-		mTop = monitorInfo.rcMonitor.top;
-		mLeft = monitorInfo.rcMonitor.left;
+		props->mTop = monitorInfo.rcMonitor.top;
+		props->mLeft = monitorInfo.rcMonitor.left;
 
 
 		// Invalidate device, which resets it
 		// Invalidate device, which resets it
 		mDevice->invalidate(this);
 		mDevice->invalidate(this);
 		mDevice->acquire();
 		mDevice->acquire();
+
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D9RenderWindow::setFullscreen(const VideoMode& mode)
+	void D3D9RenderWindowCore::setFullscreen(const VideoMode& mode)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		setFullscreen(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getOutputIdx());
 		setFullscreen(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getOutputIdx());
 	}
 	}
 
 
-	void D3D9RenderWindow::setWindowed(UINT32 width, UINT32 height)
+	void D3D9RenderWindowCore::setWindowed(UINT32 width, UINT32 height)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (!mIsFullScreen)
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
+
+		if (!props->mIsFullScreen)
 			return;
 			return;
 
 
-		mIsFullScreen = false;
+		props->mIsFullScreen = false;
 		mStyle = mWindowedStyle;
 		mStyle = mWindowedStyle;
-		mWidth = width;
-		mHeight = height;
+		props->mWidth = width;
+		props->mHeight = height;
 
 
 		unsigned int winWidth, winHeight;
 		unsigned int winWidth, winHeight;
-		getAdjustedWindowSize(mWidth, mHeight, mStyle, &winWidth, &winHeight);
+		getAdjustedWindowSize(props->mWidth, props->mHeight, mStyle, &winWidth, &winHeight);
 
 
 		// Deal with centering when switching down to smaller resolution
 		// Deal with centering when switching down to smaller resolution
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
@@ -332,13 +317,17 @@ namespace BansheeEngine
 
 
 		mDevice->invalidate(this);
 		mDevice->invalidate(this);
 		mDevice->acquire();
 		mDevice->acquire();
+
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D9RenderWindow::setHidden(bool hidden)
+	void D3D9RenderWindowCore::setHidden(bool hidden)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		mHidden = hidden;
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
+
+		props->mHidden = hidden;
 		if (!mIsExternal)
 		if (!mIsExternal)
 		{
 		{
 			if (hidden)
 			if (hidden)
@@ -346,53 +335,48 @@ namespace BansheeEngine
 			else
 			else
 				ShowWindow(mHWnd, SW_SHOWNORMAL);
 				ShowWindow(mHWnd, SW_SHOWNORMAL);
 		}
 		}
-	}
-
-	bool D3D9RenderWindow::isActive() const
-	{
-		if (isFullScreen())
-			return isVisible();
-
-		return mActive && isVisible();
-	}
 
 
-	bool D3D9RenderWindow::isVisible() const
-	{
-		return (mHWnd && !IsIconic(mHWnd));
+		markCoreDirty();
 	}
 	}
 
 
-	void D3D9RenderWindow::move(INT32 top, INT32 left)
+	void D3D9RenderWindowCore::move(INT32 top, INT32 left)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd && !mIsFullScreen)
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
+
+		if (mHWnd && !props->mIsFullScreen)
 		{
 		{
-			mLeft = left;
-			mTop = top;
+			props->mLeft = left;
+			props->mTop = top;
 
 
-			SetWindowPos(mHWnd, 0, top, left, 0, 0,
-				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+			SetWindowPos(mHWnd, 0, top, left, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+			markCoreDirty();
 		}
 		}
 	}
 	}
 
 
-	void D3D9RenderWindow::resize(UINT32 width, UINT32 height)
+	void D3D9RenderWindowCore::resize(UINT32 width, UINT32 height)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd && !mIsFullScreen)
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
+
+		if (mHWnd && !props->mIsFullScreen)
 		{
 		{
-			mWidth = width;
-			mHeight = height;
+			props->mWidth = width;
+			props->mHeight = height;
 
 
 			unsigned int winWidth, winHeight;
 			unsigned int winWidth, winHeight;
 			getAdjustedWindowSize(width, height, mStyle, &winWidth, &winHeight);
 			getAdjustedWindowSize(width, height, mStyle, &winWidth, &winHeight);
 
 
 			SetWindowPos(mHWnd, 0, 0, 0, winWidth, winHeight,
 			SetWindowPos(mHWnd, 0, 0, 0, winWidth, winHeight,
 				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
 				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+			markCoreDirty();
 		}
 		}
 	}
 	}
 
 
-	void D3D9RenderWindow::getCustomAttribute( const String& name, void* pData ) const
+	void D3D9RenderWindowCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		// Valid attributes and their equivalent native functions:
 		// Valid attributes and their equivalent native functions:
 		// D3DDEVICE			: getD3DDevice
 		// D3DDEVICE			: getD3DDevice
@@ -437,7 +421,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D9RenderWindow::swapBuffers()
+	void D3D9RenderWindowCore::swapBuffers()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -445,34 +429,14 @@ namespace BansheeEngine
 			mDevice->present(this);		
 			mDevice->present(this);		
 	}
 	}
 
 
-	Vector2I D3D9RenderWindow::screenToWindowPos(const Vector2I& screenPos) const
-	{
-		POINT pos;
-		pos.x = screenPos.x;
-		pos.y = screenPos.y;
-
-		ScreenToClient(mHWnd, &pos);
-		return Vector2I(pos.x, pos.y);
-	}
-
-	Vector2I D3D9RenderWindow::windowToScreenPos(const Vector2I& windowPos) const
-	{
-		POINT pos;
-		pos.x = windowPos.x;
-		pos.y = windowPos.y;
-
-		ClientToScreen(mHWnd, &pos);
-		return Vector2I(pos.x, pos.y);
-	}
-
-	void D3D9RenderWindow::copyToMemory(PixelData &dst, FrameBuffer buffer)
+	void D3D9RenderWindowCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		mDevice->copyContentsToMemory(this, dst, buffer);
 		mDevice->copyContentsToMemory(this, dst, buffer);
 	}
 	}
 
 
-	void D3D9RenderWindow::_windowMovedOrResized()
+	void D3D9RenderWindowCore::_windowMovedOrResized()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -481,14 +445,14 @@ namespace BansheeEngine
 	
 	
 		updateWindowRect();
 		updateWindowRect();
 
 
-		RenderWindow::_windowMovedOrResized();
+		RenderWindowCore::_windowMovedOrResized();
 	}
 	}
 
 
 	/************************************************************************/
 	/************************************************************************/
 	/* 						D3D9 IMPLEMENTATION SPECIFIC                    */
 	/* 						D3D9 IMPLEMENTATION SPECIFIC                    */
 	/************************************************************************/
 	/************************************************************************/
 
 
-	void D3D9RenderWindow::getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight,
+	void D3D9RenderWindowCore::getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight,
 		DWORD style, UINT32* winWidth, UINT32* winHeight)
 		DWORD style, UINT32* winWidth, UINT32* winHeight)
 	{
 	{
 		RECT rc;
 		RECT rc;
@@ -514,7 +478,7 @@ namespace BansheeEngine
 			*winHeight = maxH;
 			*winHeight = maxH;
 	}
 	}
 	
 	
-	void D3D9RenderWindow::_buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) const
+	void D3D9RenderWindowCore::_buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) const
 	{			
 	{			
 		IDirect3D9* pD3D = D3D9RenderSystem::getDirect3D9();
 		IDirect3D9* pD3D = D3D9RenderSystem::getDirect3D9();
 		D3DDEVTYPE devType = D3DDEVTYPE_HAL;
 		D3DDEVTYPE devType = D3DDEVTYPE_HAL;
@@ -523,14 +487,14 @@ namespace BansheeEngine
 			devType = mDevice->getDeviceType();		
 			devType = mDevice->getDeviceType();		
 	
 	
 		ZeroMemory( presentParams, sizeof(D3DPRESENT_PARAMETERS) );
 		ZeroMemory( presentParams, sizeof(D3DPRESENT_PARAMETERS) );
-		presentParams->Windowed = !mIsFullScreen;
+		presentParams->Windowed = !getProperties().isFullScreen();
 		presentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
 		presentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
 		presentParams->BackBufferCount = 1;
 		presentParams->BackBufferCount = 1;
 		presentParams->EnableAutoDepthStencil = mIsDepthBuffered;
 		presentParams->EnableAutoDepthStencil = mIsDepthBuffered;
 		presentParams->hDeviceWindow = mHWnd;
 		presentParams->hDeviceWindow = mHWnd;
-		presentParams->BackBufferWidth = mWidth;
-		presentParams->BackBufferHeight	= mHeight;
-		presentParams->FullScreen_RefreshRateInHz = mIsFullScreen ? mDisplayFrequency : 0;
+		presentParams->BackBufferWidth = getProperties().getWidth();
+		presentParams->BackBufferHeight	= getProperties().getHeight();
+		presentParams->FullScreen_RefreshRateInHz = getProperties().isFullScreen() ? mDisplayFrequency : 0;
 		
 		
 		if (presentParams->BackBufferWidth == 0)		
 		if (presentParams->BackBufferWidth == 0)		
 			presentParams->BackBufferWidth = 1;					
 			presentParams->BackBufferWidth = 1;					
@@ -538,9 +502,9 @@ namespace BansheeEngine
 		if (presentParams->BackBufferHeight == 0)	
 		if (presentParams->BackBufferHeight == 0)	
 			presentParams->BackBufferHeight = 1;					
 			presentParams->BackBufferHeight = 1;					
 
 
-		if (mVSync)
+		if (getProperties().getVSync())
 		{
 		{
-			if (mIsFullScreen)
+			if (getProperties().isFullScreen())
 			{
 			{
 				switch(mVSyncInterval)
 				switch(mVSyncInterval)
 				{
 				{
@@ -612,76 +576,146 @@ namespace BansheeEngine
 		D3DMULTISAMPLE_TYPE multisampleType;
 		D3DMULTISAMPLE_TYPE multisampleType;
 		DWORD multisampleQuality;
 		DWORD multisampleQuality;
 
 
-		rs->determineMultisampleSettings(mDevice->getD3D9Device(), mMultisampleCount, mMultisampleHint, 
-			presentParams->BackBufferFormat, mIsFullScreen, &multisampleType, &multisampleQuality);
+		rs->determineMultisampleSettings(mDevice->getD3D9Device(), getProperties().getMultisampleCount(), getProperties().getMultisampleHint(), 
+			presentParams->BackBufferFormat, getProperties().isFullScreen(), &multisampleType, &multisampleQuality);
 
 
 		presentParams->MultiSampleType = multisampleType;
 		presentParams->MultiSampleType = multisampleType;
 		presentParams->MultiSampleQuality = (multisampleQuality == 0) ? 0 : multisampleQuality;
 		presentParams->MultiSampleQuality = (multisampleQuality == 0) ? 0 : multisampleQuality;
 	}
 	}
 
 
-	IDirect3DDevice9* D3D9RenderWindow::_getD3D9Device() const
+	IDirect3DDevice9* D3D9RenderWindowCore::_getD3D9Device() const
 	{
 	{
 		return mDevice->getD3D9Device();
 		return mDevice->getD3D9Device();
 	}
 	}
 
 
-	IDirect3DSurface9* D3D9RenderWindow::_getRenderSurface() const 
+	IDirect3DSurface9* D3D9RenderWindowCore::_getRenderSurface() const
 	{
 	{
 		return mDevice->getBackBuffer(this);
 		return mDevice->getBackBuffer(this);
 	}
 	}
 
 
-	D3D9Device* D3D9RenderWindow::_getDevice() const
+	D3D9Device* D3D9RenderWindowCore::_getDevice() const
 	{
 	{
 		return mDevice;
 		return mDevice;
 	}
 	}
 
 
-	void D3D9RenderWindow::_setDevice(D3D9Device* device)
+	void D3D9RenderWindowCore::_setDevice(D3D9Device* device)
 	{
 	{
 		mDevice = device;
 		mDevice = device;
 		mDeviceValid = false;
 		mDeviceValid = false;
 	}
 	}
 
 
-	bool D3D9RenderWindow::_isDepthBuffered() const
+	bool D3D9RenderWindowCore::_isDepthBuffered() const
 	{
 	{
 		return mIsDepthBuffered;
 		return mIsDepthBuffered;
 	}
 	}
 
 
-	void D3D9RenderWindow::updateWindowRect()
+	void D3D9RenderWindowCore::updateWindowRect()
 	{
 	{
 		RECT rc;
 		RECT rc;
 		BOOL result;
 		BOOL result;
 
 
+		D3D9RenderWindowProperties* props = static_cast<D3D9RenderWindowProperties*>(mProperties);
+
 		// Update top left parameters
 		// Update top left parameters
 		result = GetWindowRect(mHWnd, &rc);
 		result = GetWindowRect(mHWnd, &rc);
 		if (result == FALSE)
 		if (result == FALSE)
 		{
 		{
-			mTop = 0;
-			mLeft = 0;
-			mWidth = 0;
-			mHeight = 0;
+			props->mTop = 0;
+			props->mLeft = 0;
+			props->mWidth = 0;
+			props->mHeight = 0;
+
+			markCoreDirty();
 			return;
 			return;
 		}
 		}
 		
 		
-		mTop = rc.top;
-		mLeft = rc.left;
+		props->mTop = rc.top;
+		props->mLeft = rc.left;
 
 
 		// Width and height represent drawable area only
 		// Width and height represent drawable area only
 		result = GetClientRect(mHWnd, &rc);
 		result = GetClientRect(mHWnd, &rc);
 		if (result == FALSE)
 		if (result == FALSE)
 		{
 		{
-			mTop = 0;
-			mLeft = 0;
-			mWidth = 0;
-			mHeight = 0;
+			props->mTop = 0;
+			props->mLeft = 0;
+			props->mWidth = 0;
+			props->mHeight = 0;
+
+			markCoreDirty();
 			return;
 			return;
 		}
 		}
 
 
-		mWidth  = rc.right - rc.left;
-		mHeight = rc.bottom - rc.top;	
+		props->mWidth = rc.right - rc.left;
+		props->mHeight = rc.bottom - rc.top;
+
+		markCoreDirty();
 	}
 	}
 
 
-	bool D3D9RenderWindow::_validateDevice()
+	bool D3D9RenderWindowCore::_validateDevice()
 	{
 	{
 		mDeviceValid = mDevice->validate(this);
 		mDeviceValid = mDevice->validate(this);
 		return mDeviceValid;
 		return mDeviceValid;
 	}
 	}
+
+	D3D9RenderWindow::D3D9RenderWindow(HINSTANCE instance)
+		:mInstance(instance), mHWnd(0)
+	{
+
+	}
+
+	void D3D9RenderWindow::getCustomAttribute(const String& name, void* pData) const
+	{
+		THROW_IF_CORE_THREAD;
+
+		if (name == "WINDOW")
+		{
+			HWND *pWnd = (HWND*)pData;
+			*pWnd = mHWnd;
+			return;
+		}
+
+		RenderWindow::getCustomAttribute(name, pData);
+	}
+
+	Vector2I D3D9RenderWindow::screenToWindowPos(const Vector2I& screenPos) const
+	{
+		POINT pos;
+		pos.x = screenPos.x;
+		pos.y = screenPos.y;
+
+		ScreenToClient(mHWnd, &pos);
+		return Vector2I(pos.x, pos.y);
+	}
+
+	Vector2I D3D9RenderWindow::windowToScreenPos(const Vector2I& windowPos) const
+	{
+		POINT pos;
+		pos.x = windowPos.x;
+		pos.y = windowPos.y;
+
+		ClientToScreen(mHWnd, &pos);
+		return Vector2I(pos.x, pos.y);
+	}
+
+	void D3D9RenderWindow::initialize_internal()
+	{
+		RenderWindow::initialize_internal();
+
+		mCore->getCustomAttribute("WINDOW", (void*)&mHWnd);
+	}
+
+	D3D9RenderWindowCore* D3D9RenderWindow::getCore() const
+	{
+		return static_cast<D3D9RenderWindowCore*>(mCore);
+	}
+
+	RenderTargetProperties* D3D9RenderWindow::createProperties() const
+	{
+		return bs_new<RenderWindowProperties>();
+	}
+
+	RenderWindowCore* D3D9RenderWindow::createCore(RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc)
+	{
+		return bs_new<D3D9RenderWindowCore>(this, properties, desc, mInstance);
+	}
 }
 }

+ 1 - 1
BansheeD3D9RenderSystem/Source/BsD3D9RenderWindowManager.cpp

@@ -20,7 +20,7 @@ namespace BansheeEngine
 			desc.platformSpecific["parentWindowHandle"] = toString((UINT64)hWnd);
 			desc.platformSpecific["parentWindowHandle"] = toString((UINT64)hWnd);
 		}
 		}
 
 
-		D3D9RenderWindow* window = new (bs_alloc<D3D9RenderWindow, PoolAlloc>()) D3D9RenderWindow(desc, mRenderSystem->getInstanceHandle());
+		D3D9RenderWindow* window = new (bs_alloc<D3D9RenderWindow, PoolAlloc>()) D3D9RenderWindow(mRenderSystem->getInstanceHandle());
 
 
 		return RenderWindowPtr(window, &CoreObject::_deleteDelayed<D3D9RenderWindow, PoolAlloc>);
 		return RenderWindowPtr(window, &CoreObject::_deleteDelayed<D3D9RenderWindow, PoolAlloc>);
 	}
 	}

+ 4 - 4
BansheeEditor/Source/BsEditorWindowBase.cpp

@@ -91,21 +91,21 @@ namespace BansheeEngine
 
 
 	INT32 EditorWindowBase::getLeft() const
 	INT32 EditorWindowBase::getLeft() const
 	{
 	{
-		return mRenderWindow->getLeft();
+		return mRenderWindow->getProperties().getLeft();
 	}
 	}
 
 
 	INT32 EditorWindowBase::getTop() const
 	INT32 EditorWindowBase::getTop() const
 	{
 	{
-		return mRenderWindow->getTop();
+		return mRenderWindow->getProperties().getTop();
 	}
 	}
 
 
 	UINT32 EditorWindowBase::getWidth() const
 	UINT32 EditorWindowBase::getWidth() const
 	{
 	{
-		return (UINT32) mRenderWindow->getWidth();
+		return (UINT32)mRenderWindow->getProperties().getWidth();
 	}
 	}
 
 
 	UINT32 EditorWindowBase::getHeight() const
 	UINT32 EditorWindowBase::getHeight() const
 	{
 	{
-		return (UINT32) mRenderWindow->getHeight();
+		return (UINT32)mRenderWindow->getProperties().getHeight();
 	}
 	}
 }
 }

+ 1 - 1
BansheeEditor/Source/BsGUIResourceTreeView.cpp

@@ -449,7 +449,7 @@ namespace BansheeEngine
 	{
 	{
 		GUITreeView::_changeParentWidget(widget);
 		GUITreeView::_changeParentWidget(widget);
 
 
-		if (widget != nullptr && widget->getTarget()->getTarget()->isWindow())
+		if (widget != nullptr && widget->getTarget()->getTarget()->getProperties().isWindow())
 		{
 		{
 			RenderWindow* parentWindow = static_cast<RenderWindow*>(widget->getTarget()->getTarget().get());
 			RenderWindow* parentWindow = static_cast<RenderWindow*>(widget->getTarget()->getTarget().get());
 			setDropTarget(parentWindow, _getOffset().x, _getOffset().y, _getWidth(), _getHeight());
 			setDropTarget(parentWindow, _getOffset().x, _getOffset().y, _getWidth(), _getHeight());

+ 1 - 1
BansheeEditor/Source/BsGUIWindowFrameWidget.cpp

@@ -47,7 +47,7 @@ namespace BansheeEngine
 
 
 	void WindowFrameWidget::ownerWindowFocusChanged()
 	void WindowFrameWidget::ownerWindowFocusChanged()
 	{
 	{
-		mWindowFrame->setFocused(mParentWindow->hasFocus());
+		mWindowFrame->setFocused(mParentWindow->getProperties().hasFocus());
 
 
 		GUIWidget::ownerWindowFocusChanged();
 		GUIWidget::ownerWindowFocusChanged();
 	}
 	}

+ 2 - 1
BansheeEditor/Source/BsSceneEditorWidget.cpp

@@ -12,6 +12,7 @@
 #include "BsSceneCameraController.h"
 #include "BsSceneCameraController.h"
 #include "BsCamera.h"
 #include "BsCamera.h"
 #include "BsGUIRenderTexture.h"
 #include "BsGUIRenderTexture.h"
+#include "BsCoreThread.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -49,7 +50,7 @@ namespace BansheeEngine
 			mSceneRenderTarget->destroy();
 			mSceneRenderTarget->destroy();
 
 
 		mSceneRenderTarget = RenderTexture::create(TEX_TYPE_2D, width, height);
 		mSceneRenderTarget = RenderTexture::create(TEX_TYPE_2D, width, height);
-		mSceneRenderTarget->setPriority(1);
+		gCoreAccessor().setPriority(mSceneRenderTarget, 1);
 
 
 		if (mCamera == nullptr)
 		if (mCamera == nullptr)
 		{
 		{

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -11,7 +11,7 @@ int CALLBACK WinMain(
 	_In_  int nCmdShow
 	_In_  int nCmdShow
 	)
 	)
 {
 {
-	EditorApplication::startUp(RenderSystemPlugin::DX11);
+	EditorApplication::startUp(RenderSystemPlugin::OpenGL);
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::shutDown();
 	EditorApplication::shutDown();
 
 

+ 3 - 2
BansheeEngine/Source/BsGUIManager.cpp

@@ -1416,6 +1416,7 @@ namespace BansheeEngine
 		// so that mInputBridge map allows us to search through it - we don't access anything unless the target is bridged
 		// so that mInputBridge map allows us to search through it - we don't access anything unless the target is bridged
 		// (in which case we know it is a RenderTexture)
 		// (in which case we know it is a RenderTexture)
 		const RenderTexture* renderTexture = static_cast<const RenderTexture*>(widget.getTarget()->getTarget().get());
 		const RenderTexture* renderTexture = static_cast<const RenderTexture*>(widget.getTarget()->getTarget().get());
+		const RenderTargetProperties& rtProps = renderTexture->getProperties();
 
 
 		auto iterFind = mInputBridge.find(renderTexture);
 		auto iterFind = mInputBridge.find(renderTexture);
 		if(iterFind != mInputBridge.end()) // Widget input is bridged, which means we need to transform the coordinates
 		if(iterFind != mInputBridge.end()) // Widget input is bridged, which means we need to transform the coordinates
@@ -1431,8 +1432,8 @@ namespace BansheeEngine
 			float x = vecLocalPos.x - (float)bridgeBounds.x;
 			float x = vecLocalPos.x - (float)bridgeBounds.x;
 			float y = vecLocalPos.y - (float)bridgeBounds.y;
 			float y = vecLocalPos.y - (float)bridgeBounds.y;
 
 
-			float scaleX = renderTexture->getWidth() / (float)bridgeBounds.width;
-			float scaleY = renderTexture->getHeight() / (float)bridgeBounds.height;
+			float scaleX = rtProps.getWidth() / (float)bridgeBounds.width;
+			float scaleY = rtProps.getHeight() / (float)bridgeBounds.height;
 
 
 			return Vector2I(Math::roundToInt(x * scaleX), Math::roundToInt(y * scaleY));
 			return Vector2I(Math::roundToInt(x * scaleX), Math::roundToInt(y * scaleY));
 		}
 		}

+ 5 - 4
BansheeEngine/Source/BsGUIViewport.cpp

@@ -84,11 +84,12 @@ namespace BansheeEngine
 
 
 		ViewportPtr viewport = mCamera->getViewport();
 		ViewportPtr viewport = mCamera->getViewport();
 		RenderTargetPtr renderTarget = viewport->getTarget();
 		RenderTargetPtr renderTarget = viewport->getTarget();
+		const RenderTargetProperties& rtProps = renderTarget->getProperties();
 
 
-		float x = mOffset.x / (float)renderTarget->getWidth();
-		float y = mOffset.y / (float)renderTarget->getHeight();
-		float width = mWidth / (float)renderTarget->getWidth();
-		float height = mHeight / (float)renderTarget->getHeight();
+		float x = mOffset.x / (float)rtProps.getWidth();
+		float y = mOffset.y / (float)rtProps.getHeight();
+		float width = mWidth / (float)rtProps.getWidth();
+		float height = mHeight / (float)rtProps.getHeight();
 
 
 		viewport->setArea(x, y, width, height);
 		viewport->setArea(x, y, width, height);
 	}
 	}

+ 33 - 13
BansheeGLRenderSystem/Include/BsGLMultiRenderTexture.h

@@ -6,38 +6,58 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	class GLMultiRenderTexture;
+
 	/**
 	/**
 	 * @brief	OpenGL implementation of a render texture with multiple color surfaces.
 	 * @brief	OpenGL implementation of a render texture with multiple color surfaces.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-	class BS_RSGL_EXPORT GLMultiRenderTexture : public MultiRenderTexture
+	class BS_RSGL_EXPORT GLMultiRenderTextureCore : public MultiRenderTextureCore
 	{
 	{
 	public:
 	public:
-		virtual ~GLMultiRenderTexture();
+		GLMultiRenderTextureCore(GLMultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc);
+		virtual ~GLMultiRenderTextureCore();
 
 
 		/**
 		/**
-		 * @copydoc MultiRenderTexture::requiresTextureFlipping
+		 * @copydoc MultiRenderTextureCore::getCustomAttribute
 		 */
 		 */
-		bool requiresTextureFlipping() const { return true; }
+		void getCustomAttribute(const String& name, void* pData) const;
+	protected:
+		friend class GLTextureManager;
+
+	private:
+		GLFrameBufferObject* mFB;
+	};
+
+	/**
+	 * @brief	OpenGL implementation of a render texture with multiple color surfaces.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_RSGL_EXPORT GLMultiRenderTexture : public MultiRenderTexture
+	{
+	public:
+		virtual ~GLMultiRenderTexture() { }
 
 
 		/**
 		/**
-		 * @copydoc MultiRenderTexture::getCustomAttribute
+		 * @copydoc	MultiRenderTexture::requiresTextureFlipping
 		 */
 		 */
-		void getCustomAttribute(const String& name, void* pData) const;
+		bool requiresTextureFlipping() const { return true; }
+
 	protected:
 	protected:
 		friend class GLTextureManager;
 		friend class GLTextureManager;
 
 
-		GLMultiRenderTexture();
+		GLMultiRenderTexture() { }
 
 
 		/**
 		/**
-		 * @copydoc MultiRenderTexture::initialize_internal
+		 * @copydoc	MultiRenderTexture::createProperties
 		 */
 		 */
-		void initialize_internal();
+		virtual RenderTargetProperties* createProperties() const;
 
 
 		/**
 		/**
-		 * @copydoc MultiRenderTexture::destroy_internal
+		 * @copydoc	MultiRenderTexture::createCore
 		 */
 		 */
-		void destroy_internal();
-	private:
-		GLFrameBufferObject* mFB;
+		virtual MultiRenderTextureCore* createCore(MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc);
 	};
 	};
 }
 }

+ 36 - 14
BansheeGLRenderSystem/Include/BsGLRenderTexture.h

@@ -9,41 +9,63 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {  
 {  
+	class GLRenderTexture;
+
 	/**
 	/**
 	 * @brief	OpenGL implementation of a render texture.
 	 * @brief	OpenGL implementation of a render texture.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-    class BS_RSGL_EXPORT GLRenderTexture: public RenderTexture
+    class BS_RSGL_EXPORT GLRenderTextureCore : public RenderTextureCore
     {
     {
 	public:
 	public:
-		virtual ~GLRenderTexture();
+		GLRenderTextureCore(GLRenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc);
 
 
-		/**
-		 * @copydoc	RenderTexture::requiresTextureFlipping
-		 */
-		bool requiresTextureFlipping() const { return true; }
+		virtual ~GLRenderTextureCore();
 
 
 		/**
 		/**
-		 * @copydoc	RenderTexture::getCustomAttribute
+		 * @copydoc	RenderTextureCore::getCustomAttribute
 		 */
 		 */
 		virtual void getCustomAttribute(const String& name, void* pData) const;
 		virtual void getCustomAttribute(const String& name, void* pData) const;
 
 
+	protected:
+		friend class GLRenderTexture;
+
+		GLFrameBufferObject* mFB;
+    };
+
+	/**
+	 * @brief	OpenGL implementation of a render texture.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_RSGL_EXPORT GLRenderTexture : public RenderTexture
+	{
+	public:
+		virtual ~GLRenderTexture() { }
+
 	protected:
 	protected:
 		friend class GLTextureManager;
 		friend class GLTextureManager;
 
 
-		GLRenderTexture();
+		GLRenderTexture() { }
 
 
 		/**
 		/**
-		 * @copydoc RenderTexture::initialize_internal
+		 * @copydoc	RenderTexture::requiresTextureFlipping
 		 */
 		 */
-		void initialize_internal();
+		bool requiresTextureFlipping() const { return true; }
 
 
 		/**
 		/**
-		 * @copydoc RenderTexture::destroy_internal
+		 * @copydoc	RenderTexture::createProperties
 		 */
 		 */
-		void destroy_internal();
+		virtual RenderTargetProperties* createProperties() const;
 
 
-		GLFrameBufferObject* mFB;
-    };
+		/**
+		 * @copydoc	RenderTexture::createCore
+		 */
+		virtual RenderTextureCore* createCore(RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+			const RENDER_SURFACE_DESC& depthStencilSurfaceDesc);
+	};
 
 
     /**
     /**
      * @brief	Manager that handles valid render texture formats.
      * @brief	Manager that handles valid render texture formats.

+ 1 - 1
BansheeGLRenderSystem/Include/BsGLVertexArrayObjectManager.h

@@ -72,7 +72,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Called when a vertex buffer containing the provided VAO is destroyed.
 		 * @brief	Called when a vertex buffer containing the provided VAO is destroyed.
 		 */
 		 */
-		void notifyBufferDestroyed(const GLVertexArrayObject& vao);
+		void notifyBufferDestroyed(GLVertexArrayObject vao);
 	private:
 	private:
 		typedef UnorderedSet<GLVertexArrayObject, GLVertexArrayObject::Hash, GLVertexArrayObject::Equal> VAOMap;
 		typedef UnorderedSet<GLVertexArrayObject, GLVertexArrayObject::Hash, GLVertexArrayObject::Equal> VAOMap;
 
 

+ 0 - 1
BansheeGLRenderSystem/Include/BsWin32VideoModeInfo.h

@@ -24,7 +24,6 @@ namespace BansheeEngine
 	{
 	{
 	public:
 	public:
 		Win32VideoOutputInfo(HMONITOR monitorHandle, UINT32 outputIdx);
 		Win32VideoOutputInfo(HMONITOR monitorHandle, UINT32 outputIdx);
-		~Win32VideoOutputInfo();
 
 
 		/**
 		/**
 		 * @brief	Gets a Win32 handle to the monitor referenced by this object.
 		 * @brief	Gets a Win32 handle to the monitor referenced by this object.

+ 87 - 53
BansheeGLRenderSystem/Include/BsWin32Window.h

@@ -5,68 +5,123 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
+	class Win32Window;
+
+	/**
+	 * @brief	Contains various properties that describe a render window.
+	 */
+	class BS_RSGL_EXPORT Win32RenderWindowProperties : public RenderWindowProperties
+	{
+	public:
+		virtual ~Win32RenderWindowProperties() { }
+
+	private:
+		friend class Win32WindowCore;
+		friend class Win32Window;
+	};
+
 	/**
 	/**
 	 * @brief	Render window implementation for Windows.
 	 * @brief	Render window implementation for Windows.
+	 *
+	 * @note	Core thread only.
 	 */
 	 */
-    class BS_RSGL_EXPORT Win32Window : public RenderWindow
+    class BS_RSGL_EXPORT Win32WindowCore : public RenderWindowCore
     {
     {
     public:
     public:
-        ~Win32Window();
+		Win32WindowCore(Win32Window* parent, RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc, Win32GLSupport &glsupport);
+		~Win32WindowCore();
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::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);
 		void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setFullscreen(const VideoMode&)
+		 * @copydoc RenderWindowCore::setFullscreen(const VideoMode&)
 		 */
 		 */
 		void setFullscreen(const VideoMode& mode);
 		void setFullscreen(const VideoMode& mode);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setWindowed
+		 * @copydoc RenderWindowCore::setWindowed
 		 */
 		 */
 		void setWindowed(UINT32 width, UINT32 height);
 		void setWindowed(UINT32 width, UINT32 height);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setHidden
+		 * @copydoc RenderWindowCore::setHidden
 		 */
 		 */
 		void setHidden(bool hidden);
 		void setHidden(bool hidden);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::isActive
+		 * @copydoc RenderWindowCore::move
 		 */
 		 */
-		bool isActive() const;
+		void move(INT32 left, INT32 top);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::isVisible
+		 * @copydoc RenderWindowCore::resize
 		 */
 		 */
-		bool isVisible() const;
+		void resize(UINT32 width, UINT32 height);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::isClosed
+		 * @copydoc RenderWindowCore::copyContentsToMemory
 		 */
 		 */
-		bool isClosed() const;
+		void copyToMemory(PixelData &dst, FrameBuffer buffer);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::move
+		 * @copydoc RenderWindowCore::swapBuffers
 		 */
 		 */
-		void move(INT32 left, INT32 top);
+		void swapBuffers();
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::resize
+		 * @copydoc RenderWindowCore::getCustomAttribute
 		 */
 		 */
-		void resize(UINT32 width, UINT32 height);
+		void getCustomAttribute(const String& name, void* pData) const;
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::copyContentsToMemory
+		 * @copydoc RenderWindowCore::setActive
 		 */
 		 */
-		void copyToMemory(PixelData &dst, FrameBuffer buffer);
+		virtual void setActive(bool state);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::swapBuffers
+		 * @copydoc RenderWindowCore::_windowMovedOrResized
 		 */
 		 */
-		void swapBuffers();
+		void _windowMovedOrResized();
+
+		/**
+		 * @brief	Returns handle to device context associated with the window.
+		 */
+		HDC _getHDC() const { return mHDC; }
+
+	protected:
+		friend class Win32GLSupport;
+
+		/**
+		 * @brief	Calculates window size based on provided client area size and currently set window style. 
+		 */
+		void getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight, UINT32* winWidth, UINT32* winHeight);
+
+	protected:
+		Win32GLSupport &mGLSupport;
+		HWND mHWnd;
+		HDC	mHDC;
+		DWORD mWindowedStyle;
+		DWORD mWindowedStyleEx;
+		bool mIsExternal;
+		bool mIsChild;
+		char* mDeviceName;
+		bool mIsExternalGLControl;
+		int mDisplayFrequency;
+		Win32Context *mContext;
+    };
+
+	/**
+	 * @brief	Render window implementation for Windows.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_RSGL_EXPORT Win32Window : public RenderWindow
+	{
+	public:
+		~Win32Window() { }
 
 
 		/**
 		/**
 		 * @copydoc RenderWindow::requiresTextureFlipping
 		 * @copydoc RenderWindow::requiresTextureFlipping
@@ -89,54 +144,33 @@ namespace BansheeEngine
 		void getCustomAttribute(const String& name, void* pData) const;
 		void getCustomAttribute(const String& name, void* pData) const;
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setActive
+		 * @copydoc	RenderWindow::getCore
 		 */
 		 */
-		virtual void setActive(bool state);
-
-		/**
-		 * @copydoc RenderWindow::_windowMovedOrResized
-		 */
-		void _windowMovedOrResized();
-
-		/**
-		 * @brief	Returns handle to device context associated with the window.
-		 */
-		HDC _getHDC() const { return mHDC; }
+		Win32WindowCore* getCore() const;
 
 
 	protected:
 	protected:
 		friend class GLRenderWindowManager;
 		friend class GLRenderWindowManager;
 		friend class Win32GLSupport;
 		friend class Win32GLSupport;
 
 
-		Win32Window(const RENDER_WINDOW_DESC& desc, Win32GLSupport &glsupport);
+		Win32Window(Win32GLSupport& glsupport);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::initialize_internal().
+		 * @copydoc	RenderWindow::initialize_internal
 		 */
 		 */
-		void initialize_internal();
+		virtual void initialize_internal();
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::destroy_internal().
+		 * @copydoc	RenderWindow::createProperties
 		 */
 		 */
-		void destroy_internal();
+		virtual RenderTargetProperties* createProperties() const;
 
 
 		/**
 		/**
-		 * @brief	Calculates window size based on provided client area size and currently set window style. 
+		 * @copydoc	RenderWindow::createCore
 		 */
 		 */
-		void getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight, UINT32* winWidth, UINT32* winHeight);
+		virtual RenderWindowCore* createCore(RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc);
 
 
-	protected:
-		Win32GLSupport &mGLSupport;
+	private:
+		Win32GLSupport& mGLSupport;
 		HWND mHWnd;
 		HWND mHWnd;
-		HDC	mHDC;
-		DWORD mWindowedStyle;
-		DWORD mWindowedStyleEx;
-		bool mIsExternal;
-		bool mIsChild;
-		char* mDeviceName;
-		bool mIsExternalGLControl;
-		bool mSizing;
-		bool mClosed;
-		int mDisplayFrequency;
-		Win32Context *mContext;
-    };
+	};
 }
 }

+ 24 - 28
BansheeGLRenderSystem/Source/BsGLMultiRenderTexture.cpp

@@ -3,35 +3,25 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	GLMultiRenderTexture::GLMultiRenderTexture()
-		:MultiRenderTexture(), mFB(nullptr)
+	GLMultiRenderTextureCore::GLMultiRenderTextureCore(GLMultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
+		:MultiRenderTextureCore(parent, properties, desc), mFB(nullptr)
 	{
 	{
-
-	}
-
-	GLMultiRenderTexture::~GLMultiRenderTexture()
-	{
-
-	}
-
-	void GLMultiRenderTexture::initialize_internal()
-	{
-		if(mFB != nullptr)
+		if (mFB != nullptr)
 			bs_delete(mFB);
 			bs_delete(mFB);
 
 
 		mFB = bs_new<GLFrameBufferObject, PoolAlloc>();
 		mFB = bs_new<GLFrameBufferObject, PoolAlloc>();
 
 
-		for(size_t i = 0; i < mColorSurfaces.size(); i++)
+		for (size_t i = 0; i < mColorSurfaces.size(); i++)
 		{
 		{
-			if(mColorSurfaces[i] != nullptr)
+			if (mColorSurfaces[i] != nullptr)
 			{
 			{
 				GLTexture* glColorSurface = static_cast<GLTexture*>(mColorSurfaces[i]->getTexture().get());
 				GLTexture* glColorSurface = static_cast<GLTexture*>(mColorSurfaces[i]->getTexture().get());
-				GLPixelBufferPtr colorBuffer = 
-					glColorSurface->getBuffer(mColorSurfaces[i]->getDesc().firstArraySlice, 
+				GLPixelBufferPtr colorBuffer =
+					glColorSurface->getBuffer(mColorSurfaces[i]->getDesc().firstArraySlice,
 					mColorSurfaces[i]->getDesc().mostDetailMip);
 					mColorSurfaces[i]->getDesc().mostDetailMip);
 
 
 				GLSurfaceDesc surfaceDesc;
 				GLSurfaceDesc surfaceDesc;
-				surfaceDesc.numSamples = mMultisampleCount;
+				surfaceDesc.numSamples = getProperties().getMultisampleCount();
 				surfaceDesc.zoffset = 0;
 				surfaceDesc.zoffset = 0;
 				surfaceDesc.buffer = colorBuffer;
 				surfaceDesc.buffer = colorBuffer;
 
 
@@ -43,11 +33,11 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
-		if(mDepthStencilSurface != nullptr)
+		if (mDepthStencilSurface != nullptr)
 		{
 		{
 			GLTexture* glDepthStencilSurface = static_cast<GLTexture*>(mDepthStencilSurface->getTexture().get());
 			GLTexture* glDepthStencilSurface = static_cast<GLTexture*>(mDepthStencilSurface->getTexture().get());
-			GLPixelBufferPtr depthStencilBuffer = 
-				glDepthStencilSurface->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice, 
+			GLPixelBufferPtr depthStencilBuffer =
+				glDepthStencilSurface->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice,
 				mDepthStencilSurface->getDesc().mostDetailMip);
 				mDepthStencilSurface->getDesc().mostDetailMip);
 
 
 			mFB->bindDepthStencil(depthStencilBuffer);
 			mFB->bindDepthStencil(depthStencilBuffer);
@@ -56,19 +46,15 @@ namespace BansheeEngine
 		{
 		{
 			mFB->unbindDepthStencil();
 			mFB->unbindDepthStencil();
 		}
 		}
-
-		MultiRenderTexture::initialize_internal();
 	}
 	}
 
 
-	void GLMultiRenderTexture::destroy_internal()
+	GLMultiRenderTextureCore::~GLMultiRenderTextureCore()
 	{
 	{
-		if(mFB != nullptr)
+		if (mFB != nullptr)
 			bs_delete(mFB);
 			bs_delete(mFB);
-
-		MultiRenderTexture::destroy_internal();
 	}
 	}
 
 
-	void GLMultiRenderTexture::getCustomAttribute(const String& name, void* pData) const
+	void GLMultiRenderTextureCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name=="FBO")
 		if(name=="FBO")
 		{
 		{
@@ -79,4 +65,14 @@ namespace BansheeEngine
 			*static_cast<GLuint*>(pData) = mFB->getGLFBOID();
 			*static_cast<GLuint*>(pData) = mFB->getGLFBOID();
 		}
 		}
 	}
 	}
+
+	RenderTargetProperties* GLMultiRenderTexture::createProperties() const
+	{
+		return bs_new<MultiRenderTextureProperties>();
+	}
+
+	MultiRenderTextureCore* GLMultiRenderTexture::createCore(MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
+	{
+		return bs_new<GLMultiRenderTextureCore>(this, properties, desc);
+	}
 }
 }

+ 21 - 16
BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp

@@ -116,7 +116,7 @@ namespace BansheeEngine
 		      
 		      
 		// Get the context from the window and finish initialization
 		// Get the context from the window and finish initialization
 		GLContext *context = nullptr;
 		GLContext *context = nullptr;
-		primaryWindow->getCustomAttribute("GLCONTEXT", &context);
+		primaryWindow->getCore()->getCustomAttribute("GLCONTEXT", &context);
 
 
 		// Set main and current context
 		// Set main and current context
 		mMainContext = context;
 		mMainContext = context;
@@ -159,8 +159,6 @@ namespace BansheeEngine
 	{
 	{
 		RenderSystem::destroy_internal();
 		RenderSystem::destroy_internal();
 
 
-		GLVertexArrayObjectManager::shutDown();
-
 		// Deleting the GLSL program factory
 		// Deleting the GLSL program factory
 		if (mGLSLProgramFactory)
 		if (mGLSLProgramFactory)
 		{
 		{
@@ -190,6 +188,7 @@ namespace BansheeEngine
 		QueryManager::shutDown();
 		QueryManager::shutDown();
 		RenderWindowManager::shutDown();
 		RenderWindowManager::shutDown();
 		RenderStateManager::shutDown();
 		RenderStateManager::shutDown();
+		GLVertexArrayObjectManager::shutDown(); // Note: Needs to be after QueryManager shutdown as some resources might be waiting for queries to complete
 
 
 		mGLInitialised = false;
 		mGLInitialised = false;
 
 
@@ -530,16 +529,18 @@ namespace BansheeEngine
 		target = vp.getTarget();
 		target = vp.getTarget();
 		setRenderTarget(target);
 		setRenderTarget(target);
 
 
+		const RenderTargetProperties& rtProps = target->getCore()->getProperties();
+
 		// Calculate the "lower-left" corner of the viewport
 		// Calculate the "lower-left" corner of the viewport
-		mViewportWidth = vp.getWidth();
-		mViewportHeight = vp.getHeight();
-		mViewportLeft = vp.getX();
-		mViewportTop = vp.getY();
+		mViewportLeft = (UINT32)(rtProps.getWidth() * vp.getNormalizedX());
+		mViewportTop = (UINT32)(rtProps.getHeight() * vp.getNormalizedY());
+		mViewportWidth = (UINT32)(rtProps.getWidth() * vp.getNormalizedWidth());
+		mViewportHeight = (UINT32)(rtProps.getHeight() * vp.getNormalizedHeight());
 
 
 		if (!target->requiresTextureFlipping())
 		if (!target->requiresTextureFlipping())
 		{
 		{
 			// Convert "upper-left" corner to "lower-left"
 			// Convert "upper-left" corner to "lower-left"
-			mViewportTop = target->getHeight() - mViewportHeight - mViewportTop;
+			mViewportTop = target->getCore()->getProperties().getHeight() - mViewportHeight - mViewportTop;
 		}
 		}
 
 
 		glViewport(mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight);
 		glViewport(mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight);
@@ -556,14 +557,14 @@ namespace BansheeEngine
 
 
 		// Switch context if different from current one
 		// Switch context if different from current one
 		GLContext *newContext = 0;
 		GLContext *newContext = 0;
-		target->getCustomAttribute("GLCONTEXT", &newContext);
+		target->getCore()->getCustomAttribute("GLCONTEXT", &newContext);
 		if(newContext && mCurrentContext != newContext) 
 		if(newContext && mCurrentContext != newContext) 
 		{
 		{
 			switchContext(newContext);
 			switchContext(newContext);
 		}
 		}
 
 
 		GLFrameBufferObject *fbo = 0;
 		GLFrameBufferObject *fbo = 0;
-		target->getCustomAttribute("FBO", &fbo);
+		target->getCore()->getCustomAttribute("FBO", &fbo);
 		if(fbo)
 		if(fbo)
 			fbo->bind();
 			fbo->bind();
 		else
 		else
@@ -573,7 +574,7 @@ namespace BansheeEngine
 		if (GLEW_EXT_framebuffer_sRGB)
 		if (GLEW_EXT_framebuffer_sRGB)
 		{
 		{
 			// Enable / disable sRGB states
 			// Enable / disable sRGB states
-			if (target->isHwGammaEnabled())
+			if (target->getCore()->getProperties().isHwGammaEnabled())
 			{
 			{
 				glEnable(GL_FRAMEBUFFER_SRGB_EXT);
 				glEnable(GL_FRAMEBUFFER_SRGB_EXT);
 
 
@@ -667,8 +668,8 @@ namespace BansheeEngine
 
 
 		// Find the correct type to render
 		// Find the correct type to render
 		GLint primType = getGLDrawMode();
 		GLint primType = getGLDrawMode();
-		beginDraw();
 
 
+		beginDraw();
 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 
 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 
 			static_cast<GLIndexBuffer*>(mBoundIndexBuffer.get())->getGLBufferId());
 			static_cast<GLIndexBuffer*>(mBoundIndexBuffer.get())->getGLBufferId());
 
 
@@ -676,7 +677,6 @@ namespace BansheeEngine
 		glDrawElementsBaseVertex(primType, indexCount, indexType, (GLvoid*)(mBoundIndexBuffer->getIndexSize() * startIndex), vertexOffset);
 		glDrawElementsBaseVertex(primType, indexCount, indexType, (GLvoid*)(mBoundIndexBuffer->getIndexSize() * startIndex), vertexOffset);
 
 
 		endDraw();
 		endDraw();
-
 		UINT32 primCount = vertexCountToPrimCount(mCurrentDrawOperation, vertexCount);
 		UINT32 primCount = vertexCountToPrimCount(mCurrentDrawOperation, vertexCount);
 
 
 		BS_INC_RENDER_STAT(NumDrawCalls);
 		BS_INC_RENDER_STAT(NumDrawCalls);
@@ -701,7 +701,8 @@ namespace BansheeEngine
 		if(mActiveRenderTarget == nullptr)
 		if(mActiveRenderTarget == nullptr)
 			return;
 			return;
 
 
-		RectI clearRect(0, 0, mActiveRenderTarget->getWidth(), mActiveRenderTarget->getHeight());
+		const RenderTargetProperties& rtProps = mActiveRenderTarget->getCore()->getProperties();
+		RectI clearRect(0, 0, rtProps.getWidth(), rtProps.getHeight());
 
 
 		clearArea(buffers, color, depth, stencil, clearRect);
 		clearArea(buffers, color, depth, stencil, clearRect);
 	}
 	}
@@ -766,8 +767,10 @@ namespace BansheeEngine
 			glDisable(GL_SCISSOR_TEST);
 			glDisable(GL_SCISSOR_TEST);
 		}
 		}
 
 
+		const RenderTargetProperties& rtProps = mActiveRenderTarget->getCore()->getProperties();
+
 		bool clearEntireTarget = clearRect.width == 0 || clearRect.height == 0;
 		bool clearEntireTarget = clearRect.width == 0 || clearRect.height == 0;
-		clearEntireTarget |= (clearRect.x == 0 && clearRect.y == 0 && clearRect.width == mActiveRenderTarget->getWidth() && clearRect.height == mActiveRenderTarget->getHeight());
+		clearEntireTarget |= (clearRect.x == 0 && clearRect.y == 0 && clearRect.width == rtProps.getWidth() && clearRect.height == rtProps.getHeight());
 
 
 		if(!clearEntireTarget)
 		if(!clearEntireTarget)
 		{
 		{
@@ -994,10 +997,12 @@ namespace BansheeEngine
 
 
 	void GLRenderSystem::setScissorTestEnable(bool enable)
 	void GLRenderSystem::setScissorTestEnable(bool enable)
 	{
 	{
+		const RenderTargetProperties& rtProps = mActiveRenderTarget->getCore()->getProperties();
+
 		// If request texture flipping, use "upper-left", otherwise use "lower-left"
 		// If request texture flipping, use "upper-left", otherwise use "lower-left"
 		bool flipping = mActiveRenderTarget->requiresTextureFlipping();
 		bool flipping = mActiveRenderTarget->requiresTextureFlipping();
 		//  GL measures from the bottom, not the top
 		//  GL measures from the bottom, not the top
-		UINT32 targetHeight = mActiveRenderTarget->getHeight();
+		UINT32 targetHeight = rtProps.getHeight();
 		// Calculate the "lower-left" corner of the viewport
 		// Calculate the "lower-left" corner of the viewport
 		GLsizei x = 0, y = 0, w = 0, h = 0;
 		GLsizei x = 0, y = 0, w = 0, h = 0;
 
 

+ 23 - 25
BansheeGLRenderSystem/Source/BsGLRenderTexture.cpp

@@ -23,34 +23,17 @@ namespace BansheeEngine
 
 
 #define DEPTHFORMAT_COUNT (sizeof(depthFormats)/sizeof(GLenum))
 #define DEPTHFORMAT_COUNT (sizeof(depthFormats)/sizeof(GLenum))
 
 
-
-	GLRenderTexture::GLRenderTexture()
-		:mFB(nullptr)
-	{
-	}
-
-	GLRenderTexture::~GLRenderTexture()
-	{
-
-	}
-
-	void GLRenderTexture::destroy_internal()
-	{
-		if(mFB != nullptr)
-			bs_delete<PoolAlloc>(mFB);
-
-		RenderTexture::destroy_internal();
-	}
-
-	void GLRenderTexture::initialize_internal()
+	GLRenderTextureCore::GLRenderTextureCore(GLRenderTexture* parent, RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+		const RENDER_SURFACE_DESC& depthStencilSurfaceDesc)
+		:RenderTextureCore(parent, properties, colorSurfaceDesc, depthStencilSurfaceDesc), mFB(nullptr)
 	{
 	{
-		if(mFB != nullptr)
+		if (mFB != nullptr)
 			bs_delete<PoolAlloc>(mFB);
 			bs_delete<PoolAlloc>(mFB);
 
 
 		mFB = bs_new<GLFrameBufferObject, PoolAlloc>();
 		mFB = bs_new<GLFrameBufferObject, PoolAlloc>();
 
 
 		GLSurfaceDesc surfaceDesc;
 		GLSurfaceDesc surfaceDesc;
-		surfaceDesc.numSamples = mMultisampleCount;
+		surfaceDesc.numSamples = properties->getMultisampleCount();
 		surfaceDesc.zoffset = 0;
 		surfaceDesc.zoffset = 0;
 
 
 		GLTexture* glTexture = static_cast<GLTexture*>(mColorSurface->getTexture().get());
 		GLTexture* glTexture = static_cast<GLTexture*>(mColorSurface->getTexture().get());
@@ -59,15 +42,19 @@ namespace BansheeEngine
 		mFB->bindSurface(0, surfaceDesc);
 		mFB->bindSurface(0, surfaceDesc);
 
 
 		GLTexture* glDepthStencilTexture = static_cast<GLTexture*>(mDepthStencilSurface->getTexture().get());
 		GLTexture* glDepthStencilTexture = static_cast<GLTexture*>(mDepthStencilSurface->getTexture().get());
-		GLPixelBufferPtr depthStencilBuffer = 
+		GLPixelBufferPtr depthStencilBuffer =
 			glDepthStencilTexture->getBuffer(mDepthStencilSurface->getFirstArraySlice(), mDepthStencilSurface->getMostDetailedMip());
 			glDepthStencilTexture->getBuffer(mDepthStencilSurface->getFirstArraySlice(), mDepthStencilSurface->getMostDetailedMip());
 
 
 		mFB->bindDepthStencil(depthStencilBuffer);
 		mFB->bindDepthStencil(depthStencilBuffer);
+	}
 
 
-		RenderTexture::initialize_internal();
+	GLRenderTextureCore::~GLRenderTextureCore()
+	{
+		if (mFB != nullptr)
+			bs_delete<PoolAlloc>(mFB);
 	}
 	}
 
 
-	void GLRenderTexture::getCustomAttribute(const String& name, void* pData) const
+	void GLRenderTextureCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name=="FBO")
 		if(name=="FBO")
 		{
 		{
@@ -79,6 +66,17 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	RenderTargetProperties* GLRenderTexture::createProperties() const
+	{
+		return bs_new<RenderTextureProperties>();
+	}
+
+	RenderTextureCore* GLRenderTexture::createCore(RenderTextureProperties* properties, const RENDER_SURFACE_DESC& colorSurfaceDesc,
+		const RENDER_SURFACE_DESC& depthStencilSurfaceDesc)
+	{
+		return bs_new<GLRenderTextureCore>(this, properties, colorSurfaceDesc, depthStencilSurfaceDesc);
+	}
+
 	GLRTTManager::GLRTTManager()
 	GLRTTManager::GLRTTManager()
     {
     {
 		detectFBOFormats();
 		detectFBOFormats();

+ 24 - 11
BansheeGLRenderSystem/Source/BsGLVertexArrayObjectManager.cpp

@@ -77,27 +77,39 @@ namespace BansheeEngine
 	const GLVertexArrayObject& GLVertexArrayObjectManager::getVAO(const GLSLGpuProgramPtr& vertexProgram,
 	const GLVertexArrayObject& GLVertexArrayObjectManager::getVAO(const GLSLGpuProgramPtr& vertexProgram,
 		const VertexDeclarationPtr& vertexDecl, const Vector<VertexBufferPtr>& boundBuffers)
 		const VertexDeclarationPtr& vertexDecl, const Vector<VertexBufferPtr>& boundBuffers)
 	{
 	{
+		UINT16 maxStreamIdx = 0;
+		const VertexDeclaration::VertexElementList& decl = vertexDecl->getElements();
+		for (auto& elem : decl)
+			maxStreamIdx = std::max(maxStreamIdx, elem.getStreamIdx());
+
+		UINT32 numStreams = maxStreamIdx + 1;
 		UINT32 numUsedBuffers = 0;
 		UINT32 numUsedBuffers = 0;
-		INT32* streamToSeqIdx = stackAllocN<INT32>((UINT32)boundBuffers.size());
+		INT32* streamToSeqIdx = stackAllocN<INT32>(numStreams);
 		GLVertexBuffer** usedBuffers = stackAllocN<GLVertexBuffer*>((UINT32)boundBuffers.size());
 		GLVertexBuffer** usedBuffers = stackAllocN<GLVertexBuffer*>((UINT32)boundBuffers.size());
 		
 		
-		const VertexDeclaration::VertexElementList& decl = vertexDecl->getElements();
+		memset(usedBuffers, 0, (UINT32)boundBuffers.size() * sizeof(GLVertexBuffer*));
+
+		for (UINT32 i = 0; i < numStreams; i++)
+			streamToSeqIdx[i] = -1;
+
 		for (auto& elem : decl)
 		for (auto& elem : decl)
 		{
 		{
 			UINT16 streamIdx = elem.getStreamIdx();
 			UINT16 streamIdx = elem.getStreamIdx();
 			if (streamIdx >= (UINT32)boundBuffers.size())
 			if (streamIdx >= (UINT32)boundBuffers.size())
-			{
-				streamToSeqIdx[streamIdx] = -1;
 				continue;
 				continue;
-			}
+
+			if (streamToSeqIdx[streamIdx] != -1) // Already visited
+				continue;
 
 
 			VertexBufferPtr vertexBuffer = boundBuffers[streamIdx];
 			VertexBufferPtr vertexBuffer = boundBuffers[streamIdx];
+			streamToSeqIdx[streamIdx] = (INT32)numUsedBuffers;
 
 
-			if (vertexBuffer == nullptr)
-				continue; // Skip unbound elements
+			if (vertexBuffer != nullptr)
+				usedBuffers[numUsedBuffers] = static_cast<GLVertexBuffer*>(vertexBuffer.get()); 
+			else
+				usedBuffers[numUsedBuffers] = nullptr;
 
 
-			streamToSeqIdx[streamIdx] = (INT32)numUsedBuffers;
-			usedBuffers[numUsedBuffers++] = static_cast<GLVertexBuffer*>(vertexBuffer.get());
+			numUsedBuffers++;
 		}
 		}
 		
 		
 		GLVertexArrayObject wantedVAO(0, vertexProgram->getInternalID(), usedBuffers, numUsedBuffers);
 		GLVertexArrayObject wantedVAO(0, vertexProgram->getInternalID(), usedBuffers, numUsedBuffers);
@@ -167,7 +179,7 @@ namespace BansheeEngine
 			glEnableVertexAttribArray(attribLocation);
 			glEnableVertexAttribArray(attribLocation);
 		}
 		}
 
 
-		wantedVAO.mAttachedBuffers = (GLVertexBuffer**)bs_alloc<GLVertexBuffer*>(numUsedBuffers);
+		wantedVAO.mAttachedBuffers = (GLVertexBuffer**)bs_alloc(numUsedBuffers * sizeof(GLVertexBuffer*));
 		for (UINT32 i = 0; i < numUsedBuffers; i++)
 		for (UINT32 i = 0; i < numUsedBuffers; i++)
 		{
 		{
 			wantedVAO.mAttachedBuffers[i] = usedBuffers[i];
 			wantedVAO.mAttachedBuffers[i] = usedBuffers[i];
@@ -183,7 +195,8 @@ namespace BansheeEngine
 		return *iter.first;
 		return *iter.first;
 	}
 	}
 
 
-	void GLVertexArrayObjectManager::notifyBufferDestroyed(const GLVertexArrayObject& vao)
+	// Note: This must receieve a copy and not a ref because original will be destroyed
+	void GLVertexArrayObjectManager::notifyBufferDestroyed(GLVertexArrayObject vao)
 	{
 	{
 		mVAObjects.erase(vao);
 		mVAObjects.erase(vao);
 
 

+ 3 - 3
BansheeGLRenderSystem/Source/BsWin32GLSupport.cpp

@@ -31,11 +31,11 @@ namespace BansheeEngine
 		if(parentWindow != nullptr)
 		if(parentWindow != nullptr)
 		{
 		{
 			HWND hWnd;
 			HWND hWnd;
-			parentWindow->getCustomAttribute("WINDOW", &hWnd);
+			parentWindow->getCore()->getCustomAttribute("WINDOW", &hWnd);
 			desc.platformSpecific["parentWindowHandle"] = toString((UINT64)hWnd);
 			desc.platformSpecific["parentWindowHandle"] = toString((UINT64)hWnd);
 		}
 		}
 
 
-		Win32Window* window = new (bs_alloc<Win32Window, PoolAlloc>()) Win32Window(desc, *this);
+		Win32Window* window = new (bs_alloc<Win32Window, PoolAlloc>()) Win32Window(*this);
 		
 		
 		if(!mInitialWindow)
 		if(!mInitialWindow)
 			mInitialWindow = window;
 			mInitialWindow = window;
@@ -65,7 +65,7 @@ namespace BansheeEngine
 		if(_wglGetExtensionsString == nullptr)
 		if(_wglGetExtensionsString == nullptr)
 			return;
 			return;
 
 
-		const char *wgl_extensions = _wglGetExtensionsString(mInitialWindow->_getHDC());
+		const char *wgl_extensions = _wglGetExtensionsString(mInitialWindow->getCore()->_getHDC());
 
 
 		// Parse them, and add them to the main list
 		// Parse them, and add them to the main list
 		StringStream ext;
 		StringStream ext;

+ 0 - 5
BansheeGLRenderSystem/Source/BsWin32VideoModeInfo.cpp

@@ -98,11 +98,6 @@ namespace BansheeEngine
 		mDesktopVideoMode = desktopVideoMode;
 		mDesktopVideoMode = desktopVideoMode;
 	}
 	}
 
 
-	Win32VideoOutputInfo::~Win32VideoOutputInfo()
-	{
-		CloseHandle(mMonitorHandle);
-	}
-
 	Win32VideoMode::Win32VideoMode(UINT32 width, UINT32 height, float refreshRate, UINT32 outputIdx)
 	Win32VideoMode::Win32VideoMode(UINT32 width, UINT32 height, float refreshRate, UINT32 outputIdx)
 		:VideoMode(width, height, refreshRate, outputIdx)
 		:VideoMode(width, height, refreshRate, outputIdx)
 	{ }
 	{ }

+ 213 - 183
BansheeGLRenderSystem/Source/BsWin32Window.cpp

@@ -19,26 +19,9 @@ namespace BansheeEngine
 {
 {
 	#define _MAX_CLASS_NAME_ 128
 	#define _MAX_CLASS_NAME_ 128
 
 
-	Win32Window::Win32Window(const RENDER_WINDOW_DESC& desc, Win32GLSupport &glsupport)
-		:RenderWindow(desc), mGLSupport(glsupport), mContext(0), mWindowedStyle(0), mWindowedStyleEx(0)
-	{
-		mIsFullScreen = false;
-		mHWnd = 0;
-		mIsExternal = false;
-		mIsExternalGLControl = false;
-		mSizing = false;
-		mClosed = false;
-		mDisplayFrequency = 0;
-		mActive = false;
-		mDeviceName = NULL;
-	}
-
-	Win32Window::~Win32Window()
-	{
-
-	}
-
-	void Win32Window::initialize_internal()
+	Win32WindowCore::Win32WindowCore(Win32Window* parentWnd, RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc, Win32GLSupport& glsupport)
+		:RenderWindowCore(parentWnd, properties), mGLSupport(glsupport), mContext(0), mWindowedStyle(0), mWindowedStyleEx(0), mHWnd(0), mIsExternal(false),
+		mIsExternalGLControl(false), mDisplayFrequency(0), mDeviceName(nullptr)
 	{
 	{
 #ifdef BS_STATIC_LIB
 #ifdef BS_STATIC_LIB
 		HINSTANCE hInst = GetModuleHandle(NULL);
 		HINSTANCE hInst = GetModuleHandle(NULL);
@@ -46,19 +29,20 @@ namespace BansheeEngine
 		HINSTANCE hInst = GetModuleHandle(MODULE_NAME.c_str());
 		HINSTANCE hInst = GetModuleHandle(MODULE_NAME.c_str());
 #endif
 #endif
 
 
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+
 		mHWnd = 0;
 		mHWnd = 0;
-		mName = mDesc.title;
-		mIsFullScreen = mDesc.fullscreen;
-		mClosed = false;
+		props->mName = desc.title;
+		props->mIsFullScreen = desc.fullscreen;
 		mIsChild = false;
 		mIsChild = false;
-		mDisplayFrequency = Math::roundToInt(mDesc.videoMode.getRefreshRate());
-		mColorDepth = 32;
+		mDisplayFrequency = Math::roundToInt(desc.videoMode.getRefreshRate());
+		props->mColorDepth = 32;
 		HWND parent = 0;
 		HWND parent = 0;
 
 
 		NameValuePairList::const_iterator opt;
 		NameValuePairList::const_iterator opt;
-		NameValuePairList::const_iterator end = mDesc.platformSpecific.end();
+		NameValuePairList::const_iterator end = desc.platformSpecific.end();
 
 
-		if ((opt = mDesc.platformSpecific.find("externalWindowHandle")) != end)
+		if ((opt = desc.platformSpecific.find("externalWindowHandle")) != end)
 		{
 		{
 			mHWnd = (HWND)parseUnsignedInt(opt->second);
 			mHWnd = (HWND)parseUnsignedInt(opt->second);
 			if (mHWnd)
 			if (mHWnd)
@@ -66,22 +50,22 @@ namespace BansheeEngine
 				mIsExternal = true;
 				mIsExternal = true;
 			}
 			}
 
 
-			if ((opt = mDesc.platformSpecific.find("externalGLControl")) != end) {
+			if ((opt = desc.platformSpecific.find("externalGLControl")) != end) {
 				mIsExternalGLControl = parseBool(opt->second);
 				mIsExternalGLControl = parseBool(opt->second);
 			}
 			}
 		}
 		}
 
 
 		HGLRC glrc = 0;
 		HGLRC glrc = 0;
-		if ((opt = mDesc.platformSpecific.find("externalGLContext")) != end)
+		if ((opt = desc.platformSpecific.find("externalGLContext")) != end)
 		{
 		{
 			glrc = (HGLRC)parseUnsignedLong(opt->second);
 			glrc = (HGLRC)parseUnsignedLong(opt->second);
 		}
 		}
 
 
-		if ((opt = mDesc.platformSpecific.find("parentWindowHandle")) != end)
+		if ((opt = desc.platformSpecific.find("parentWindowHandle")) != end)
 		{
 		{
 			parent = (HWND)parseUnsignedInt(opt->second);
 			parent = (HWND)parseUnsignedInt(opt->second);
 			mIsChild = true;
 			mIsChild = true;
-			mIsFullScreen = false;
+			props->mIsFullScreen = false;
 		}
 		}
 
 
 		HMONITOR hMonitor = NULL;
 		HMONITOR hMonitor = NULL;
@@ -89,36 +73,36 @@ namespace BansheeEngine
 		UINT32 numOutputs = videoModeInfo.getNumOutputs();
 		UINT32 numOutputs = videoModeInfo.getNumOutputs();
 		if (numOutputs > 0)
 		if (numOutputs > 0)
 		{
 		{
-			UINT32 actualMonitorIdx = std::min(mDesc.videoMode.getOutputIdx(), numOutputs - 1);
+			UINT32 actualMonitorIdx = std::min(desc.videoMode.getOutputIdx(), numOutputs - 1);
 			const Win32VideoOutputInfo& outputInfo = static_cast<const Win32VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 			const Win32VideoOutputInfo& outputInfo = static_cast<const Win32VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 			hMonitor = outputInfo.getMonitorHandle();
 			hMonitor = outputInfo.getMonitorHandle();
 		}
 		}
 
 
-		if (!mIsFullScreen)
+		if (!props->mIsFullScreen)
 		{
 		{
 			// Make sure we don't exceed desktop color depth
 			// Make sure we don't exceed desktop color depth
-			if ((int)mColorDepth > GetDeviceCaps(GetDC(0), BITSPIXEL))
-				mColorDepth = GetDeviceCaps(GetDC(0), BITSPIXEL);
+			if ((int)props->mColorDepth > GetDeviceCaps(GetDC(0), BITSPIXEL))
+				props->mColorDepth = GetDeviceCaps(GetDC(0), BITSPIXEL);
 		}
 		}
 
 
 		mWindowedStyle = WS_VISIBLE | WS_CLIPCHILDREN;
 		mWindowedStyle = WS_VISIBLE | WS_CLIPCHILDREN;
 		mWindowedStyleEx = 0;
 		mWindowedStyleEx = 0;
 
 
-		if (!mIsFullScreen)
+		if (!props->mIsFullScreen)
 		{
 		{
 			if (parent)
 			if (parent)
 			{
 			{
-				if (mDesc.toolWindow)
+				if (desc.toolWindow)
 					mWindowedStyleEx = WS_EX_TOOLWINDOW;
 					mWindowedStyleEx = WS_EX_TOOLWINDOW;
 				else
 				else
 					mWindowedStyle |= WS_CHILD;
 					mWindowedStyle |= WS_CHILD;
 			}
 			}
 
 
-			if (!parent || mDesc.toolWindow)
+			if (!parent || desc.toolWindow)
 			{
 			{
-				if (mDesc.border == WindowBorder::None)
+				if (desc.border == WindowBorder::None)
 					mWindowedStyle |= WS_POPUP;
 					mWindowedStyle |= WS_POPUP;
-				else if (mDesc.border == WindowBorder::Fixed)
+				else if (desc.border == WindowBorder::Fixed)
 					mWindowedStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
 					mWindowedStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
 					WS_SYSMENU | WS_MINIMIZEBOX;
 					WS_SYSMENU | WS_MINIMIZEBOX;
 				else
 				else
@@ -136,8 +120,8 @@ namespace BansheeEngine
 				POINT windowAnchorPoint;
 				POINT windowAnchorPoint;
 
 
 				// Fill in anchor point.
 				// Fill in anchor point.
-				windowAnchorPoint.x = mDesc.left;
-				windowAnchorPoint.y = mDesc.top;
+				windowAnchorPoint.x = desc.left;
+				windowAnchorPoint.y = desc.top;
 
 
 				// Get the nearest monitor to this window.
 				// Get the nearest monitor to this window.
 				hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST);
 				hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST);
@@ -155,21 +139,21 @@ namespace BansheeEngine
 
 
 			strcpy_s(mDeviceName, devNameLen + 1, monitorInfoEx.szDevice);
 			strcpy_s(mDeviceName, devNameLen + 1, monitorInfoEx.szDevice);
 
 
-			UINT32 left = mDesc.left;
-			UINT32 top = mDesc.top;
+			UINT32 left = desc.left;
+			UINT32 top = desc.top;
 
 
 			// No specified top left -> Center the window in the middle of the monitor
 			// No specified top left -> Center the window in the middle of the monitor
 			if (left == -1 || top == -1)
 			if (left == -1 || top == -1)
-			{				
-				int screenw = monitorInfoEx.rcWork.right  - monitorInfoEx.rcWork.left;
+			{
+				int screenw = monitorInfoEx.rcWork.right - monitorInfoEx.rcWork.left;
 				int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top;
 				int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top;
 
 
 				unsigned int winWidth, winHeight;
 				unsigned int winWidth, winHeight;
-				getAdjustedWindowSize(mDesc.videoMode.getWidth(), mDesc.videoMode.getHeight(), &winWidth, &winHeight);
+				getAdjustedWindowSize(desc.videoMode.getWidth(), desc.videoMode.getHeight(), &winWidth, &winHeight);
 
 
 				// clamp window dimensions to screen size
 				// clamp window dimensions to screen size
-				int outerw = (int(winWidth) < screenw)? int(winWidth) : screenw;
-				int outerh = (int(winHeight) < screenh)? int(winHeight) : screenh;
+				int outerw = (int(winWidth) < screenw) ? int(winWidth) : screenw;
+				int outerh = (int(winHeight) < screenh) ? int(winHeight) : screenh;
 
 
 				if (left == -1)
 				if (left == -1)
 					left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2;
 					left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2;
@@ -187,49 +171,49 @@ namespace BansheeEngine
 				top += monitorInfoEx.rcWork.top;
 				top += monitorInfoEx.rcWork.top;
 			}
 			}
 
 
-			mWidth = mDesc.videoMode.getWidth();
-			mHeight = mDesc.videoMode.getHeight();
-			mTop = top;
-			mLeft = left;
+			props->mWidth = desc.videoMode.getWidth();
+			props->mHeight = desc.videoMode.getHeight();
+			props->mTop = top;
+			props->mLeft = left;
 
 
 			DWORD dwStyle = 0;
 			DWORD dwStyle = 0;
 			DWORD dwStyleEx = 0;
 			DWORD dwStyleEx = 0;
-			if (mIsFullScreen)
+			if (props->mIsFullScreen)
 			{
 			{
 				dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_POPUP;
 				dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_POPUP;
-				mTop = monitorInfoEx.rcMonitor.top;
-				mLeft = monitorInfoEx.rcMonitor.left;											
+				props->mTop = monitorInfoEx.rcMonitor.top;
+				props->mLeft = monitorInfoEx.rcMonitor.left;
 			}
 			}
 			else
 			else
-			{			
+			{
 				dwStyle = mWindowedStyle;
 				dwStyle = mWindowedStyle;
 				dwStyleEx = mWindowedStyleEx;
 				dwStyleEx = mWindowedStyleEx;
 
 
 				int screenw = GetSystemMetrics(SM_CXSCREEN);
 				int screenw = GetSystemMetrics(SM_CXSCREEN);
 				int screenh = GetSystemMetrics(SM_CYSCREEN);
 				int screenh = GetSystemMetrics(SM_CYSCREEN);
 
 
-				if (!mDesc.outerDimensions)
+				if (!desc.outerDimensions)
 				{
 				{
 					// Calculate window dimensions required
 					// Calculate window dimensions required
 					// to get the requested client area
 					// to get the requested client area
-					SetRect(&rc, 0, 0, mWidth, mHeight);
+					SetRect(&rc, 0, 0, props->mWidth, props->mHeight);
 					AdjustWindowRect(&rc, dwStyle, false);
 					AdjustWindowRect(&rc, dwStyle, false);
-					mWidth = rc.right - rc.left;
-					mHeight = rc.bottom - rc.top;
+					props->mWidth = rc.right - rc.left;
+					props->mHeight = rc.bottom - rc.top;
 
 
 					// Clamp window rect to the nearest display monitor.
 					// Clamp window rect to the nearest display monitor.
-					if (mLeft < monitorInfoEx.rcWork.left)
-						mLeft = monitorInfoEx.rcWork.left;		
+					if (props->mLeft < monitorInfoEx.rcWork.left)
+						props->mLeft = monitorInfoEx.rcWork.left;
 
 
-					if (mTop < monitorInfoEx.rcWork.top)					
-						mTop = monitorInfoEx.rcWork.top;					
+					if (props->mTop < monitorInfoEx.rcWork.top)
+						props->mTop = monitorInfoEx.rcWork.top;
 
 
-					if ((int)mWidth > monitorInfoEx.rcWork.right - mLeft)					
-						mWidth = monitorInfoEx.rcWork.right - mLeft;	
+					if ((int)props->mWidth > monitorInfoEx.rcWork.right - props->mLeft)
+						props->mWidth = monitorInfoEx.rcWork.right - props->mLeft;
 
 
-					if ((int)mHeight > monitorInfoEx.rcWork.bottom - mTop)					
-						mHeight = monitorInfoEx.rcWork.bottom - mTop;		
-				}			
+					if ((int)props->mHeight > monitorInfoEx.rcWork.bottom - props->mTop)
+						props->mHeight = monitorInfoEx.rcWork.bottom - props->mTop;
+				}
 			}
 			}
 
 
 			// register class and create window
 			// register class and create window
@@ -238,15 +222,15 @@ namespace BansheeEngine
 				(HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "GLWindow" };
 				(HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "GLWindow" };
 			RegisterClass(&wc);
 			RegisterClass(&wc);
 
 
-			if (mIsFullScreen)
+			if (props->mIsFullScreen)
 			{
 			{
 				DEVMODE displayDeviceMode;
 				DEVMODE displayDeviceMode;
 
 
 				memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
 				memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
 				displayDeviceMode.dmSize = sizeof(DEVMODE);
 				displayDeviceMode.dmSize = sizeof(DEVMODE);
-				displayDeviceMode.dmBitsPerPel = mColorDepth;
-				displayDeviceMode.dmPelsWidth = mWidth;
-				displayDeviceMode.dmPelsHeight = mHeight;
+				displayDeviceMode.dmBitsPerPel = props->mColorDepth;
+				displayDeviceMode.dmPelsWidth = props->mWidth;
+				displayDeviceMode.dmPelsHeight = props->mHeight;
 				displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
 				displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
 
 
 				if (mDisplayFrequency)
 				if (mDisplayFrequency)
@@ -267,50 +251,50 @@ namespace BansheeEngine
 			}
 			}
 
 
 			// Pass pointer to self as WM_CREATE parameter
 			// Pass pointer to self as WM_CREATE parameter
-			mHWnd = CreateWindowEx(dwStyleEx, "GLWindow", mDesc.title.c_str(),
-				dwStyle, mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this);		
+			mHWnd = CreateWindowEx(dwStyleEx, "GLWindow", desc.title.c_str(),
+				dwStyle, props->mLeft, props->mTop, props->mWidth, props->mHeight, parent, 0, hInst, this);
 		}
 		}
 
 
 		RECT rc;
 		RECT rc;
 
 
 		GetWindowRect(mHWnd, &rc);
 		GetWindowRect(mHWnd, &rc);
-		mTop = rc.top;
-		mLeft = rc.left;
+		props->mTop = rc.top;
+		props->mLeft = rc.left;
 
 
 		GetClientRect(mHWnd, &rc);
 		GetClientRect(mHWnd, &rc);
-		mWidth = rc.right;
-		mHeight = rc.bottom;
+		props->mWidth = rc.right;
+		props->mHeight = rc.bottom;
 
 
 		mHDC = GetDC(mHWnd);
 		mHDC = GetDC(mHWnd);
 
 
 		if (!mIsExternalGLControl)
 		if (!mIsExternalGLControl)
 		{
 		{
-			int testMultisample = mMultisampleCount;
-			bool testHwGamma = mDesc.gamma;
-			bool formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testMultisample, testHwGamma);
+			int testMultisample = props->mMultisampleCount;
+			bool testHwGamma = desc.gamma;
+			bool formatOk = mGLSupport.selectPixelFormat(mHDC, props->mColorDepth, testMultisample, testHwGamma);
 			if (!formatOk)
 			if (!formatOk)
 			{
 			{
-				if (mMultisampleCount > 0)
+				if (props->mMultisampleCount > 0)
 				{
 				{
 					// Try without multisampling
 					// Try without multisampling
 					testMultisample = 0;
 					testMultisample = 0;
-					formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testMultisample, testHwGamma);
+					formatOk = mGLSupport.selectPixelFormat(mHDC, props->mColorDepth, testMultisample, testHwGamma);
 				}
 				}
 
 
-				if (!formatOk && mDesc.gamma)
+				if (!formatOk && desc.gamma)
 				{
 				{
 					// Try without sRGB
 					// Try without sRGB
 					testHwGamma = false;
 					testHwGamma = false;
-					testMultisample = mMultisampleCount;
-					formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testMultisample, testHwGamma);
+					testMultisample = props->mMultisampleCount;
+					formatOk = mGLSupport.selectPixelFormat(mHDC, props->mColorDepth, testMultisample, testHwGamma);
 				}
 				}
 
 
-				if (!formatOk && mDesc.gamma && (mMultisampleCount > 0))
+				if (!formatOk && desc.gamma && (props->mMultisampleCount > 0))
 				{
 				{
 					// Try without both
 					// Try without both
 					testHwGamma = false;
 					testHwGamma = false;
 					testMultisample = 0;
 					testMultisample = 0;
-					formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testMultisample, testHwGamma);
+					formatOk = mGLSupport.selectPixelFormat(mHDC, props->mColorDepth, testMultisample, testHwGamma);
 				}
 				}
 
 
 				if (!formatOk)
 				if (!formatOk)
@@ -320,27 +304,27 @@ namespace BansheeEngine
 
 
 			// Record what gamma option we used in the end
 			// Record what gamma option we used in the end
 			// this will control enabling of sRGB state flags when used
 			// this will control enabling of sRGB state flags when used
-			mHwGamma = testHwGamma;
-			mMultisampleCount = testMultisample;
+			props->mHwGamma = testHwGamma;
+			props->mMultisampleCount = testMultisample;
 		}
 		}
-		
-		mActive = true;
-		mContext = mGLSupport.createContext(mHDC, glrc);
 
 
-		RenderWindow::initialize_internal();
+		props->mActive = true;
+		mContext = mGLSupport.createContext(mHDC, glrc);
 	}
 	}
 
 
-	void Win32Window::destroy_internal()
+	Win32WindowCore::~Win32WindowCore()
 	{
 	{
 		if (!mHWnd)
 		if (!mHWnd)
 			return;
 			return;
 
 
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+
 		// Unregister and destroy GLContext
 		// Unregister and destroy GLContext
 		bs_delete(mContext);
 		bs_delete(mContext);
 
 
 		if (!mIsExternal)
 		if (!mIsExternal)
 		{
 		{
-			if (mIsFullScreen)
+			if (props->mIsFullScreen)
 				ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
 				ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
 			DestroyWindow(mHWnd);
 			DestroyWindow(mHWnd);
 		}
 		}
@@ -350,8 +334,7 @@ namespace BansheeEngine
 			ReleaseDC(mHWnd, mHDC);
 			ReleaseDC(mHWnd, mHDC);
 		}
 		}
 
 
-		mActive = false;
-		mClosed = true;
+		props->mActive = false;
 		mHDC = 0; // no release thanks to CS_OWNDC wndclass style
 		mHDC = 0; // no release thanks to CS_OWNDC wndclass style
 		mHWnd = 0;
 		mHWnd = 0;
 
 
@@ -361,10 +344,10 @@ namespace BansheeEngine
 			mDeviceName = NULL;
 			mDeviceName = NULL;
 		}
 		}
 
 
-		RenderWindow::destroy_internal();
+		markCoreDirty();
 	}
 	}
 
 
-	void Win32Window::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
+	void Win32WindowCore::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -376,19 +359,21 @@ namespace BansheeEngine
 		if (numOutputs == 0)
 		if (numOutputs == 0)
 			return;
 			return;
 
 
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+
 		UINT32 actualMonitorIdx = std::min(monitorIdx, numOutputs - 1);
 		UINT32 actualMonitorIdx = std::min(monitorIdx, numOutputs - 1);
 		const Win32VideoOutputInfo& outputInfo = static_cast<const Win32VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 		const Win32VideoOutputInfo& outputInfo = static_cast<const Win32VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 
 
-		bool oldFullscreen = mIsFullScreen;
+		bool oldFullscreen = props->mIsFullScreen;
 
 
 		mDisplayFrequency = Math::roundToInt(refreshRate);
 		mDisplayFrequency = Math::roundToInt(refreshRate);
-		mIsFullScreen = true;
+		props->mIsFullScreen = true;
 
 
 		DEVMODE displayDeviceMode;
 		DEVMODE displayDeviceMode;
 
 
 		memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
 		memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
 		displayDeviceMode.dmSize = sizeof(DEVMODE);
 		displayDeviceMode.dmSize = sizeof(DEVMODE);
-		displayDeviceMode.dmBitsPerPel = mColorDepth;
+		displayDeviceMode.dmBitsPerPel = props->mColorDepth;
 		displayDeviceMode.dmPelsWidth = width;
 		displayDeviceMode.dmPelsWidth = width;
 		displayDeviceMode.dmPelsHeight = height;
 		displayDeviceMode.dmPelsHeight = height;
 		displayDeviceMode.dmDisplayFrequency = mDisplayFrequency;
 		displayDeviceMode.dmDisplayFrequency = mDisplayFrequency;
@@ -406,38 +391,42 @@ namespace BansheeEngine
 			BS_EXCEPT(RenderingAPIException, "ChangeDisplaySettings failed");
 			BS_EXCEPT(RenderingAPIException, "ChangeDisplaySettings failed");
 		}
 		}
 
 
-		mTop = monitorInfo.rcMonitor.top;
-		mLeft = monitorInfo.rcMonitor.left;
-		mWidth = width;
-		mHeight = height;
+		props->mTop = monitorInfo.rcMonitor.top;
+		props->mLeft = monitorInfo.rcMonitor.left;
+		props->mWidth = width;
+		props->mHeight = height;
+
+		SetWindowPos(mHWnd, HWND_TOP, props->mLeft, props->mTop, width, height, SWP_NOACTIVATE);
 
 
-		SetWindowPos(mHWnd, HWND_TOP, mLeft, mTop, width, height, SWP_NOACTIVATE);
+		markCoreDirty();
 	}
 	}
 
 
-	void Win32Window::setFullscreen(const VideoMode& mode)
+	void Win32WindowCore::setFullscreen(const VideoMode& mode)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		setFullscreen(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getOutputIdx());
 		setFullscreen(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getOutputIdx());
 	}
 	}
 
 
-	void Win32Window::setWindowed(UINT32 width, UINT32 height)
+	void Win32WindowCore::setWindowed(UINT32 width, UINT32 height)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (!mIsFullScreen)
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+
+		if (!props->mIsFullScreen)
 			return;
 			return;
 
 
-		mIsFullScreen = false;
-		mWidth = width;
-		mHeight = height;
+		props->mIsFullScreen = false;
+		props->mWidth = width;
+		props->mHeight = height;
 
 
 		// Drop out of fullscreen
 		// Drop out of fullscreen
 		ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
 		ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
 
 
 		// Calculate overall dimensions for requested client area
 		// Calculate overall dimensions for requested client area
 		UINT32 winWidth, winHeight;
 		UINT32 winWidth, winHeight;
-		getAdjustedWindowSize(mWidth, mHeight, &winWidth, &winHeight);
+		getAdjustedWindowSize(props->mWidth, props->mHeight, &winWidth, &winHeight);
 
 
 		// Deal with centering when switching down to smaller resolution
 		// Deal with centering when switching down to smaller resolution
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
@@ -458,48 +447,36 @@ namespace BansheeEngine
 			SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
 			SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
 
 
 		_windowMovedOrResized();
 		_windowMovedOrResized();
-	}
-
-	bool Win32Window::isActive(void) const
-	{
-		if (isFullScreen())
-			return isVisible();
-
-		return mActive && isVisible();
-	}
 
 
-	bool Win32Window::isVisible() const
-	{
-		return (mHWnd && !IsIconic(mHWnd));
-	}
-
-	bool Win32Window::isClosed() const
-	{
-		return mClosed;
+		markCoreDirty();
 	}
 	}
 
 
-	void Win32Window::move(INT32 left, INT32 top)
+	void Win32WindowCore::move(INT32 left, INT32 top)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd && !mIsFullScreen)
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+		if (mHWnd && !props->mIsFullScreen)
 		{
 		{
-			mLeft = left;
-			mTop = top;
+			props->mLeft = left;
+			props->mTop = top;
 
 
 			SetWindowPos(mHWnd, 0, left, top, 0, 0,
 			SetWindowPos(mHWnd, 0, left, top, 0, 0,
 				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
 				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+			markCoreDirty();
 		}
 		}
 	}
 	}
 
 
-	void Win32Window::resize(UINT32 width, UINT32 height)
+	void Win32WindowCore::resize(UINT32 width, UINT32 height)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd && !mIsFullScreen)
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+		if (mHWnd && !props->mIsFullScreen)
 		{
 		{
-			mWidth = width;
-			mHeight = height;
+			props->mWidth = width;
+			props->mHeight = height;
 
 
 			RECT rc = { 0, 0, width, height };
 			RECT rc = { 0, 0, width, height };
 			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
 			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
@@ -507,10 +484,12 @@ namespace BansheeEngine
 			height = rc.bottom - rc.top;
 			height = rc.bottom - rc.top;
 			SetWindowPos(mHWnd, 0, 0, 0, width, height,
 			SetWindowPos(mHWnd, 0, 0, 0, width, height,
 				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
 				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+			markCoreDirty();
 		}
 		}
 	}
 	}
 
 
-	void Win32Window::swapBuffers()
+	void Win32WindowCore::swapBuffers()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -519,12 +498,12 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void Win32Window::copyToMemory(PixelData &dst, FrameBuffer buffer)
+	void Win32WindowCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if ((dst.getLeft() < 0) || (dst.getRight() > mWidth) ||
-			(dst.getTop() < 0) || (dst.getBottom() > mHeight) ||
+		if ((dst.getLeft() < 0) || (dst.getRight() > getProperties().getWidth()) ||
+			(dst.getTop() < 0) || (dst.getBottom() > getProperties().getHeight()) ||
 			(dst.getFront() != 0) || (dst.getBack() != 1))
 			(dst.getFront() != 0) || (dst.getBack() != 1))
 		{
 		{
 			BS_EXCEPT(InvalidParametersException, "Invalid box.");
 			BS_EXCEPT(InvalidParametersException, "Invalid box.");
@@ -532,7 +511,7 @@ namespace BansheeEngine
 
 
 		if (buffer == FB_AUTO)
 		if (buffer == FB_AUTO)
 		{
 		{
-			buffer = mIsFullScreen? FB_FRONT : FB_BACK;
+			buffer = getProperties().isFullScreen() ? FB_FRONT : FB_BACK;
 		}
 		}
 
 
 		GLenum format = BansheeEngine::GLPixelUtil::getGLOriginFormat(dst.getFormat());
 		GLenum format = BansheeEngine::GLPixelUtil::getGLOriginFormat(dst.getFormat());
@@ -573,27 +552,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	Vector2I Win32Window::screenToWindowPos(const Vector2I& screenPos) const
-	{
-		POINT pos;
-		pos.x = screenPos.x;
-		pos.y = screenPos.y;
-
-		ScreenToClient(mHWnd, &pos);
-		return Vector2I(pos.x, pos.y);
-	}
-
-	Vector2I Win32Window::windowToScreenPos(const Vector2I& windowPos) const
-	{
-		POINT pos;
-		pos.x = windowPos.x;
-		pos.y = windowPos.y;
-
-		ClientToScreen(mHWnd, &pos);
-		return Vector2I(pos.x, pos.y);
-	}	
-
-	void Win32Window::getCustomAttribute(const String& name, void* pData) const
+	void Win32WindowCore::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name == "GLCONTEXT") 
 		if(name == "GLCONTEXT") 
 		{
 		{
@@ -608,7 +567,7 @@ namespace BansheeEngine
 		} 
 		} 
 	}
 	}
 
 
-	void Win32Window::setActive(bool state)
+	void Win32WindowCore::setActive(bool state)
 	{	
 	{	
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -627,9 +586,10 @@ namespace BansheeEngine
 			}						
 			}						
 		}
 		}
 		
 		
-		mActive = state;
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+		props->mActive = state;
 
 
-		if( mIsFullScreen )
+		if(props->mIsFullScreen)
 		{
 		{
 			if( state == false )
 			if( state == false )
 			{	//Restore Desktop
 			{	//Restore Desktop
@@ -644,9 +604,9 @@ namespace BansheeEngine
 
 
 				memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
 				memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
 				displayDeviceMode.dmSize = sizeof(DEVMODE);
 				displayDeviceMode.dmSize = sizeof(DEVMODE);
-				displayDeviceMode.dmBitsPerPel = mColorDepth;
-				displayDeviceMode.dmPelsWidth = mWidth;
-				displayDeviceMode.dmPelsHeight = mHeight;
+				displayDeviceMode.dmBitsPerPel = props->mColorDepth;
+				displayDeviceMode.dmPelsWidth = props->mWidth;
+				displayDeviceMode.dmPelsHeight = props->mHeight;
 				displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
 				displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
 				if (mDisplayFrequency)
 				if (mDisplayFrequency)
 				{
 				{
@@ -656,13 +616,16 @@ namespace BansheeEngine
 				ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL);
 				ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL);
 			}
 			}
 		}
 		}
+
+		markCoreDirty();
 	}
 	}
 
 
-	void Win32Window::setHidden(bool hidden)
+	void Win32WindowCore::setHidden(bool hidden)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		mHidden = hidden;
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
+		props->mHidden = hidden;
 		if (!mIsExternal)
 		if (!mIsExternal)
 		{
 		{
 			if (hidden)
 			if (hidden)
@@ -670,27 +633,32 @@ namespace BansheeEngine
 			else
 			else
 				ShowWindow(mHWnd, SW_SHOWNORMAL);
 				ShowWindow(mHWnd, SW_SHOWNORMAL);
 		}
 		}
+
+		markCoreDirty();
 	}
 	}
 
 
-	void Win32Window::_windowMovedOrResized()
+	void Win32WindowCore::_windowMovedOrResized()
 	{
 	{
 		if (!mHWnd || IsIconic(mHWnd))
 		if (!mHWnd || IsIconic(mHWnd))
 			return;
 			return;
 
 
 		RECT rc;
 		RECT rc;
 
 
+		Win32RenderWindowProperties* props = static_cast<Win32RenderWindowProperties*>(mProperties);
 		GetWindowRect(mHWnd, &rc);
 		GetWindowRect(mHWnd, &rc);
-		mTop = rc.top;
-		mLeft = rc.left;
+		props->mTop = rc.top;
+		props->mLeft = rc.left;
 
 
 		GetClientRect(mHWnd, &rc);
 		GetClientRect(mHWnd, &rc);
-		mWidth = rc.right - rc.left;
-		mHeight = rc.bottom - rc.top;
+		props->mWidth = rc.right - rc.left;
+		props->mHeight = rc.bottom - rc.top;
 
 
-		RenderWindow::_windowMovedOrResized();
+		markCoreDirty();
+
+		RenderWindowCore::_windowMovedOrResized();
 	}
 	}
 
 
-	void Win32Window::getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight, UINT32* winWidth, UINT32* winHeight)
+	void Win32WindowCore::getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight, UINT32* winWidth, UINT32* winHeight)
 	{
 	{
 		RECT rc;
 		RECT rc;
 		SetRect(&rc, 0, 0, clientWidth, clientHeight);
 		SetRect(&rc, 0, 0, clientWidth, clientHeight);
@@ -717,4 +685,66 @@ namespace BansheeEngine
 		if (*winHeight > (UINT32)maxH)
 		if (*winHeight > (UINT32)maxH)
 			*winHeight = maxH;
 			*winHeight = maxH;
 	}
 	}
+
+	Win32Window::Win32Window(Win32GLSupport &glsupport)
+		:mGLSupport(glsupport)
+	{
+
+	}
+
+	void Win32Window::getCustomAttribute(const String& name, void* pData) const
+	{
+		THROW_IF_CORE_THREAD;
+
+		if (name == "WINDOW")
+		{
+			HWND *pWnd = (HWND*)pData;
+			*pWnd = mHWnd;
+			return;
+		}
+
+		RenderWindow::getCustomAttribute(name, pData);
+	}
+
+	Vector2I Win32Window::screenToWindowPos(const Vector2I& screenPos) const
+	{
+		POINT pos;
+		pos.x = screenPos.x;
+		pos.y = screenPos.y;
+
+		ScreenToClient(mHWnd, &pos);
+		return Vector2I(pos.x, pos.y);
+	}
+
+	Vector2I Win32Window::windowToScreenPos(const Vector2I& windowPos) const
+	{
+		POINT pos;
+		pos.x = windowPos.x;
+		pos.y = windowPos.y;
+
+		ClientToScreen(mHWnd, &pos);
+		return Vector2I(pos.x, pos.y);
+	}
+
+	Win32WindowCore* Win32Window::getCore() const
+	{
+		return static_cast<Win32WindowCore*>(mCore);
+	}
+
+	void Win32Window::initialize_internal()
+	{
+		RenderWindow::initialize_internal();
+
+		mCore->getCustomAttribute("WINDOW", (void*)&mHWnd);
+	}
+
+	RenderTargetProperties* Win32Window::createProperties() const
+	{
+		return bs_new<RenderWindowProperties>();
+	}
+
+	RenderWindowCore* Win32Window::createCore(RenderWindowProperties* properties, const RENDER_WINDOW_DESC& desc)
+	{
+		return bs_new<Win32WindowCore>(this, properties, desc, mGLSupport);
+	}
 }
 }

+ 2 - 1
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -140,7 +140,8 @@ namespace BansheeEngine
 
 
 		// Sort everything based on priority
 		// Sort everything based on priority
 		auto cameraComparer = [&](const CameraProxyPtr& a, const CameraProxyPtr& b) { return a->priority > b->priority; };
 		auto cameraComparer = [&](const CameraProxyPtr& a, const CameraProxyPtr& b) { return a->priority > b->priority; };
-		auto renderTargetInfoComparer = [&](const RenderTargetData& a, const RenderTargetData& b) { return a.target->getPriority() > b.target->getPriority(); };
+		auto renderTargetInfoComparer = [&](const RenderTargetData& a, const RenderTargetData& b) 
+		{ return a.target->getCore()->getProperties().getPriority() > b.target->getCore()->getProperties().getPriority(); };
 		std::sort(begin(mRenderTargets), end(mRenderTargets), renderTargetInfoComparer);
 		std::sort(begin(mRenderTargets), end(mRenderTargets), renderTargetInfoComparer);
 
 
 		for (auto& camerasPerTarget : mRenderTargets)
 		for (auto& camerasPerTarget : mRenderTargets)

+ 6 - 0
BansheeUtility/Include/BsThreadPool.h

@@ -76,6 +76,12 @@ namespace BansheeEngine
 		 */
 		 */
 		UINT32 getId() const;
 		UINT32 getId() const;
 
 
+		/**
+		 * @brief	Blocks the current thread until this thread completes.
+		 *			Returns immediately if the thread is idle.
+		 */
+		void blockUntilComplete();
+
 		/**
 		/**
 		 * @brief	Called when the thread is first created.
 		 * @brief	Called when the thread is first created.
 		 */
 		 */

+ 18 - 6
BansheeUtility/Source/BsThreadPool.cpp

@@ -89,18 +89,20 @@ namespace BansheeEngine
 			std::function<void()> worker = nullptr;
 			std::function<void()> worker = nullptr;
 
 
 			{
 			{
-				BS_LOCK_MUTEX_NAMED(mMutex, lock);
+				{
+					BS_LOCK_MUTEX_NAMED(mMutex, lock);
+
+					while (!mThreadReady)
+						BS_THREAD_WAIT(mReadyCond, mMutex, lock);
 
 
-				while(!mThreadReady)
-					BS_THREAD_WAIT(mReadyCond, mMutex, lock);
+					worker = mWorkerMethod;
+				}
 
 
-				if(mWorkerMethod == nullptr)
+				if (worker == nullptr)
 				{
 				{
 					onThreadEnded(mName);
 					onThreadEnded(mName);
 					return;
 					return;
 				}
 				}
-
-				worker = mWorkerMethod;
 			}
 			}
 
 
 			worker();
 			worker();
@@ -120,6 +122,8 @@ namespace BansheeEngine
 
 
 	void PooledThread::destroy()
 	void PooledThread::destroy()
 	{
 	{
+		blockUntilComplete();
+
 		{
 		{
 			BS_LOCK_MUTEX(mMutex);
 			BS_LOCK_MUTEX(mMutex);
 			mWorkerMethod = nullptr;
 			mWorkerMethod = nullptr;
@@ -131,6 +135,14 @@ namespace BansheeEngine
 		BS_THREAD_DESTROY(mThread);
 		BS_THREAD_DESTROY(mThread);
 	}
 	}
 
 
+	void PooledThread::blockUntilComplete()
+	{
+		BS_LOCK_MUTEX_NAMED(mMutex, lock);
+
+		while (!mIdle)
+			BS_THREAD_WAIT(mWorkerEndedCond, mMutex, lock);
+	}
+
 	bool PooledThread::isIdle()
 	bool PooledThread::isIdle()
 	{
 	{
 		BS_LOCK_MUTEX(mMutex);
 		BS_LOCK_MUTEX(mMutex);

+ 19 - 23
SceneView.txt

@@ -13,6 +13,18 @@ TODO - Think about:
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 Handles
 Handles
 
 
+ - Make a few different base handle types:
+   - Slider 1D (e.g. for movement using an arrow cap)
+   - Slider 2D (e.g. for movement in 2D using a plane render)
+   - Similar for scale/rotation handles  (see Unity for its implementations of those)
+
+Handles should have colliders which will be queries whenever user input is detected in scene view
+If any handle is hit the input will not proceed further (e.g. no picking will be done) and that handle control
+will become active.
+
+Base handle types should just be positioned in space and then return value every frame as user moves them.
+ - This way they can also easily be used from C# for custom user-made stuff
+
 TODO - Think about this
 TODO - Think about this
 See for inspiration: http://docs.unity3d.com/ScriptReference/Handles.html
 See for inspiration: http://docs.unity3d.com/ScriptReference/Handles.html
 
 
@@ -81,32 +93,16 @@ Need to allow the user to specify custom gizmos.
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------
 RenderTarget (and in turn, Viewport) make data available to sim thread, even though that data can be arbitrarily modified from the core thread
 RenderTarget (and in turn, Viewport) make data available to sim thread, even though that data can be arbitrarily modified from the core thread
 
 
-Create a separate set of classes: RenderTargetCore, RenderTextureCore, RenderWindowCore.
- - They would not be core objects but would be used exclusively on the core thread
- - Majority of the current classes would go into those new classes
+TODO:
+ - Fix invalid height
+ - Test DX9 and OpenGL
+ - getProperties on non-core should just make a copy of core for now to check if everything works
+ - Remove the debug stuff in RenderTarget when done testing
 
 
-Current RenderTarget/RenderTexture/RenderWindow would stay and be useable on sim thread but not meant for core thread use.
- - Internally it would store the *Core versions of the objects
 
 
 Whenever a core object gets changed it should notify a RenderTargetManager, which will on beginning of every frame update
 Whenever a core object gets changed it should notify a RenderTargetManager, which will on beginning of every frame update
 non-core version with valid data.
 non-core version with valid data.
+ - Make sure core dirty properties are updated before render window manager events are triggered
 
 
 Viewport should return a ViewportProxy for use on core thread (instead of a clone as it has now)
 Viewport should return a ViewportProxy for use on core thread (instead of a clone as it has now)
- - The proxy will reference the *Core version of render target
-
-IMPLEMENTATION:
- - Create RenderTargetCore, RenderTextureCore, RenderWindowCore files
- - Start copying (don't modify original files) code from original files and modify them for core use
- - Find any references of render targets on the core thread and make sure it uses those core objects instead
- - Add getCoreImplementation() that returns the core version from "normal" objects
-
-
-Stuff that needs to be synchronized:
- mIsFullscreen
- mWidth
- mHeight
- mHidden
- mTop
- mLeft
- mHasFocus
- (more? check)
+ - The proxy will reference the *Core version of render target