Pārlūkot izejas kodu

Added DX11 RenderWindow
Some basic support for separate DepthStencilBuffer class

Marko Pintera 13 gadi atpakaļ
vecāks
revīzija
cd4008400e
27 mainītis faili ar 1158 papildinājumiem un 65 dzēšanām
  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)