فهرست منبع

OpenGL render window now uses the common Win32Window

BearishSun 10 سال پیش
والد
کامیت
f9376590d8

+ 4 - 3
BansheeCore/Include/Win32/BsWin32Window.h

@@ -12,11 +12,12 @@ namespace BansheeEngine
 	struct BS_CORE_EXPORT WINDOW_DESC
 	struct BS_CORE_EXPORT WINDOW_DESC
 	{
 	{
 		WINDOW_DESC()
 		WINDOW_DESC()
-			: monitor(nullptr), parent(nullptr), external(nullptr), width(0), height(0), fullscreen(false), hidden(false)
-			, left(-1), top(-1), title(""), border(WindowBorder::Normal), outerDimensions(false), enableDoubleClick(true)
-			, toolWindow(false)
+			: module(nullptr), monitor(nullptr), parent(nullptr), external(nullptr), width(0), height(0), fullscreen(false)
+			, hidden(false), left(-1), top(-1), title(""), border(WindowBorder::Normal), outerDimensions(false)
+			, enableDoubleClick(true), toolWindow(false)
 		{ }
 		{ }
 
 
+		HINSTANCE module; /**< Instance to the local module. */
 		HMONITOR monitor; /**< Handle ot the monitor onto which to display the window. */
 		HMONITOR monitor; /**< Handle ot the monitor onto which to display the window. */
 		HWND parent; /**< Optional handle to the parent window if this window is to be a child of an existing window. */
 		HWND parent; /**< Optional handle to the parent window if this window is to be a child of an existing window. */
 		HWND external; /**< Optional external window handle if the window was created externally. */
 		HWND external; /**< Optional external window handle if the window was created externally. */

+ 2 - 4
BansheeCore/Source/Win32/BsWin32Window.cpp

@@ -135,10 +135,8 @@ namespace BansheeEngine
 			if (desc.enableDoubleClick)
 			if (desc.enableDoubleClick)
 				classStyle |= CS_DBLCLKS;
 				classStyle |= CS_DBLCLKS;
 
 
-			HINSTANCE hInst = nullptr;
-
 			// Register the window class
 			// Register the window class
-			WNDCLASS wc = { classStyle, Win32Platform::_win32WndProc, 0, 0, hInst,
+			WNDCLASS wc = { classStyle, Win32Platform::_win32WndProc, 0, 0, desc.module,
 				LoadIcon(nullptr, IDI_APPLICATION), LoadCursor(nullptr, IDC_ARROW),
 				LoadIcon(nullptr, IDI_APPLICATION), LoadCursor(nullptr, IDC_ARROW),
 				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "Win32Wnd" };
 				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "Win32Wnd" };
 
 
@@ -146,7 +144,7 @@ namespace BansheeEngine
 
 
 			// Create main window
 			// Create main window
 			m->hWnd = CreateWindowEx(m->styleEx, "Win32Wnd", desc.title.c_str(), m->style,
 			m->hWnd = CreateWindowEx(m->styleEx, "Win32Wnd", desc.title.c_str(), m->style,
-				left, top, width, height, desc.parent, nullptr, hInst, desc.creationParams);
+				left, top, width, height, desc.parent, nullptr, desc.module, desc.creationParams);
 			m->isExternal = false;
 			m->isExternal = false;
 		}
 		}
 		else
 		else

+ 6 - 0
BansheeD3D11RenderAPI/Source/BsD3D11RenderWindow.cpp

@@ -76,6 +76,12 @@ namespace BansheeEngine
 		windowDesc.toolWindow = mDesc.toolWindow;
 		windowDesc.toolWindow = mDesc.toolWindow;
 		windowDesc.creationParams = this;
 		windowDesc.creationParams = this;
 
 
+#ifdef BS_STATIC_LIB
+		windowDesc.module = GetModuleHandle(NULL);
+#else
+		windowDesc.module = GetModuleHandle("BansheeD3D11RenderAPI.dll");
+#endif
+
 		NameValuePairList::const_iterator opt;
 		NameValuePairList::const_iterator opt;
 		opt = mDesc.platformSpecific.find("parentWindowHandle");
 		opt = mDesc.platformSpecific.find("parentWindowHandle");
 		if (opt != mDesc.platformSpecific.end())
 		if (opt != mDesc.platformSpecific.end())

+ 1 - 1
BansheeD3D9RenderAPI/Source/BsD3D9RenderAPIFactory.cpp

@@ -8,7 +8,7 @@ namespace BansheeEngine
 	#ifdef BS_STATIC_LIB
 	#ifdef BS_STATIC_LIB
 		HINSTANCE hInst = GetModuleHandle(NULL);
 		HINSTANCE hInst = GetModuleHandle(NULL);
 	#else
 	#else
-		HINSTANCE hInst = GetModuleHandle("BansheeD3D9RenderSystem.dll");
+		HINSTANCE hInst = GetModuleHandle("BansheeD3D9RenderAPI.dll");
 	#endif
 	#endif
 
 
 		RenderAPICore::startUp<D3D9RenderAPI>(hInst);
 		RenderAPICore::startUp<D3D9RenderAPI>(hInst);

+ 1 - 3
BansheeD3D9RenderAPI/Source/BsD3D9RenderWindow.cpp

@@ -47,7 +47,6 @@ namespace BansheeEngine
 	{
 	{
 		RenderWindowCore::initialize();
 		RenderWindowCore::initialize();
 
 
-		HINSTANCE hInst = mInstance;
 		D3D9RenderWindowProperties& props = mProperties;
 		D3D9RenderWindowProperties& props = mProperties;
 
 
 		mMultisampleType = D3DMULTISAMPLE_NONE;
 		mMultisampleType = D3DMULTISAMPLE_NONE;
@@ -67,6 +66,7 @@ namespace BansheeEngine
 		windowDesc.title = mDesc.title;
 		windowDesc.title = mDesc.title;
 		windowDesc.toolWindow = mDesc.toolWindow;
 		windowDesc.toolWindow = mDesc.toolWindow;
 		windowDesc.creationParams = this;
 		windowDesc.creationParams = this;
+		windowDesc.module = mInstance;
 
 
 		NameValuePairList::const_iterator opt;
 		NameValuePairList::const_iterator opt;
 		opt = mDesc.platformSpecific.find("parentWindowHandle");
 		opt = mDesc.platformSpecific.find("parentWindowHandle");
@@ -82,8 +82,6 @@ namespace BansheeEngine
 		props.mColorDepth = 32;
 		props.mColorDepth = 32;
 		props.mActive = true;
 		props.mActive = true;
 
 
-		MONITORINFO monitorInfo;
-
 		const D3D9VideoModeInfo& videoModeInfo = static_cast<const D3D9VideoModeInfo&>(RenderAPICore::instance().getVideoModeInfo());
 		const D3D9VideoModeInfo& videoModeInfo = static_cast<const D3D9VideoModeInfo&>(RenderAPICore::instance().getVideoModeInfo());
 		UINT32 numOutputs = videoModeInfo.getNumOutputs();
 		UINT32 numOutputs = videoModeInfo.getNumOutputs();
 		if (numOutputs > 0)
 		if (numOutputs > 0)

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -72,7 +72,7 @@ int CALLBACK WinMain(
 
 
 	__try
 	__try
 	{
 	{
-		EditorApplication::startUp(RenderAPIPlugin::DX9);
+		EditorApplication::startUp(RenderAPIPlugin::OpenGL);
 		EditorApplication::instance().runMainLoop();
 		EditorApplication::instance().runMainLoop();
 		EditorApplication::shutDown();
 		EditorApplication::shutDown();
 	}
 	}

+ 1 - 1
BansheeGLRenderAPI/Include/BsGLPrerequisites.h

@@ -4,7 +4,7 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-	extern String MODULE_NAME;
+	extern const char* MODULE_NAME;
 
 
     class GLSupport;
     class GLSupport;
     class GLRenderAPI;
     class GLRenderAPI;

+ 3 - 12
BansheeGLRenderAPI/Include/BsWin32RenderWindow.h

@@ -110,7 +110,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Returns internal window handle.
 		 * @brief	Returns internal window handle.
 		 */
 		 */
-		HWND _getHWnd() const { return mHWnd; }
+		HWND _getHWnd() const;
 
 
 	protected:
 	protected:
 		friend class Win32GLSupport;
 		friend class Win32GLSupport;
@@ -120,11 +120,6 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual void initialize() override;
 		virtual void initialize() override;
 
 
-		/**
-		 * @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);
-
 		/**
 		/**
 		 * @copydoc	RenderWindowCore::getProperties
 		 * @copydoc	RenderWindowCore::getProperties
 		 */
 		 */
@@ -143,17 +138,13 @@ namespace BansheeEngine
 	protected:
 	protected:
 		friend class Win32RenderWindow;
 		friend class Win32RenderWindow;
 
 
-		Win32GLSupport &mGLSupport;
+		Win32Window* mWindow;
+		Win32GLSupport& mGLSupport;
 		HDC	mHDC;
 		HDC	mHDC;
-		DWORD mWindowedStyle;
-		DWORD mWindowedStyleEx;
-		bool mIsExternal;
 		bool mIsChild;
 		bool mIsChild;
 		char* mDeviceName;
 		char* mDeviceName;
-		bool mIsExternalGLControl;
 		int mDisplayFrequency;
 		int mDisplayFrequency;
 		bool mShowOnSwap;
 		bool mShowOnSwap;
-		HWND mHWnd;
 		SPtr<Win32Context> mContext;
 		SPtr<Win32Context> mContext;
 		Win32RenderWindowProperties mProperties;
 		Win32RenderWindowProperties mProperties;
 		Win32RenderWindowProperties mSyncedProperties;
 		Win32RenderWindowProperties mSyncedProperties;

+ 1 - 1
BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -27,7 +27,7 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-	String MODULE_NAME = "BansheeGLRenderSystem.dll";
+	const char* MODULE_NAME = "BansheeGLRenderAPI.dll";
 
 
 	void __stdcall openGlErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
 	void __stdcall openGlErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
 
 

+ 1 - 1
BansheeGLRenderAPI/Source/BsWin32GLSupport.cpp

@@ -147,7 +147,7 @@ namespace BansheeEngine
 #ifdef BS_STATIC_LIB
 #ifdef BS_STATIC_LIB
 		HINSTANCE hinst = GetModuleHandle(NULL);
 		HINSTANCE hinst = GetModuleHandle(NULL);
 #else
 #else
-		HINSTANCE hinst = GetModuleHandle(MODULE_NAME.c_str());
+		HINSTANCE hinst = GetModuleHandle(MODULE_NAME);
 #endif
 #endif
 		
 		
 		WNDCLASS dummyClass;
 		WNDCLASS dummyClass;

+ 127 - 355
BansheeGLRenderAPI/Source/BsWin32RenderWindow.cpp

@@ -13,6 +13,7 @@
 #include "BsWin32VideoModeInfo.h"
 #include "BsWin32VideoModeInfo.h"
 #include "BsGLPixelFormat.h"
 #include "BsGLPixelFormat.h"
 #include "BsRenderWindowManager.h"
 #include "BsRenderWindowManager.h"
+#include "Win32/BsWin32Window.h"
 
 
 GLenum GLEWAPIENTRY wglewContextInit(BansheeEngine::GLSupport *glSupport);
 GLenum GLEWAPIENTRY wglewContextInit(BansheeEngine::GLSupport *glSupport);
 
 
@@ -25,38 +26,30 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	Win32RenderWindowCore::Win32RenderWindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId, Win32GLSupport& glsupport)
 	Win32RenderWindowCore::Win32RenderWindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId, Win32GLSupport& glsupport)
-		: RenderWindowCore(desc, windowId), mProperties(desc), mSyncedProperties(desc), mGLSupport(glsupport), mContext(0), 
-		mWindowedStyle(0), mWindowedStyleEx(0), mIsExternal(false), mIsExternalGLControl(false), mDisplayFrequency(0), 
-		mDeviceName(nullptr), mHWnd(0), mShowOnSwap(false)
+		: RenderWindowCore(desc, windowId), mProperties(desc), mSyncedProperties(desc), mGLSupport(glsupport)
+		, mContext(nullptr), mWindow(nullptr), mDisplayFrequency(0), mDeviceName(nullptr)
+		, mShowOnSwap(false)
 	{ }
 	{ }
 
 
 	Win32RenderWindowCore::~Win32RenderWindowCore()
 	Win32RenderWindowCore::~Win32RenderWindowCore()
 	{ 
 	{ 
 		Win32RenderWindowProperties& props = mProperties;
 		Win32RenderWindowProperties& props = mProperties;
 
 
-		if (!mHWnd)
-			return;
-
-		if (!mIsExternal)
-		{
-			if (props.mIsFullScreen)
-				ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
-			DestroyWindow(mHWnd);
-		}
-		else
+		if (mWindow != nullptr)
 		{
 		{
-			// just release the DC
-			ReleaseDC(mHWnd, mHDC);
+			ReleaseDC(mWindow->getHWnd(), mHDC);
+
+			bs_delete(mWindow);
+			mWindow = nullptr;
 		}
 		}
 
 
 		props.mActive = false;
 		props.mActive = false;
-		mHDC = 0; // no release thanks to CS_OWNDC wndclass style
-		mHWnd = 0;
+		mHDC = nullptr;
 
 
-		if (mDeviceName != NULL)
+		if (mDeviceName != nullptr)
 		{
 		{
 			bs_free(mDeviceName);
 			bs_free(mDeviceName);
-			mDeviceName = NULL;
+			mDeviceName = nullptr;
 		}
 		}
 	}
 	}
 
 
@@ -64,213 +57,71 @@ namespace BansheeEngine
 	{
 	{
 		RenderWindowCore::initialize();
 		RenderWindowCore::initialize();
 
 
-#ifdef BS_STATIC_LIB
-		HINSTANCE hInst = GetModuleHandle(NULL);
-#else
-		HINSTANCE hInst = GetModuleHandle(MODULE_NAME.c_str());
-#endif
-
 		Win32RenderWindowProperties& props = mProperties;
 		Win32RenderWindowProperties& props = mProperties;
 
 
 		props.mIsFullScreen = mDesc.fullscreen;
 		props.mIsFullScreen = mDesc.fullscreen;
 		mIsChild = false;
 		mIsChild = false;
 		mDisplayFrequency = Math::roundToInt(mDesc.videoMode.getRefreshRate());
 		mDisplayFrequency = Math::roundToInt(mDesc.videoMode.getRefreshRate());
 		props.mColorDepth = 32;
 		props.mColorDepth = 32;
-		HWND parent = 0;
-
-		NameValuePairList::const_iterator opt;
-		NameValuePairList::const_iterator end = mDesc.platformSpecific.end();
 
 
-		if ((opt = mDesc.platformSpecific.find("externalWindowHandle")) != end)
-		{
-			mHWnd = (HWND)parseUnsignedInt(opt->second);
-			if (mHWnd)
-			{
-				mIsExternal = true;
-			}
-
-			if ((opt = mDesc.platformSpecific.find("externalGLControl")) != end) {
-				mIsExternalGLControl = parseBool(opt->second);
-			}
-		}
+		WINDOW_DESC windowDesc;
+		windowDesc.border = mDesc.border;
+		windowDesc.enableDoubleClick = mDesc.enableDoubleClick;
+		windowDesc.fullscreen = mDesc.fullscreen;
+		windowDesc.width = mDesc.videoMode.getWidth();
+		windowDesc.height = mDesc.videoMode.getHeight();
+		windowDesc.hidden = mDesc.hidden || mDesc.hideUntilSwap;
+		windowDesc.left = mDesc.left;
+		windowDesc.top = mDesc.top;
+		windowDesc.outerDimensions = mDesc.outerDimensions;
+		windowDesc.title = mDesc.title;
+		windowDesc.toolWindow = mDesc.toolWindow;
+		windowDesc.creationParams = this;
 
 
-		HGLRC glrc = 0;
-		if ((opt = mDesc.platformSpecific.find("externalGLContext")) != end)
-		{
-			glrc = (HGLRC)parseUnsignedLong(opt->second);
-		}
-
-		if ((opt = mDesc.platformSpecific.find("parentWindowHandle")) != end)
-		{
-			parent = (HWND)parseUnsignedInt(opt->second);
-			mIsChild = true;
-			props.mIsFullScreen = false;
-		}
+#ifdef BS_STATIC_LIB
+		windowDesc.module = GetModuleHandle(NULL);
+#else
+		windowDesc.module = GetModuleHandle(MODULE_NAME);
+#endif
 
 
-		HMONITOR hMonitor = NULL;
+		NameValuePairList::const_iterator opt;
+		opt = mDesc.platformSpecific.find("parentWindowHandle");
+		if (opt != mDesc.platformSpecific.end())
+			windowDesc.parent = (HWND)parseUnsignedInt(opt->second);
+
+		opt = mDesc.platformSpecific.find("externalWindowHandle");
+		if (opt != mDesc.platformSpecific.end())
+			windowDesc.external = (HWND)parseUnsignedInt(opt->second);
+		
 		const Win32VideoModeInfo& videoModeInfo = static_cast<const Win32VideoModeInfo&>(RenderAPICore::instance().getVideoModeInfo());
 		const Win32VideoModeInfo& videoModeInfo = static_cast<const Win32VideoModeInfo&>(RenderAPICore::instance().getVideoModeInfo());
 		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(mDesc.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();
+			windowDesc.monitor = outputInfo.getMonitorHandle();
 		}
 		}
 
 
-		if (!props.mIsFullScreen)
-		{
-			// Make sure we don't exceed desktop color depth
-			if ((int)props.mColorDepth > GetDeviceCaps(GetDC(0), BITSPIXEL))
-				props.mColorDepth = GetDeviceCaps(GetDC(0), BITSPIXEL);
-		}
-
-		mWindowedStyle = WS_CLIPCHILDREN;
-		mShowOnSwap = mDesc.hideUntilSwap;
-		props.mHidden = mDesc.hideUntilSwap;
-
-		if (!mShowOnSwap)
-			mWindowedStyle |= WS_VISIBLE;
-
-		mWindowedStyleEx = 0;
+		mIsChild = windowDesc.parent != nullptr;
+		props.mIsFullScreen = mDesc.fullscreen && !mIsChild;
+		props.mColorDepth = 32;
+		props.mActive = true;
 
 
-		if (!props.mIsFullScreen)
+		if (!windowDesc.external)
 		{
 		{
-			if (parent)
-			{
-				if (mDesc.toolWindow)
-					mWindowedStyleEx = WS_EX_TOOLWINDOW;
-				else
-					mWindowedStyle |= WS_CHILD;
-			}
-
-			if (!parent || mDesc.toolWindow)
-			{
-				if (mDesc.border == WindowBorder::None)
-					mWindowedStyle |= WS_POPUP;
-				else if (mDesc.border == WindowBorder::Fixed)
-					mWindowedStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
-					WS_SYSMENU | WS_MINIMIZEBOX;
-				else
-					mWindowedStyle |= WS_OVERLAPPEDWINDOW;
-			}
+			mShowOnSwap = mDesc.hideUntilSwap;
+			props.mHidden = mDesc.hideUntilSwap || mDesc.hidden;
 		}
 		}
 
 
-		if (!mIsExternal)
-		{
-			RECT rc;
-
-			// If we didn't specified the adapter index, or if it didn't find it
-			if (hMonitor == NULL)
-			{
-				POINT windowAnchorPoint;
-
-				// Fill in anchor point.
-				windowAnchorPoint.x = mDesc.left;
-				windowAnchorPoint.y = mDesc.top;
-
-				// Get the nearest monitor to this window.
-				hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST);
-			}
-
-			// Get the target monitor info		
-			MONITORINFOEX monitorInfoEx;
-			memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX));
-			monitorInfoEx.cbSize = sizeof(MONITORINFOEX);
-
-			GetMonitorInfo(hMonitor, &monitorInfoEx);
-
-			size_t devNameLen = strlen(monitorInfoEx.szDevice);
-			mDeviceName = (char*)bs_alloc((UINT32)(devNameLen + 1));
-
-			strcpy_s(mDeviceName, devNameLen + 1, monitorInfoEx.szDevice);
-
-			UINT32 left = mDesc.left;
-			UINT32 top = mDesc.top;
-
-			// No specified top left -> Center the window in the middle of the monitor
-			if (left == -1 || top == -1)
-			{
-				int screenw = monitorInfoEx.rcWork.right - monitorInfoEx.rcWork.left;
-				int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top;
-
-				unsigned int winWidth, winHeight;
-				getAdjustedWindowSize(mDesc.videoMode.getWidth(), mDesc.videoMode.getHeight(), &winWidth, &winHeight);
-
-				// clamp window dimensions to screen size
-				int outerw = (int(winWidth) < screenw) ? int(winWidth) : screenw;
-				int outerh = (int(winHeight) < screenh) ? int(winHeight) : screenh;
-
-				if (left == -1)
-					left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2;
-				else if (hMonitor != NULL)
-					left += monitorInfoEx.rcWork.left;
-
-				if (top == -1)
-					top = monitorInfoEx.rcWork.top + (screenh - outerh) / 2;
-				else if (hMonitor != NULL)
-					top += monitorInfoEx.rcWork.top;
-			}
-			else if (hMonitor != NULL)
-			{
-				left += monitorInfoEx.rcWork.left;
-				top += monitorInfoEx.rcWork.top;
-			}
-
-			props.mWidth = mDesc.videoMode.getWidth();
-			props.mHeight = mDesc.videoMode.getHeight();
-			props.mTop = top;
-			props.mLeft = left;
-
-			DWORD dwStyle = 0;
-			DWORD dwStyleEx = 0;
-			if (props.mIsFullScreen)
-			{
-				dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_POPUP;
-				props.mTop = monitorInfoEx.rcMonitor.top;
-				props.mLeft = monitorInfoEx.rcMonitor.left;
-			}
-			else
-			{
-				dwStyle = mWindowedStyle;
-				dwStyleEx = mWindowedStyleEx;
-
-				int screenw = GetSystemMetrics(SM_CXSCREEN);
-				int screenh = GetSystemMetrics(SM_CYSCREEN);
-
-				if (!mDesc.outerDimensions)
-				{
-					// Calculate window dimensions required
-					// to get the requested client area
-					SetRect(&rc, 0, 0, props.mWidth, props.mHeight);
-					AdjustWindowRect(&rc, dwStyle, false);
-					props.mWidth = rc.right - rc.left;
-					props.mHeight = rc.bottom - rc.top;
-
-					// Clamp window rect to the nearest display monitor.
-					if (props.mLeft < monitorInfoEx.rcWork.left)
-						props.mLeft = monitorInfoEx.rcWork.left;
-
-					if (props.mTop < monitorInfoEx.rcWork.top)
-						props.mTop = monitorInfoEx.rcWork.top;
-
-					if ((int)props.mWidth > monitorInfoEx.rcWork.right - props.mLeft)
-						props.mWidth = monitorInfoEx.rcWork.right - props.mLeft;
-
-					if ((int)props.mHeight > monitorInfoEx.rcWork.bottom - props.mTop)
-						props.mHeight = monitorInfoEx.rcWork.bottom - props.mTop;
-				}
-			}
-
-			UINT classStyle = CS_OWNDC;
-			if (mDesc.enableDoubleClick)
-				classStyle |= CS_DBLCLKS;
-
-			// register class and create window
-			WNDCLASS wc = { classStyle, Win32Platform::_win32WndProc, 0, 0, hInst,
-				LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
-				(HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "GLWindow" };
-			RegisterClass(&wc);
+		mWindow = bs_new<Win32Window>(windowDesc);
 
 
+		props.mWidth = mWindow->getWidth();
+		props.mHeight = mWindow->getHeight();
+		props.mTop = mWindow->getTop();
+		props.mLeft = mWindow->getLeft();
+		
+		if (!windowDesc.external)
+		{
 			if (props.mIsFullScreen)
 			if (props.mIsFullScreen)
 			{
 			{
 				DEVMODE displayDeviceMode;
 				DEVMODE displayDeviceMode;
@@ -298,67 +149,49 @@ namespace BansheeEngine
 					BS_EXCEPT(RenderingAPIException, "ChangeDisplaySettings failed.");
 					BS_EXCEPT(RenderingAPIException, "ChangeDisplaySettings failed.");
 				}
 				}
 			}
 			}
-
-			// Pass pointer to self as WM_CREATE parameter
-			mHWnd = CreateWindowEx(dwStyleEx, "GLWindow", mDesc.title.c_str(),
-				dwStyle, props.mLeft, props.mTop, props.mWidth, props.mHeight, parent, 0, hInst, this);
 		}
 		}
 
 
-		RECT rc;
-
-		GetWindowRect(mHWnd, &rc);
-		props.mTop = rc.top;
-		props.mLeft = rc.left;
-
-		GetClientRect(mHWnd, &rc);
-		props.mWidth = rc.right;
-		props.mHeight = rc.bottom;
-
-		mHDC = GetDC(mHWnd);
+		mHDC = GetDC(mWindow->getHWnd());
 
 
-		if (!mIsExternalGLControl)
+		int testMultisample = props.mMultisampleCount;
+		bool testHwGamma = mDesc.gamma;
+		bool formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
+		if (!formatOk)
 		{
 		{
-			int testMultisample = props.mMultisampleCount;
-			bool testHwGamma = mDesc.gamma;
-			bool formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
-			if (!formatOk)
+			if (props.mMultisampleCount > 0)
 			{
 			{
-				if (props.mMultisampleCount > 0)
-				{
-					// Try without multisampling
-					testMultisample = 0;
-					formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
-				}
-
-				if (!formatOk && mDesc.gamma)
-				{
-					// Try without sRGB
-					testHwGamma = false;
-					testMultisample = props.mMultisampleCount;
-					formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
-				}
-
-				if (!formatOk && mDesc.gamma && (props.mMultisampleCount > 0))
-				{
-					// Try without both
-					testHwGamma = false;
-					testMultisample = 0;
-					formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
-				}
+				// Try without multisampling
+				testMultisample = 0;
+				formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
+			}
 
 
-				if (!formatOk)
-					BS_EXCEPT(RenderingAPIException, "Failed selecting pixel format.");
+			if (!formatOk && mDesc.gamma)
+			{
+				// Try without sRGB
+				testHwGamma = false;
+				testMultisample = props.mMultisampleCount;
+				formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
+			}
 
 
+			if (!formatOk && mDesc.gamma && (props.mMultisampleCount > 0))
+			{
+				// Try without both
+				testHwGamma = false;
+				testMultisample = 0;
+				formatOk = mGLSupport.selectPixelFormat(mHDC, props.mColorDepth, testMultisample, testHwGamma, mDesc.depthBuffer);
 			}
 			}
 
 
-			// Record what gamma option we used in the end
-			// this will control enabling of sRGB state flags when used
-			props.mHwGamma = testHwGamma;
-			props.mMultisampleCount = testMultisample;
+			if (!formatOk)
+				BS_EXCEPT(RenderingAPIException, "Failed selecting pixel format.");
+
 		}
 		}
 
 
-		props.mActive = true;
-		mContext = mGLSupport.createContext(mHDC, glrc);
+		// Record what gamma option we used in the end
+		// this will control enabling of sRGB state flags when used
+		props.mHwGamma = testHwGamma;
+		props.mMultisampleCount = testMultisample;
+
+		mContext = mGLSupport.createContext(mHDC, nullptr);
 
 
 		{
 		{
 			ScopedSpinLock lock(mLock);
 			ScopedSpinLock lock(mLock);
@@ -385,8 +218,6 @@ namespace BansheeEngine
 		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 = props.mIsFullScreen;
-
 		mDisplayFrequency = Math::roundToInt(refreshRate);
 		mDisplayFrequency = Math::roundToInt(refreshRate);
 		props.mIsFullScreen = true;
 		props.mIsFullScreen = true;
 
 
@@ -417,18 +248,9 @@ namespace BansheeEngine
 		props.mWidth = width;
 		props.mWidth = width;
 		props.mHeight = height;
 		props.mHeight = height;
 
 
-		SetWindowPos(mHWnd, HWND_TOP, props.mLeft, props.mTop, width, height, SWP_NOACTIVATE);
+		SetWindowPos(mWindow->getHWnd(), HWND_TOP, props.mLeft, props.mTop, width, height, SWP_NOACTIVATE);
 
 
-		{
-			ScopedSpinLock lock(mLock);
-			mSyncedProperties.mTop = props.mTop;
-			mSyncedProperties.mLeft = props.mLeft;
-			mSyncedProperties.mWidth = props.mWidth;
-			mSyncedProperties.mHeight = props.mHeight;
-		}
-
-		RenderWindowManager::instance().notifySyncDataDirty(this);
-		RenderWindowManager::instance().notifyMovedOrResized(this);
+		_windowMovedOrResized();
 	}
 	}
 
 
 	void Win32RenderWindowCore::setFullscreen(const VideoMode& mode)
 	void Win32RenderWindowCore::setFullscreen(const VideoMode& mode)
@@ -454,12 +276,18 @@ namespace BansheeEngine
 		// 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
-		UINT32 winWidth, winHeight;
-		getAdjustedWindowSize(props.mWidth, props.mHeight, &winWidth, &winHeight);
+		UINT32 winWidth = 0;
+		UINT32 winHeight = 0;
+
+		RECT rect;
+		SetRect(&rect, 0, 0, winWidth, winHeight);
+
+		AdjustWindowRect(&rect, mWindow->getStyle(), false);
+		winWidth = rect.right - rect.left;
+		winHeight = rect.bottom - rect.top;
 
 
 		// 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(mWindow->getHWnd(), MONITOR_DEFAULTTONEAREST);
 		MONITORINFO monitorInfo;
 		MONITORINFO monitorInfo;
 		memset(&monitorInfo, 0, sizeof(MONITORINFO));
 		memset(&monitorInfo, 0, sizeof(MONITORINFO));
 		monitorInfo.cbSize = sizeof(MONITORINFO);
 		monitorInfo.cbSize = sizeof(MONITORINFO);
@@ -471,9 +299,9 @@ namespace BansheeEngine
 		INT32 left = screenw > INT32(winWidth) ? ((screenw - INT32(winWidth)) / 2) : 0;
 		INT32 left = screenw > INT32(winWidth) ? ((screenw - INT32(winWidth)) / 2) : 0;
 		INT32 top = screenh > INT32(winHeight) ? ((screenh - INT32(winHeight)) / 2) : 0;
 		INT32 top = screenh > INT32(winHeight) ? ((screenh - INT32(winHeight)) / 2) : 0;
 
 
-		SetWindowLong(mHWnd, GWL_STYLE, mWindowedStyle);
-		SetWindowLong(mHWnd, GWL_EXSTYLE, mWindowedStyleEx);
-		SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight,
+		SetWindowLong(mWindow->getHWnd(), GWL_STYLE, mWindow->getStyle());
+		SetWindowLong(mWindow->getHWnd(), GWL_EXSTYLE, mWindow->getStyleEx());
+		SetWindowPos(mWindow->getHWnd(), HWND_NOTOPMOST, left, top, winWidth, winHeight,
 			SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
 			SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
 
 
 		{
 		{
@@ -491,13 +319,12 @@ namespace BansheeEngine
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		Win32RenderWindowProperties& props = mProperties;
 		Win32RenderWindowProperties& props = mProperties;
-		if (mHWnd && !props.mIsFullScreen)
+		if (!props.mIsFullScreen)
 		{
 		{
-			props.mLeft = left;
-			props.mTop = top;
+			mWindow->move(top, left);
 
 
-			SetWindowPos(mHWnd, 0, left, top, 0, 0,
-				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+			props.mTop = mWindow->getTop();
+			props.mLeft = mWindow->getLeft();
 
 
 			{
 			{
 				ScopedSpinLock lock(mLock);
 				ScopedSpinLock lock(mLock);
@@ -514,18 +341,13 @@ namespace BansheeEngine
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		Win32RenderWindowProperties& props = mProperties;
 		Win32RenderWindowProperties& props = mProperties;
-		if (mHWnd && !props.mIsFullScreen)
+		if (!props.mIsFullScreen)
 		{
 		{
-			props.mWidth = width;
-			props.mHeight = height;
-
-			RECT rc = { 0, 0, width, height };
-			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
-			width = rc.right - rc.left;
-			height = rc.bottom - rc.top;
-			SetWindowPos(mHWnd, 0, 0, 0, width, height,
-				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+			mWindow->resize(width, height);
 
 
+			props.mWidth = mWindow->getWidth();
+			props.mHeight = mWindow->getHeight();
+			
 			{
 			{
 				ScopedSpinLock lock(mLock);
 				ScopedSpinLock lock(mLock);
 				mSyncedProperties.mWidth = props.mWidth;
 				mSyncedProperties.mWidth = props.mWidth;
@@ -540,24 +362,21 @@ namespace BansheeEngine
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd)
-			SendMessage(mHWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+		mWindow->minimize();
 	}
 	}
 
 
 	void Win32RenderWindowCore::maximize()
 	void Win32RenderWindowCore::maximize()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd)
-			SendMessage(mHWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+		mWindow->maximize();
 	}
 	}
 
 
 	void Win32RenderWindowCore::restore()
 	void Win32RenderWindowCore::restore()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (mHWnd)
-			SendMessage(mHWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
+		mWindow->restore();
 	}
 	}
 
 
 	void Win32RenderWindowCore::swapBuffers()
 	void Win32RenderWindowCore::swapBuffers()
@@ -567,9 +386,7 @@ namespace BansheeEngine
 		if (mShowOnSwap)
 		if (mShowOnSwap)
 			setHidden(false);
 			setHidden(false);
 
 
-		if (!mIsExternalGLControl) {
-			SwapBuffers(mHDC);
-		}
+		SwapBuffers(mHDC);
 	}
 	}
 
 
 	void Win32RenderWindowCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
 	void Win32RenderWindowCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
@@ -637,7 +454,7 @@ namespace BansheeEngine
 		else if(name == "WINDOW")
 		else if(name == "WINDOW")
 		{
 		{
 			UINT64 *pHwnd = (UINT64*)pData;
 			UINT64 *pHwnd = (UINT64*)pData;
-			*pHwnd = (UINT64)mHWnd;
+			*pHwnd = (UINT64)_getHWnd();
 			return;
 			return;
 		} 
 		} 
 	}
 	}
@@ -646,15 +463,7 @@ namespace BansheeEngine
 	{	
 	{	
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		Win32RenderWindowProperties& props = mProperties;
-
-		if (mHWnd)
-		{
-			if (state)
-				ShowWindow(mHWnd, SW_RESTORE);
-			else
-				ShowWindow(mHWnd, SW_SHOWMINNOACTIVE);
-		}
+		mWindow->setActive(state);
 
 
 		RenderWindowCore::setActive(state);
 		RenderWindowCore::setActive(state);
 	}
 	}
@@ -663,68 +472,31 @@ namespace BansheeEngine
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		Win32RenderWindowProperties& props = mProperties;
-		props.mHidden = hidden;
 		mShowOnSwap = false;
 		mShowOnSwap = false;
-
-		if (!mIsExternal)
-		{
-			if (hidden)
-				ShowWindow(mHWnd, SW_HIDE);
-			else
-				ShowWindow(mHWnd, SW_SHOWNORMAL);
-		}
+		mWindow->setHidden(hidden);
 
 
 		RenderWindowCore::setHidden(hidden);
 		RenderWindowCore::setHidden(hidden);
 	}
 	}
 
 
 	void Win32RenderWindowCore::_windowMovedOrResized()
 	void Win32RenderWindowCore::_windowMovedOrResized()
 	{
 	{
-		Win32RenderWindowProperties& props = mProperties;
-
-		if (!mHWnd || IsIconic(mHWnd))
+		if (!mWindow)
 			return;
 			return;
 
 
-		RECT rc;
-		GetWindowRect(mHWnd, &rc);
-		props.mTop = rc.top;
-		props.mLeft = rc.left;
+		mWindow->_windowMovedOrResized();
 
 
-		GetClientRect(mHWnd, &rc);
-		props.mWidth = rc.right - rc.left;
-		props.mHeight = rc.bottom - rc.top;
+		Win32RenderWindowProperties& props = mProperties;
+		props.mTop = mWindow->getTop();
+		props.mLeft = mWindow->getLeft();
+		props.mWidth = mWindow->getWidth();
+		props.mHeight = mWindow->getHeight();
 
 
 		RenderWindowCore::_windowMovedOrResized();
 		RenderWindowCore::_windowMovedOrResized();
 	}
 	}
 
 
-	void Win32RenderWindowCore::getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight, UINT32* winWidth, UINT32* winHeight)
+	HWND Win32RenderWindowCore::_getHWnd() const
 	{
 	{
-		Win32RenderWindowProperties& props = mProperties;
-
-		RECT rc;
-		SetRect(&rc, 0, 0, clientWidth, clientHeight);
-		AdjustWindowRectEx(&rc, mWindowedStyle, false, mWindowedStyleEx);
-		*winWidth = rc.right - rc.left;
-		*winHeight = rc.bottom - rc.top;
-
-		// Adjust to monitor
-		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
-
-		// Get monitor info	
-		MONITORINFO monitorInfo;
-
-		memset(&monitorInfo, 0, sizeof(MONITORINFO));
-		monitorInfo.cbSize = sizeof(MONITORINFO);
-		GetMonitorInfo(hMonitor, &monitorInfo);
-
-		LONG maxW = monitorInfo.rcWork.right  - monitorInfo.rcWork.left;
-		LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
-
-		if (*winWidth > (UINT32)maxW)
-			*winWidth = maxW;
-
-		if (*winHeight > (UINT32)maxH)
-			*winHeight = maxH;
+		return mWindow->getHWnd();
 	}
 	}
 
 
 	void Win32RenderWindowCore::syncProperties()
 	void Win32RenderWindowCore::syncProperties()