Browse Source

Added DX11 RenderWindow
Some basic support for separate DepthStencilBuffer class

Marko Pintera 13 years ago
parent
commit
cd4008400e
27 changed files with 1158 additions and 65 deletions
  1. 2 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj
  2. 6 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters
  3. 3 61
      CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h
  4. 80 0
      CamelotD3D11RenderSystem/Include/CmD3D11RenderWindow.h
  5. 109 0
      CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp
  6. 778 0
      CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp
  7. 2 0
      CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj
  8. 6 0
      CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj.filters
  9. 15 0
      CamelotD3D9Renderer/Include/CmD3D9DepthStencilBuffer.h
  10. 6 0
      CamelotD3D9Renderer/Include/CmD3D9TextureManager.h
  11. 8 0
      CamelotD3D9Renderer/Source/CmD3D9DepthStencilBuffer.cpp
  12. 7 0
      CamelotD3D9Renderer/Source/CmD3D9TextureManager.cpp
  13. 2 0
      CamelotGLRenderer/CamelotGLRenderer.vcxproj
  14. 6 0
      CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters
  15. 6 0
      CamelotGLRenderer/Include/CmGLTextureManager.h
  16. 8 0
      CamelotGLRenderer/Source/CmGLDepthStencilBuffer.cpp
  17. 7 1
      CamelotGLRenderer/Source/CmGLTextureManager.cpp
  18. 2 0
      CamelotRenderer/CamelotRenderer.vcxproj
  19. 6 0
      CamelotRenderer/CamelotRenderer.vcxproj.filters
  20. 38 0
      CamelotRenderer/Include/CmDepthStencilBuffer.h
  21. 2 0
      CamelotRenderer/Include/CmPrerequisites.h
  22. 7 0
      CamelotRenderer/Include/CmRenderTarget.h
  23. 5 0
      CamelotRenderer/Include/CmRenderTexture.h
  24. 7 0
      CamelotRenderer/Include/CmTextureManager.h
  25. 32 0
      CamelotRenderer/Source/CmDepthStencilBuffer.cpp
  26. 3 1
      CamelotRenderer/Source/CmRenderWindow.cpp
  27. 5 2
      CamelotRenderer/TODO.txt

+ 2 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj

@@ -160,6 +160,7 @@
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
     <ClInclude Include="Include\CmD3D11HardwareVertexBuffer.h" />
     <ClInclude Include="Include\CmD3D11RenderSystem.h" />
+    <ClInclude Include="Include\CmD3D11RenderWindow.h" />
     <ClInclude Include="Include\CmD3D11VertexDeclaration.h" />
     <ClInclude Include="Include\CmD3D11VideoMode.h" />
     <ClInclude Include="Include\CmD3D11VideoModeList.h" />
@@ -178,6 +179,7 @@
     <ClCompile Include="Source\CmD3D11Mappings.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareVertexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11RenderSystem.cpp" />
+    <ClCompile Include="Source\CmD3D11RenderWindow.cpp" />
     <ClCompile Include="Source\CmD3D11VertexDeclaration.cpp" />
     <ClCompile Include="Source\CmD3D11VideoMode.cpp" />
     <ClCompile Include="Source\CmD3D11VideoModeList.cpp" />

+ 6 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters

@@ -66,6 +66,9 @@
     <ClInclude Include="Include\CmD3D11RenderSystem.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D11RenderWindow.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
@@ -116,5 +119,8 @@
     <ClCompile Include="Source\CmD3D11RenderSystem.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D11RenderWindow.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 3 - 61
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h

@@ -8,68 +8,10 @@ namespace CamelotEngine
 	class CM_D3D11_EXPORT D3D11RenderSystem : public RenderSystem
 	{
 	public:
-		//D3D11RenderSystem();
-		//~D3D11RenderSystem();
-
-		//const String& getName() const;
-		//void startUp_internal();
-		//void shutdown();
-
-		//void setStencilCheckEnabled_internal(bool enabled);
-		//void setStencilBufferParams_internal(CompareFunction func = CMPF_ALWAYS_PASS, 
-		//	UINT32 refValue = 0, UINT32 mask = 0xFFFFFFFF, 
-		//	StencilOperation stencilFailOp = SOP_KEEP, 
-		//	StencilOperation depthFailOp = SOP_KEEP,
-		//	StencilOperation passOp = SOP_KEEP, 
-		//	bool twoSidedOperation = false);
-
-		//void createRenderWindow_internal(const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList& miscParams, AsyncOp& asyncOp);
-		//void destroyRenderTarget_internal(RenderTarget* renderTarget);
-		//void setRenderTarget_internal(RenderTarget *target);
-
-		//void bindGpuProgram_internal(GpuProgramHandle prg);
-		//void unbindGpuProgram_internal(GpuProgramType gptype);
-		//void bindGpuProgramParameters_internal(GpuProgramType gptype, GpuProgramParametersSharedPtr params, UINT16 variabilityMask);
-
-		//void setPointParameters_internal(float size, bool attenuationEnabled, float constant, float linear, float quadratic, float minSize, float maxSize);
-		//void setTexture_internal(UINT16 unit, bool enabled, const TexturePtr &texPtr);
-		//void setVertexTexture_internal(UINT16 unit, const TexturePtr& tex);
-		//void disableTextureUnit_internal(UINT16 texUnit);
-		//void setTextureAddressingMode_internal(UINT16 stage, const SamplerState::UVWAddressingMode& uvw);
-		//void setTextureBorderColor_internal(UINT16 stage, const Color& colour);
-		//void setTextureMipmapBias_internal(UINT16 unit, float bias);
-		//void setSceneBlending_internal( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op );
-		//void setSeparateSceneBlending_internal( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp );
-		//void setAlphaRejectSettings_internal( CompareFunction func, unsigned char value, bool alphaToCoverage );
-		//void setViewport_internal(const Viewport& vp);				
-		//void setCullingMode_internal(CullingMode mode);
-		//void setDepthBufferParams_internal( bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL );
-		//void setDepthBufferCheckEnabled_internal( bool enabled = true );
-		//void setColorBufferWriteEnabled_internal(bool red, bool green, bool blue, bool alpha);
-		//void setDepthBufferWriteEnabled_internal(bool enabled = true);
-		//void setDepthBufferFunction_internal( CompareFunction func = CMPF_LESS_EQUAL );
-		//void setDepthBias_internal(float constantBias, float slopeScaleBias);
-		//void setPolygonMode_internal(PolygonMode level);
-		//void setTextureFiltering_internal(UINT16 unit, FilterType ftype, FilterOptions filter);
-		//void setTextureAnisotropy_internal(UINT16 unit, unsigned int maxAnisotropy);
-		//void setVertexDeclaration_internal(VertexDeclarationPtr decl);
-		//void setVertexBufferBinding_internal(VertexBufferBinding* binding);
-
-		//void render_internal(const RenderOperation& op);
-		//void beginFrame_internal();
-		//void endFrame_internal();
-
-		//void setScissorTest_internal(bool enabled, UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600);
-		//void clearFrameBuffer_internal(unsigned int buffers, const Color& colour = Color::Black, float depth = 1.0f, unsigned short stencil = 0);
-
-		//float getHorizontalTexelOffset();
-		//float getVerticalTexelOffset();
-		//float getMinimumDepthInputValue();
-		//float getMaximumDepthInputValue();
-		//VertexElementType getColorVertexElementType() const;
-		//void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false);
-
+		
 		static D3D11Device& getPrimaryDevice();
+
+		void determineFSAASettings(UINT32 fsaa, const String& fsaaHint, DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings);
 	protected:
 
 	private:

+ 80 - 0
CamelotD3D11RenderSystem/Include/CmD3D11RenderWindow.h

@@ -0,0 +1,80 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmRenderWindow.h"
+
+namespace CamelotEngine
+{
+	class CM_D3D11_EXPORT D3D11RenderWindow : public RenderWindow
+	{
+	public:
+		D3D11RenderWindow(D3D11Device& device, IDXGIFactory* DXGIFactory);
+		~D3D11RenderWindow();
+
+		void initialize(const String& name, unsigned width, unsigned height, bool fullScreen, 
+			const NameValuePairList* miscParams);
+		void destroy(void);
+
+		void reposition(int left, int top);
+		void resize(unsigned int width, unsigned int height);
+
+		void setHidden(bool hidden);
+		void setActive(bool state);
+		void setFullscreen(bool fullScreen, unsigned int width, unsigned int height);
+
+		void swapBuffers(bool waitForVSync = true);
+		void copyContentsToMemory(const PixelData &dst, FrameBuffer buffer);
+
+		void windowMovedOrResized();
+
+		bool isClosed() const									{ return mClosed; }
+		bool isHidden() const									{ return mHidden; }
+
+		void getCustomAttribute( const String& name, void* pData );
+		DXGI_SWAP_CHAIN_DESC* getPresentationParameters(void)	{ return &mSwapChainDesc; }
+		HWND getWindowHandle() const							{ return mHWnd; }
+
+		bool requiresTextureFlipping() const					{ return false; }
+
+	protected:
+		void _createSizeDependedD3DResources();
+		void _destroySizeDependedD3DResources();
+
+		IDXGIDevice* _queryDxgiDevice(); 
+	
+		bool _checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format);
+
+		void _createSwapChain();
+		void _resizeSwapChainBuffers(unsigned width, unsigned height);
+
+		bool _getSwitchingFullscreen() const					{ return mSwitchingFullscreen; }
+		void _finishSwitchingFullscreen();
+		
+	protected:
+		D3D11Device&	mDevice;			// D3D11 driver
+		IDXGIFactory*	mDXGIFactory;
+		bool	mIsExternal;
+		bool	mSizing;
+		bool	mClosed;
+		bool	mHidden;
+
+		// -------------------------------------------------------
+		// DirectX-specific
+		// -------------------------------------------------------
+		DXGI_SAMPLE_DESC mFSAAType;
+		UINT mDisplayFrequency;
+		bool mVSync;
+		unsigned int mVSyncInterval;
+
+		// Window size depended resources - must be released before swapchain resize and recreated later
+		ID3D11Texture2D*			mBackBuffer;
+		ID3D11RenderTargetView*		mRenderTargetView;
+		ID3D11DepthStencilView*		mDepthStencilView;
+
+		IDXGISwapChain*				mSwapChain;
+		DXGI_SWAP_CHAIN_DESC		mSwapChainDesc;
+
+		HWND	mHWnd;					// Win32 window handle
+		bool	mSwitchingFullscreen;	// Are we switching from fullscreen to windowed or vice versa
+	};
+}

+ 109 - 0
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -8,4 +8,113 @@ namespace CamelotEngine
 	{ 
 		CM_EXCEPT(NotImplementedException, "Not implemented"); 
 	}
+
+	void D3D11RenderSystem::determineFSAASettings(UINT32 fsaa, const String& fsaaHint, DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings)
+	{
+		CM_EXCEPT(NotImplementedException, "Not implemented");
+
+		/*
+		bool ok = false;
+		bool qualityHint = fsaaHint.find("Quality") != String::npos;
+		size_t origFSAA = fsaa;
+		bool tryCSAA = false;
+		// NVIDIA, prefer CSAA if available for 8+
+		// it would be tempting to use getCapabilities()->getVendor() == GPU_NVIDIA but
+		// if this is the first window, caps will not be initialised yet
+		
+		if (mActiveD3DDriver->getAdapterIdentifier().VendorId == 0x10DE && 
+			fsaa >= 8)
+		{
+			tryCSAA	 = true;
+		}
+
+		while (!ok)
+		{
+			// Deal with special cases
+			if (tryCSAA)
+			{
+				// see http://developer.nvidia.com/object/coverage-sampled-aa.html
+				switch(fsaa)
+				{
+				case 8:
+					if (qualityHint)
+					{
+						outFSAASettings->Count = 8;
+						outFSAASettings->Quality = 8;
+					}
+					else
+					{
+						outFSAASettings->Count = 4;
+						outFSAASettings->Quality = 8;
+					}
+					break;
+				case 16:
+					if (qualityHint)
+					{
+						outFSAASettings->Count = 8;
+						outFSAASettings->Quality = 16;
+					}
+					else
+					{
+						outFSAASettings->Count = 4;
+						outFSAASettings->Quality = 16;
+					}
+					break;
+				}
+			}
+			else // !CSAA
+			{
+				outFSAASettings->Count = fsaa == 0 ? 1 : fsaa;
+				outFSAASettings->Quality = 0;
+			}
+
+
+			HRESULT hr;
+			UINT outQuality;
+			hr = mDevice->CheckMultisampleQualityLevels( 
+				format, 
+				outFSAASettings->Count, 
+				&outQuality);
+
+			if (SUCCEEDED(hr) && (!tryCSAA || outQuality > outFSAASettings->Quality))
+			{
+				ok = true;
+			}
+			else
+			{
+				// downgrade
+				if (tryCSAA && fsaa == 8)
+				{
+					// for CSAA, we'll try downgrading with quality mode at all samples.
+					// then try without quality, then drop CSAA
+					if (qualityHint)
+					{
+						// drop quality first
+						qualityHint = false;
+					}
+					else
+					{
+						// drop CSAA entirely 
+						tryCSAA = false;
+					}
+					// return to original requested samples
+					fsaa = static_cast<UINT32>(origFSAA);
+				}
+				else
+				{
+					// drop samples
+					--fsaa;
+
+					if (fsaa == 1)
+					{
+						// ran out of options, no FSAA
+						fsaa = 0;
+						ok = true;
+					}
+				}
+			}
+
+		} // while !ok
+		*/
+	}
 }

+ 778 - 0
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -0,0 +1,778 @@
+#include "CmD3D11RenderWindow.h"
+#include "CmWindowEventUtilities.h"
+#include "CmD3D11RenderSystem.h"
+#include "CmD3D11Device.h"
+#include "CmDepthStencilBuffer.h"
+#include "CmTextureManager.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	D3D11RenderWindow::D3D11RenderWindow(D3D11Device& device, IDXGIFactory* DXGIFactory)
+		: RenderWindow()
+		, mDevice(device)
+		, mDXGIFactory(DXGIFactory)
+		, mIsExternal(false)
+		, mSizing(false)
+		, mClosed(false)
+		, mHidden(false)
+		, mSwitchingFullscreen(false)
+		, mDisplayFrequency(0)
+		, mRenderTargetView(nullptr)
+		, mDepthStencilView(nullptr)
+		, mBackBuffer(nullptr)
+		, mSwapChain(nullptr)
+		, mHWnd(0)
+	{
+		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
+	}
+
+	D3D11RenderWindow::~D3D11RenderWindow()
+	{
+		destroy();
+	}
+
+	void D3D11RenderWindow::initialize(const String& name, unsigned int width, unsigned int height,
+		bool fullScreen, const NameValuePairList *miscParams)
+	{
+		mFSAAType.Count = 1;
+		mFSAAType.Quality = 0;
+		mFSAA = 0;
+		mFSAAHint = "";
+		mVSync = false;
+		mVSyncInterval = 1;
+		HWND parentHWnd = 0;
+		HWND externalHandle = 0;
+		String title = name;
+		int left = -1; // Defaults to screen center
+		int top = -1; // Defaults to screen center
+		String border = "";
+		bool outerSize = false;
+		bool enableDoubleClick = false;
+
+		unsigned int colourDepth = 32;
+		bool depthBuffer = true;
+
+		if(miscParams)
+		{
+			// Get variable-length params
+			NameValuePairList::const_iterator opt;
+			// vsync	[parseBool]
+			opt = miscParams->find("vsync");
+			if(opt != miscParams->end())
+				mVSync = parseBool(opt->second);
+			// vsyncInterval	[parseUnsignedInt]
+			opt = miscParams->find("vsyncInterval");
+			if(opt != miscParams->end())
+				mVSyncInterval = parseUnsignedInt(opt->second);
+			// hidden	[parseBool]
+			opt = miscParams->find("hidden");
+			if(opt != miscParams->end())
+				mHidden = parseBool(opt->second);
+			// displayFrequency
+			opt = miscParams->find("displayFrequency");
+			if(opt != miscParams->end())
+				mDisplayFrequency = parseUnsignedInt(opt->second);
+			// colourDepth
+			opt = miscParams->find("colourDepth");
+			if(opt != miscParams->end())
+				colourDepth = parseUnsignedInt(opt->second);
+			// depthBuffer [parseBool]
+			opt = miscParams->find("depthBuffer");
+			if(opt != miscParams->end())
+				depthBuffer = parseBool(opt->second);
+			// FSAA type
+			opt = miscParams->find("FSAA");
+			if(opt != miscParams->end())
+				mFSAA = parseUnsignedInt(opt->second);
+			// FSAA quality
+			opt = miscParams->find("FSAAHint");
+			if(opt != miscParams->end())
+				mFSAAHint = opt->second;
+			// sRGB?
+			opt = miscParams->find("gamma");
+			if(opt != miscParams->end())
+				mHwGamma = parseBool(opt->second);
+			// left (x)
+			opt = miscParams->find("left");
+			if(opt != miscParams->end())
+				left = parseInt(opt->second);
+			// top (y)
+			opt = miscParams->find("top");
+			if(opt != miscParams->end())
+				top = parseInt(opt->second);
+			// Window title
+			opt = miscParams->find("title");
+			if(opt != miscParams->end())
+				title = opt->second;
+			// parentWindowHandle		-> parentHWnd
+			opt = miscParams->find("parentWindowHandle");
+			if(opt != miscParams->end())
+				parentHWnd = (HWND)parseUnsignedInt(opt->second);
+			// externalWindowHandle		-> externalHandle
+			opt = miscParams->find("externalWindowHandle");
+			if(opt != miscParams->end())
+				externalHandle = (HWND)parseUnsignedInt(opt->second);
+			// window border style
+			opt = miscParams->find("border");
+			if(opt != miscParams->end())
+				border = opt->second;
+			// set outer dimensions?
+			opt = miscParams->find("outerDimensions");
+			if(opt != miscParams->end())
+				outerSize = parseBool(opt->second);
+			// enable double click messages
+			opt = miscParams->find("enableDoubleClick");
+			if(opt != miscParams->end())
+				enableDoubleClick = parseBool(opt->second);
+		}
+
+		mName = name;
+		mIsFullScreen = fullScreen;
+		mColourDepth = colourDepth;
+		mWidth = mHeight = mLeft = mTop = 0;
+
+		mActive = true;
+		mClosed = false;
+
+		// Destroy current window if any
+		if(mHWnd)
+			destroy();
+
+		if (!externalHandle)
+		{
+			DWORD dwStyle = (mHidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN;
+			RECT rc;
+
+			mWidth = width;
+			mHeight = height;
+			mTop = top;
+			mLeft = left;
+
+			if (!fullScreen)
+			{
+				if (parentHWnd)
+				{
+					dwStyle |= WS_CHILD;
+				}
+				else
+				{
+					if (border == "none")
+						dwStyle |= WS_POPUP;
+					else if (border == "fixed")
+						dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
+						WS_SYSMENU | WS_MINIMIZEBOX;
+					else
+						dwStyle |= WS_OVERLAPPEDWINDOW;
+				}
+
+				if (!outerSize)
+				{
+					// Calculate window dimensions required
+					// to get the requested client area
+					SetRect(&rc, 0, 0, mWidth, mHeight);
+					AdjustWindowRect(&rc, dwStyle, false);
+					mWidth = rc.right - rc.left;
+					mHeight = rc.bottom - rc.top;
+
+					// Clamp width and height to the desktop dimensions
+					int screenw = GetSystemMetrics(SM_CXSCREEN);
+					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;
+				}
+			}
+			else
+			{
+				dwStyle |= WS_POPUP;
+				mTop = mLeft = 0;
+			}
+
+			UINT classStyle = 0;
+			if (enableDoubleClick)
+				classStyle |= CS_DBLCLKS;
+
+			HINSTANCE hInst = NULL;
+
+			// Register the window class
+			// Allow 4 bytes of window data for D3D11RenderWindow pointer
+			WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst,
+				LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
+				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "D3D11Wnd" };	
+
+
+			RegisterClass(&wc);
+
+			// Create our main window
+			// Pass pointer to self
+			mIsExternal = false;
+			mHWnd = CreateWindow("D3D11Wnd", title.c_str(), dwStyle,
+				mLeft, mTop, mWidth, mHeight, parentHWnd, 0, hInst, this);
+
+			WindowEventUtilities::_addRenderWindow(this);
+		}
+		else
+		{
+			mHWnd = externalHandle;
+			mIsExternal = true;
+		}
+
+		RECT rc;
+		// top and left represent outer window coordinates
+		GetWindowRect(mHWnd, &rc);
+		mTop = rc.top;
+		mLeft = rc.left;
+		// width and height represent interior drawable area
+		GetClientRect(mHWnd, &rc);
+		mWidth = rc.right;
+		mHeight = rc.bottom;
+
+		_createSwapChain();
+		_createSizeDependedD3DResources();
+		mDXGIFactory->MakeWindowAssociation(mHWnd, NULL);
+		setHidden(mHidden);
+	}
+
+	void D3D11RenderWindow::destroy()
+	{
+		_destroySizeDependedD3DResources();
+
+		mActive = false;
+		mClosed = true;
+
+		SAFE_RELEASE(mSwapChain);
+
+		if (mHWnd && !mIsExternal)
+		{
+			WindowEventUtilities::_removeRenderWindow(this);
+			DestroyWindow(mHWnd);
+		}
+
+		mHWnd = nullptr;
+	}
+
+	void D3D11RenderWindow::swapBuffers(bool waitForVSync)
+	{
+		if(mDevice.getD3D11Device() != nullptr)
+		{
+			HRESULT hr = mSwapChain->Present(waitForVSync ? mVSyncInterval : 0, 0);
+
+			if( FAILED(hr) )
+				CM_EXCEPT(RenderingAPIException, "Error Presenting surfaces");
+		}
+	}
+
+	void D3D11RenderWindow::reposition(int top, int left)
+	{
+		if (mHWnd && !mIsFullScreen)
+		{
+			SetWindowPos(mHWnd, 0, top, left, 0, 0,
+				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+		}
+	}
+
+	void D3D11RenderWindow::resize(unsigned int width, unsigned int height)
+	{
+		if (mHWnd && !mIsFullScreen)
+		{
+			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);
+		}
+	}
+
+	void D3D11RenderWindow::windowMovedOrResized()
+	{
+		if (!mHWnd || IsIconic(mHWnd))
+			return;
+
+		RECT rc;
+		// top and left represent outer window position
+		GetWindowRect(mHWnd, &rc);
+		mTop = rc.top;
+		mLeft = rc.left;
+		// width and height represent drawable area only
+		GetClientRect(mHWnd, &rc);
+		unsigned int width = rc.right - rc.left;
+		unsigned int height = rc.bottom - rc.top;
+
+		if (width == 0) 
+			width = 1;
+		if (height == 0)
+			height = 1;
+
+		if (mWidth == width && mHeight == height)
+			return;
+
+		_resizeSwapChainBuffers(width, height);
+	}
+
+	void D3D11RenderWindow::setActive(bool state)
+	{
+		if (mHWnd && mSwapChain)
+		{
+			if (state)
+			{
+				ShowWindow(mHWnd, SW_RESTORE);
+				mSwapChain->SetFullscreenState(mIsFullScreen, nullptr);
+			}
+			else
+			{
+				ShowWindow(mHWnd, SW_SHOWMINIMIZED);
+				mSwapChain->SetFullscreenState(FALSE, nullptr);
+			}
+		}
+
+		RenderWindow::setActive(state);
+	}
+
+	void D3D11RenderWindow::setHidden(bool hidden)
+	{
+		mHidden = hidden;
+		if (!mIsExternal)
+		{
+			if (hidden)
+				ShowWindow(mHWnd, SW_HIDE);
+			else
+				ShowWindow(mHWnd, SW_SHOWNORMAL);
+		}
+	}
+
+	void D3D11RenderWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height)
+	{
+		if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight)
+		{
+			if (fullScreen != mIsFullScreen)
+				mSwitchingFullscreen = true;
+
+			DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
+
+			bool oldFullscreen = mIsFullScreen;
+			mIsFullScreen = fullScreen;
+
+			if (fullScreen)
+			{
+				dwStyle |= WS_POPUP;
+				mTop = mLeft = 0;
+				mWidth = width;
+				mHeight = height;
+				// need different ordering here
+
+				if (oldFullscreen)
+				{
+					// was previously fullscreen, just changing the resolution
+					SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
+				}
+				else
+				{
+					SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
+					//MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE);
+					SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
+					SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
+				}
+			}
+			else
+			{
+				dwStyle |= WS_OVERLAPPEDWINDOW;
+				// Calculate window dimensions required
+				// to get the requested client area
+				RECT rc;
+				SetRect(&rc, 0, 0, width, height);
+				AdjustWindowRect(&rc, dwStyle, false);
+				unsigned int winWidth = rc.right - rc.left;
+				unsigned int winHeight = rc.bottom - rc.top;
+
+				SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
+				SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight,
+					SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE);
+				// Note that we also set the position in the restoreLostDevice method
+				// via _finishSwitchingFullScreen
+			}
+
+			mSwapChainDesc.Windowed = !fullScreen;
+			mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+			mSwapChainDesc.BufferDesc.RefreshRate.Denominator=0;
+			mSwapChainDesc.BufferDesc.Height = height;
+			mSwapChainDesc.BufferDesc.Width = width;
+		}
+	} 
+
+	void D3D11RenderWindow::getCustomAttribute( const String& name, void* pData )
+	{
+		// Valid attributes and their equvalent native functions:
+		// D3DDEVICE			: getD3DDevice
+		// WINDOW				: getWindowHandle
+
+		if(name == "WINDOW")
+		{
+			HWND *pWnd = (HWND*)pData;
+			*pWnd = mHWnd;
+			return;
+		}
+
+		if(name == "D3DDEVICE")
+		{
+			ID3D11Device **device = (ID3D11Device **)pData;
+			*device = mDevice.getD3D11Device();
+			return;
+		}
+		else if(name == "isTexture")
+		{
+			bool *b = reinterpret_cast< bool * >( pData );
+			*b = false;
+			return;
+		}
+		else if(name == "ID3D11RenderTargetView")
+		{
+			*static_cast<ID3D11RenderTargetView**>(pData) = mRenderTargetView;
+			return;
+		}
+		else if(name == "ID3D11Texture2D")
+		{
+			ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData;
+			*pBackBuffer = mBackBuffer;
+			return;
+		}
+		else if(name == "numberOfViews")
+		{
+			unsigned int* n = reinterpret_cast<unsigned int*>(pData);
+			*n = 1;
+			return;
+		}
+		else if(name == "DDBACKBUFFER")
+		{
+			ID3D11Texture2D **ppBackBuffer = (ID3D11Texture2D**) pData;
+			ppBackBuffer[0] = NULL;
+			return;
+		}
+
+		RenderWindow::getCustomAttribute_internal(name, pData);
+	}
+
+	void D3D11RenderWindow::copyContentsToMemory(const PixelData &dst, FrameBuffer buffer)
+	{
+		if(mBackBuffer == nullptr)
+			return;
+
+		// get the backbuffer desc
+		D3D11_TEXTURE2D_DESC BBDesc;
+		mBackBuffer->GetDesc(&BBDesc);
+
+		ID3D11Texture2D *backbuffer = nullptr;
+
+		if(BBDesc.SampleDesc.Quality > 0)
+		{
+			D3D11_TEXTURE2D_DESC desc = BBDesc;
+			desc.Usage = D3D11_USAGE_DEFAULT;
+			desc.CPUAccessFlags = 0;
+			desc.BindFlags = 0;
+			desc.SampleDesc.Quality = 0;
+			desc.SampleDesc.Count = 1;
+
+			HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
+				&desc,
+				NULL,
+				&backbuffer);
+
+			if (FAILED(hr) || mDevice.hasError())
+			{
+				String errorDescription = mDevice.getErrorDescription();
+				CM_EXCEPT(RenderingAPIException,
+					"Error creating texture\nError Description:" + errorDescription);
+			}
+
+			mDevice.getImmediateContext()->ResolveSubresource(backbuffer, D3D11CalcSubresource(0, 0, 1), mBackBuffer, D3D11CalcSubresource(0, 0, 1), desc.Format);
+		}
+
+
+		// change the parameters of the texture so we can read it
+		BBDesc.Usage = D3D11_USAGE_STAGING;
+		BBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+		BBDesc.BindFlags = 0;
+		BBDesc.SampleDesc.Quality = 0;
+		BBDesc.SampleDesc.Count = 1;
+
+		// create a temp buffer to copy to
+		ID3D11Texture2D * pTempTexture2D;
+		HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
+			&BBDesc,
+			NULL,
+			&pTempTexture2D);
+
+		if (FAILED(hr) || mDevice.hasError())
+		{
+			String errorDescription = mDevice.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException,
+				"Error creating texture\nError Description:" + errorDescription);
+		}
+		// copy the back buffer
+		mDevice.getImmediateContext()->CopyResource(pTempTexture2D, backbuffer != NULL ? backbuffer : mBackBuffer);
+
+		// map the copied texture
+		D3D11_MAPPED_SUBRESOURCE mappedTex2D;
+		mDevice.getImmediateContext()->Map(pTempTexture2D, 0,D3D11_MAP_READ, 0, &mappedTex2D);
+
+		// copy the the texture to the dest
+		PixelUtil::bulkPixelConversion(PixelData(mWidth, mHeight, 1, PF_A8B8G8R8, mappedTex2D.pData), dst);
+
+		// unmap the temp buffer
+		mDevice.getImmediateContext()->Unmap(pTempTexture2D, 0);
+
+		// Release the temp buffer
+		SAFE_RELEASE(pTempTexture2D);
+		SAFE_RELEASE(backbuffer);
+	}
+
+	void D3D11RenderWindow::_createSwapChain()
+	{
+		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
+
+		// get the dxgi device
+		IDXGIDevice* pDXGIDevice = _queryDxgiDevice();
+
+		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
+		DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
+		mSwapChainDesc.OutputWindow			= mHWnd;
+		mSwapChainDesc.BufferDesc.Width		= mWidth;
+		mSwapChainDesc.BufferDesc.Height	= mHeight;
+		mSwapChainDesc.BufferDesc.Format	= format;
+		mSwapChainDesc.BufferDesc.RefreshRate.Numerator=0;
+		mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
+
+		mSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+		mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+		mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ;
+
+		// triple buffer if VSync is on
+		mSwapChainDesc.BufferUsage			= DXGI_USAGE_RENDER_TARGET_OUTPUT;
+		mSwapChainDesc.BufferCount			= mVSync ? 2 : 1;
+		mSwapChainDesc.SwapEffect			= DXGI_SWAP_EFFECT_DISCARD ;
+
+		mSwapChainDesc.OutputWindow 		= mHWnd;
+		mSwapChainDesc.Windowed				= !mIsFullScreen;
+
+		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
+		rs->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType);
+		mSwapChainDesc.SampleDesc.Count = mFSAAType.Count;
+		mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality;
+
+		HRESULT hr;
+
+		// Create swap chain			
+		hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
+
+		if (FAILED(hr))
+		{
+			// Try a second time, may fail the first time due to back buffer count,
+			// which will be corrected by the runtime
+			hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
+		}
+
+		SAFE_RELEASE(pDXGIDevice);
+
+		if (FAILED(hr))
+			CM_EXCEPT(RenderingAPIException, "Unable to create swap chain");
+	}
+
+	void D3D11RenderWindow::_createSizeDependedD3DResources()
+	{
+		// obtain back buffer
+		SAFE_RELEASE(mBackBuffer);
+
+		HRESULT hr = mSwapChain->GetBuffer(0,  __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer);
+		if( FAILED(hr) )
+			CM_EXCEPT(RenderingAPIException, "Unable to Get Back Buffer for swap chain");
+
+		// create all other size depended resources
+		assert(mBackBuffer && !mRenderTargetView && !mDepthStencilView);
+
+		// get the backbuffer desc
+		D3D11_TEXTURE2D_DESC BBDesc;
+		mBackBuffer->GetDesc(&BBDesc);
+
+		// create the render target view
+		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
+		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
+
+		RTVDesc.Format = BBDesc.Format;
+		RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
+		RTVDesc.Texture2D.MipSlice = 0;
+		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
+
+		if( FAILED(hr) )
+		{
+			String errorDescription = mDevice.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Unable to create rendertagert view\nError Description:" + errorDescription);
+		}
+
+		mDepthStencilBuffer = TextureManager::instance().createDepthStencilBuffer(32, BBDesc.Width, BBDesc.Height, mFSAA, mFSAAHint);
+
+		//if(mDepthBufferPoolId != DepthStencilBuffer::POOL_NO_DEPTH)
+		//{
+		//	// Create depth stencil texture
+		//	ID3D11Texture2D* pDepthStencil = NULL;
+		//	D3D11_TEXTURE2D_DESC descDepth;
+
+		//	descDepth.Width = BBDesc.Width;
+		//	descDepth.Height = BBDesc.Height;
+		//	descDepth.MipLevels = 1;
+		//	descDepth.ArraySize = 1;
+		//	descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+		//	descDepth.SampleDesc.Count = mFSAAType.Count;
+		//	descDepth.SampleDesc.Quality = mFSAAType.Quality;
+		//	descDepth.Usage = D3D11_USAGE_DEFAULT;
+		//	descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+		//	descDepth.CPUAccessFlags = 0;
+		//	descDepth.MiscFlags = 0;
+
+		//	hr = mDevice.getD3D11Device()->CreateTexture2D(&descDepth, NULL, &pDepthStencil);
+		//	if( FAILED(hr) || mDevice.hasError())
+		//	{
+		//		String errorDescription = mDevice.getErrorDescription(hr);
+		//		CM_EXCEPT(RenderingAPIException, "Unable to create depth texture\nError Description:" + errorDescription);
+		//	}
+
+		//	// Create the depth stencil view
+		//	D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
+		//	ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) );
+
+		//	descDSV.Format =  descDepth.Format;
+		//	descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
+		//	descDSV.Texture2D.MipSlice = 0;
+		//	hr = mDevice.getD3D11Device()->CreateDepthStencilView(pDepthStencil, &descDSV, &mDepthStencilView);
+
+		//	SAFE_RELEASE(pDepthStencil);
+
+		//	if( FAILED(hr) )
+		//	{
+		//		String errorDescription = mDevice.getErrorDescription();
+		//		CM_EXCEPT(RenderingAPIException, 
+		//			"Unable to create depth stencil view\nError Description:" + errorDescription);
+		//	}
+
+		//	D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
+		//	DepthStencilBuffer *depthBuf = rsys->_addManualDepthBuffer(mDepthStencilView, mWidth, mHeight, mFSAAType.Count, mFSAAType.Quality);
+
+		//	//Don't forget we want this window to use _this_ depth buffer
+		//	this->attachDepthBuffer(depthBuf);
+		//} 
+	}
+
+	void D3D11RenderWindow::_destroySizeDependedD3DResources()
+	{
+		SAFE_RELEASE(mBackBuffer);
+		SAFE_RELEASE(mRenderTargetView);
+
+		mDepthStencilBuffer = nullptr;
+
+		SAFE_RELEASE(mDepthStencilView);
+	}
+
+	void D3D11RenderWindow::_resizeSwapChainBuffers(unsigned width, unsigned height)
+	{
+		_destroySizeDependedD3DResources();
+
+		// width and height can be zero to autodetect size, therefore do not rely on them
+		UINT Flags = mIsFullScreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
+		mSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags);
+		mSwapChain->GetDesc(&mSwapChainDesc);
+		mWidth = mSwapChainDesc.BufferDesc.Width;
+		mHeight = mSwapChainDesc.BufferDesc.Height;
+		mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state
+
+		_createSizeDependedD3DResources();
+
+		mDevice.getImmediateContext()->OMSetRenderTargets(0, 0, 0);
+		// Additional swap chains need their own depth buffer
+		// to support resizing them
+
+		HRESULT hr = mSwapChain->GetBuffer( 0,  __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer  );
+		if( FAILED(hr) )
+		{
+			CM_EXCEPT(RenderingAPIException, 
+				"Unable to Get Back Buffer for swap chain");
+		}
+
+		// get the backbuffer desc
+		D3D11_TEXTURE2D_DESC BBDesc;
+		mBackBuffer->GetDesc(&BBDesc);
+
+		// create the render target view
+		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
+		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
+
+		RTVDesc.Format = BBDesc.Format;
+		RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
+		RTVDesc.Texture2D.MipSlice = 0;
+		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
+
+		if(FAILED(hr))
+		{
+			String errorDescription = mDevice.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, 
+				"Unable to create rendertagert view\nError Description:" + errorDescription);
+		}
+	}
+
+	IDXGIDevice* D3D11RenderWindow::_queryDxgiDevice()
+	{
+		if (mDevice.getD3D11Device() == nullptr)
+		{
+			CM_EXCEPT(RenderingAPIException, "D3D11Device is NULL!");
+		}
+
+		IDXGIDevice* pDXGIDevice = nullptr;
+		HRESULT hr = mDevice.getD3D11Device()->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDXGIDevice);
+		if(FAILED(hr))
+			CM_EXCEPT(RenderingAPIException, "Unable to query a DXGIDevice");
+
+		return pDXGIDevice;
+	}
+
+	void D3D11RenderWindow::_finishSwitchingFullscreen()
+	{
+		if(mIsFullScreen)
+		{
+			// Need to reset the region on the window sometimes, when the 
+			// windowed mode was constrained by desktop 
+			HRGN hRgn = CreateRectRgn(0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
+			SetWindowRgn(mHWnd, hRgn, FALSE);
+		}
+		else
+		{
+			// When switching back to windowed mode, need to reset window size 
+			// after device has been restored
+			RECT rc;
+			SetRect(&rc, 0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
+			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
+			unsigned int winWidth = rc.right - rc.left;
+			unsigned int winHeight = rc.bottom - rc.top;
+			int screenw = GetSystemMetrics(SM_CXSCREEN);
+			int screenh = GetSystemMetrics(SM_CYSCREEN);
+			int left = (screenw - winWidth) / 2;
+			int top = (screenh - winHeight) / 2;
+			SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight,
+				SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
+		}
+
+		mSwapChain->SetFullscreenState(mIsFullScreen, NULL);
+		mSwitchingFullscreen = false;
+	}
+
+	bool D3D11RenderWindow::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format)
+	{
+		if (SUCCEEDED(mDevice.getD3D11Device()->CheckMultisampleQualityLevels(format, SampleCount, outQuality)))
+			return true;
+		else
+			return false;
+	}
+}

+ 2 - 0
CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj

@@ -147,6 +147,7 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClInclude Include="Include\CmD3D9DepthStencilBuffer.h" />
     <ClInclude Include="Include\CmD3D9Device.h" />
     <ClInclude Include="Include\CmD3D9DeviceManager.h" />
     <ClInclude Include="Include\CmD3D9Driver.h" />
@@ -178,6 +179,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="CmD3D9Plugin.cpp" />
+    <ClCompile Include="Source\CmD3D9DepthStencilBuffer.cpp" />
     <ClCompile Include="Source\CmD3D9Device.cpp" />
     <ClCompile Include="Source\CmD3D9DeviceManager.cpp" />
     <ClCompile Include="Source\CmD3D9Driver.cpp" />

+ 6 - 0
CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj.filters

@@ -102,6 +102,9 @@
     <ClInclude Include="Include\CmD3D9RenderWindowManager.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D9DepthStencilBuffer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D9Device.cpp">
@@ -185,5 +188,8 @@
     <ClCompile Include="Source\CmD3D9RenderWindowManager.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D9DepthStencilBuffer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 15 - 0
CamelotD3D9Renderer/Include/CmD3D9DepthStencilBuffer.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "CmD3D9Prerequisites.h"
+#include "CmDepthStencilBuffer.h"
+
+namespace CamelotEngine
+{
+	class CM_D3D9_EXPORT D3D9DepthStencilBuffer : public DepthStencilBuffer
+	{
+	public:
+		D3D9DepthStencilBuffer(UINT32 bitDepth, UINT32 width, UINT32 height, UINT32 fsaa, const String &fsaaHint);
+
+		// TODO - Add D3D9 specific implementation
+	};
+}

+ 6 - 0
CamelotD3D9Renderer/Include/CmD3D9TextureManager.h

@@ -47,6 +47,12 @@ namespace CamelotEngine
         bool isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage,
             bool preciseFormatOnly = false);		
 
+		/**
+		 * @copydoc TextureManager::createDepthStencilBuffer()
+		 */
+		DepthStencilBufferPtr createDepthStencilBuffer(UINT32 bitDepth, UINT32 width, 
+			UINT32 height, UINT32 fsaa, const String& fsaaHint);
+
 	protected:		
 		D3D9Texture* createImpl();
 	};

+ 8 - 0
CamelotD3D9Renderer/Source/CmD3D9DepthStencilBuffer.cpp

@@ -0,0 +1,8 @@
+#include "CmD3D9DepthStencilBuffer.h"
+
+namespace CamelotEngine
+{
+	D3D9DepthStencilBuffer::D3D9DepthStencilBuffer(UINT32 bitDepth, UINT32 width, UINT32 height, UINT32 fsaa, const String &fsaaHint)
+		:DepthStencilBuffer(bitDepth, width, height, fsaa, fsaaHint)
+	{ }
+}

+ 7 - 0
CamelotD3D9Renderer/Source/CmD3D9TextureManager.cpp

@@ -30,6 +30,7 @@ THE SOFTWARE.
 #include "CmException.h"
 #include "CmD3D9Mappings.h"
 #include "CmD3D9RenderSystem.h"
+#include "CmD3D9DepthStencilBuffer.h"
 
 namespace CamelotEngine 
 {
@@ -48,6 +49,12 @@ namespace CamelotEngine
 		return new D3D9Texture();
     }
 
+	DepthStencilBufferPtr D3D9TextureManager::createDepthStencilBuffer(UINT32 bitDepth, UINT32 width, 
+		UINT32 height, UINT32 fsaa, const String& fsaaHint)
+	{
+		return DepthStencilBufferPtr(new D3D9DepthStencilBuffer(bitDepth, width, height, fsaa, fsaaHint));
+	}
+
 	PixelFormat D3D9TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage)
 	{
 		// Basic filtering

+ 2 - 0
CamelotGLRenderer/CamelotGLRenderer.vcxproj

@@ -150,6 +150,7 @@
     <ClInclude Include="Include\CmGLATIFSInit.h" />
     <ClInclude Include="Include\CmGLContext.h" />
     <ClInclude Include="Include\CmGLDefaultHardwareBufferManager.h" />
+    <ClInclude Include="Include\CmGLDepthStencilBuffer.h" />
     <ClInclude Include="Include\CmGLMultiRenderTarget.h" />
     <ClInclude Include="Include\CmGLFrameBufferObject.h" />
     <ClInclude Include="Include\CmGLGpuProgram.h" />
@@ -193,6 +194,7 @@
     <ClCompile Include="Source\CmGLATIFSInit.cpp" />
     <ClCompile Include="Source\CmGLContext.cpp" />
     <ClCompile Include="Source\CmGLDefaultHardwareBufferManager.cpp" />
+    <ClCompile Include="Source\CmGLDepthStencilBuffer.cpp" />
     <ClCompile Include="Source\CmGLMultiRenderTarget.cpp" />
     <ClCompile Include="Source\CmGLFrameBufferObject.cpp" />
     <ClCompile Include="Source\CmGLGpuProgram.cpp" />

+ 6 - 0
CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters

@@ -138,6 +138,9 @@
     <ClInclude Include="Include\CmGLRenderWindowManager.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmGLDepthStencilBuffer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\atifs\src\ATI_FS_GLGpuProgram.cpp">
@@ -245,5 +248,8 @@
     <ClCompile Include="Source\CmGLRenderWindowManager.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmGLDepthStencilBuffer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 6 - 0
CamelotGLRenderer/Include/CmGLTextureManager.h

@@ -51,6 +51,12 @@ namespace CamelotEngine {
         bool isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage,
             bool preciseFormatOnly = false);
 
+		/**
+		 * @copydoc TextureManager::createDepthStencilBuffer()
+		 */
+		DepthStencilBufferPtr createDepthStencilBuffer(UINT32 bitDepth, UINT32 width, 
+			UINT32 height, UINT32 fsaa, const String& fsaaHint);
+
     protected:
         /// @copydoc ResourceManager::createImpl
         Texture* createImpl();

+ 8 - 0
CamelotGLRenderer/Source/CmGLDepthStencilBuffer.cpp

@@ -0,0 +1,8 @@
+#include "CmGLDepthStencilBuffer.h"
+
+namespace CamelotEngine
+{
+	GLDepthStencilBuffer::GLDepthStencilBuffer(UINT32 bitDepth, UINT32 width, UINT32 height, UINT32 fsaa, const String &fsaaHint)
+		:DepthStencilBuffer(bitDepth, width, height, fsaa, fsaaHint)
+	{ }
+}

+ 7 - 1
CamelotGLRenderer/Source/CmGLTextureManager.cpp

@@ -29,6 +29,7 @@ THE SOFTWARE.
 #include "CmGLTextureManager.h"
 #include "CmRenderSystem.h"
 #include "CmGLRenderTexture.h"
+#include "CmGLDepthStencilBuffer.h"
 
 namespace CamelotEngine {
     //-----------------------------------------------------------------------------
@@ -48,7 +49,12 @@ namespace CamelotEngine {
     {
         return new GLTexture(mGLSupport);
     }
-
+	//----------------------------------------------------------------------------
+	DepthStencilBufferPtr GLTextureManager::createDepthStencilBuffer(UINT32 bitDepth, UINT32 width, 
+		UINT32 height, UINT32 fsaa, const String& fsaaHint)
+	{
+		return DepthStencilBufferPtr(new GLDepthStencilBuffer(bitDepth, width, height, fsaa, fsaaHint));
+	}
 	//-----------------------------------------------------------------------------
 	void GLTextureManager::createWarningTexture()
 	{

+ 2 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -189,6 +189,7 @@
     <ClInclude Include="Include\CmConfigOptionMap.h" />
     <ClInclude Include="Include\CmDefaultHardwareBufferManager.h" />
     <ClInclude Include="Include\CmDeferredRenderContext.h" />
+    <ClInclude Include="Include\CmDepthStencilBuffer.h" />
     <ClInclude Include="Include\CmDepthStencilStateRTTI.h" />
     <ClInclude Include="Include\CmDepthStencilState.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
@@ -272,6 +273,7 @@
     <ClCompile Include="Source\CmCommandQueue.cpp" />
     <ClCompile Include="Source\CmDefaultHardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmDeferredRenderContext.cpp" />
+    <ClCompile Include="Source\CmDepthStencilBuffer.cpp" />
     <ClCompile Include="Source\CmDepthStencilState.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />

+ 6 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -344,6 +344,9 @@
     <ClInclude Include="Include\CmRenderWindowManager.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmDepthStencilBuffer.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -514,5 +517,8 @@
     <ClCompile Include="Source\CmRenderWindowManager.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmDepthStencilBuffer.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 38 - 0
CamelotRenderer/Include/CmDepthStencilBuffer.h

@@ -0,0 +1,38 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT DepthStencilBuffer
+	{
+	public:
+		DepthStencilBuffer(UINT32 bitDepth, UINT32 width, UINT32 height, UINT32 fsaa, const String &fsaaHint);
+		virtual ~DepthStencilBuffer();
+
+		UINT32 getBitDepth() const { return mBitDepth; }
+		UINT32 getWidth() const { return mWidth; }
+		UINT32 getHeight() const { return mHeight; }
+		UINT32 getFsaa() const { return mFsaa; }
+		const String& getFsaaHint() const { return mFsaaHint; }
+
+		/** Returns whether the specified RenderTarget is compatible with this DepthBuffer
+			That is, this DepthBuffer can be attached to that RenderTarget
+            @note
+                Most APIs impose the following restrictions:
+				Width & height must be equal or higher than the render target's
+				They must be of the same bit depth.
+				They need to have the same FSAA setting
+        */
+		virtual bool isCompatible(RenderTarget *renderTarget) const;
+
+	protected:
+		UINT32						mBitDepth;
+		UINT32						mWidth;
+		UINT32						mHeight;
+		UINT32						mFsaa;
+		String						mFsaaHint;
+
+		void detachFromAllRenderTargets();
+	};
+}

+ 2 - 0
CamelotRenderer/Include/CmPrerequisites.h

@@ -89,6 +89,7 @@ namespace CamelotEngine {
     class RenderTexture;
 	class MultiRenderTarget;
     class RenderWindow;
+	class DepthStencilBuffer;
     class RenderOperation;
     class StringInterface;
     class SamplerState;
@@ -167,6 +168,7 @@ namespace CamelotEngine
 	typedef std::shared_ptr<BlendState> BlendStatePtr;
 	typedef std::shared_ptr<RenderWindow> RenderWindowPtr;
 	typedef std::shared_ptr<RenderTarget> RenderTargetPtr;
+	typedef std::shared_ptr<DepthStencilBuffer> DepthStencilBufferPtr;
 }
 
 // All type IDs used for RTTI

+ 7 - 0
CamelotRenderer/Include/CmRenderTarget.h

@@ -198,6 +198,11 @@ namespace CamelotEngine {
 		*/
 		virtual const String& getFSAAHint() const { return mFSAAHint; }
 
+		/**
+		 * @brief	Gets the depth stencil buffer attached to this render target.
+		 */
+		virtual DepthStencilBufferPtr getDepthStencilBuffer() const { return mDepthStencilBuffer; }
+
         /** RenderSystem specific interface for a RenderTarget;
             this should be subclassed by RenderSystems.
         */
@@ -252,6 +257,8 @@ namespace CamelotEngine {
 		/// The priority of the render target.
 		UINT8 mPriority;
 
+		DepthStencilBufferPtr mDepthStencilBuffer;
+
         unsigned int mWidth;
         unsigned int mHeight;
         unsigned int mColourDepth;

+ 5 - 0
CamelotRenderer/Include/CmRenderTexture.h

@@ -54,6 +54,11 @@ namespace CamelotEngine
 		virtual void copyContentsToMemory(const PixelData &dst, FrameBuffer buffer);
 		PixelFormat suggestPixelFormat() const;
 
+		/**
+		 * @brief	Sets the depth stencil buffer attached to this render target.
+		 */
+		//virtual void setDepthStencilBuffer(DepthStencilBufferPtr depthStencil) = 0;
+
 	protected:
 		HardwarePixelBuffer *mBuffer;
 		UINT32 mZOffset;

+ 7 - 0
CamelotRenderer/Include/CmTextureManager.h

@@ -172,6 +172,13 @@ namespace CamelotEngine {
 		 */
 		TexturePtr createEmpty();
 
+		/**
+		 * @brief	Creates a new depth/stencil buffer.
+		 */
+		virtual DepthStencilBufferPtr createDepthStencilBuffer(UINT32 bitDepth, UINT32 width, 
+			UINT32 height, UINT32 fsaa, const String& fsaaHint) = 0;
+
+
 		/** Returns whether this render system can natively support the precise texture 
 			format requested with the given usage options.
 		@remarks

+ 32 - 0
CamelotRenderer/Source/CmDepthStencilBuffer.cpp

@@ -0,0 +1,32 @@
+#include "CmDepthStencilBuffer.h"
+#include "CmRenderTarget.h"
+
+namespace CamelotEngine
+{
+	DepthStencilBuffer::DepthStencilBuffer(UINT32 bitDepth, UINT32 width, UINT32 height, UINT32 fsaa, const String &fsaaHint)
+		: mBitDepth(bitDepth)
+		, mWidth(width)
+		, mHeight(height)
+		, mFsaa(fsaa)
+		, mFsaaHint(fsaaHint)
+	{
+
+	}
+
+	DepthStencilBuffer::~DepthStencilBuffer()
+	{
+
+	}
+
+	bool DepthStencilBuffer::isCompatible(RenderTarget *renderTarget) const
+	{
+		if( this->getWidth() >= renderTarget->getWidth() &&
+			this->getHeight() >= renderTarget->getHeight() &&
+			this->getFsaa() == renderTarget->getFSAA() )
+		{
+			return true;
+		}
+
+		return false;
+	}
+}

+ 3 - 1
CamelotRenderer/Source/CmRenderWindow.cpp

@@ -32,7 +32,9 @@ THE SOFTWARE.
 namespace CamelotEngine {
 
     RenderWindow::RenderWindow()
-        : RenderTarget(), mIsPrimary(false)
+        : RenderTarget()
+		, mIsPrimary(false)
+		, mIsFullScreen(false)
     {
         mAutoDeactivatedOnFocusChange = true;
     }

+ 5 - 2
CamelotRenderer/TODO.txt

@@ -23,8 +23,6 @@ Move createRenderTexture to TextureManager? (also createMultiRenderTexture)
  - Right now its created with a special texture usage flag, which I don't like
 Drop OpenGL support for low level shaders? (See if cg can translate to GLSL)
 
-Make RenderSystem a module? (Initialize it using startUp, and get rid of directly accessing RenderSystemManager whenever I need the active RenderSystem)
-
 Keeping a list of all render targets in RenderSystem shouldn't be needed (and calling attach/detach renderTarget). Renderer should determine in what order are render targets presented.
 
 Make CommandQueue not use mutexes and use atomics instead??
@@ -53,6 +51,11 @@ RenderSystem needed modifications
  - 1D/2D/Cube texture arrays
  - Multisampled texture resources
  - Multiple adapters (multi gpu)
+ - DX11 allows detachable and reusable depthStencil buffers but right now DX9 and OpenGL just ignore them
+   - Also RenderWindow can't have detachable depth stencil buffers for multiple reasons:
+     - Resizing a window requires a resize of the depth/stencil buffer, so what to do if the buffer is external?
+	 - OpenGL doesn't allow access to primary window buffer anyway
+	 - Is there any situation where I actually need to set primary depth buffer?
  - Process OpenGL and make sure to equivalents of DX11 features
   - Exact features that are missing (not an exhaustive list):
     - Vertex buffer stream out (Transform Feedback)