Parcourir la source

WIP video modes

Marko Pintera il y a 11 ans
Parent
commit
f9f157ec22
35 fichiers modifiés avec 735 ajouts et 475 suppressions
  1. 1 2
      BansheeEditor/Source/BsEditorWindowBase.cpp
  2. 3 4
      BansheeEditor/Source/BsMainEditorWindow.cpp
  3. 1 1
      BansheeEditorExec/BsEditorExec.cpp
  4. 1 1
      BansheeEngine/Include/BsBuiltinResources.h
  5. 6 8
      BansheeEngine/Include/BsCamera.h
  6. 1 0
      BansheeEngine/Include/BsRenderable.h
  7. 1 1
      BansheeEngine/Include/BsVirtualInput.h
  8. 6 34
      BansheeEngine/Source/BsCamera.cpp
  9. 1 1
      BansheeEngine/Source/BsProfilerOverlay.cpp
  10. 5 0
      BansheeEngine/Source/BsRenderable.cpp
  11. 2 0
      CamelotCore/CamelotCore.vcxproj
  12. 6 0
      CamelotCore/CamelotCore.vcxproj.filters
  13. 4 0
      CamelotCore/Include/CmPrerequisites.h
  14. 8 0
      CamelotCore/Include/CmRenderSystem.h
  15. 22 3
      CamelotCore/Include/CmRenderWindow.h
  16. 105 0
      CamelotCore/Include/CmVideoModeInfo.h
  17. 28 0
      CamelotCore/Source/CmVideoModeInfo.cpp
  18. 2 4
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj
  19. 6 12
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters
  20. 3 5
      CamelotD3D11RenderSystem/Include/CmD3D11Driver.h
  21. 32 28
      CamelotD3D11RenderSystem/Include/CmD3D11RenderWindow.h
  22. 0 29
      CamelotD3D11RenderSystem/Include/CmD3D11VideoMode.h
  23. 60 0
      CamelotD3D11RenderSystem/Include/CmD3D11VideoModeInfo.h
  24. 0 25
      CamelotD3D11RenderSystem/Include/CmD3D11VideoModeList.h
  25. 0 26
      CamelotD3D11RenderSystem/Source/CmD3D11Driver.cpp
  26. 4 3
      CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp
  27. 77 89
      CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp
  28. 0 43
      CamelotD3D11RenderSystem/Source/CmD3D11VideoMode.cpp
  29. 135 0
      CamelotD3D11RenderSystem/Source/CmD3D11VideoModeInfo.cpp
  30. 0 112
      CamelotD3D11RenderSystem/Source/CmD3D11VideoModeList.cpp
  31. 1 1
      ExampleProject/ExampleProject.vcxproj
  32. 1 1
      ExampleProject/ExampleProject.vcxproj.filters
  33. 192 0
      ExampleProject/Main/Main.cpp
  34. 0 41
      ExampleProject/Main/Source.cpp
  35. 21 1
      Polish.txt

+ 1 - 2
BansheeEditor/Source/BsEditorWindowBase.cpp

@@ -64,8 +64,7 @@ namespace BansheeEngine
 		mRenderWindow = renderWindow;
 		mRenderWindow = renderWindow;
 		mSceneObject = SceneObject::create("EditorWindow");
 		mSceneObject = SceneObject::create("EditorWindow");
 
 
-		mCamera = mSceneObject->addComponent<Camera>();
-		mCamera->initialize(renderWindow, 0.0f, 0.0f, 1.0f, 1.0f);
+		mCamera = mSceneObject->addComponent<Camera>(renderWindow, 0.0f, 0.0f, 1.0f, 1.0f);
 		mCamera->setNearClipDistance(5);
 		mCamera->setNearClipDistance(5);
 		mCamera->setAspectRatio(1.0f);
 		mCamera->setAspectRatio(1.0f);
 		mCamera->setIgnoreSceneRenderables(true);
 		mCamera->setIgnoreSceneRenderables(true);

+ 3 - 4
BansheeEditor/Source/BsMainEditorWindow.cpp

@@ -49,13 +49,12 @@ namespace BansheeEngine
 
 
 		// DEBUG ONLY
 		// DEBUG ONLY
 
 
-		HSceneObject sceneCameraGO = SceneObject::create("SceneCamera");
-		HCamera sceneCamera = sceneCameraGO->addComponent<Camera>();
-
 		RenderTexturePtr sceneRenderTarget = RenderTexture::create(TEX_TYPE_2D, 800, 600);
 		RenderTexturePtr sceneRenderTarget = RenderTexture::create(TEX_TYPE_2D, 800, 600);
 		sceneRenderTarget->setPriority(1);
 		sceneRenderTarget->setPriority(1);
 
 
-		sceneCamera->initialize(sceneRenderTarget, 0.0f, 0.0f, 1.0f, 1.0f);
+		HSceneObject sceneCameraGO = SceneObject::create("SceneCamera");
+		HCamera sceneCamera = sceneCameraGO->addComponent<Camera>(sceneRenderTarget, 0.0f, 0.0f, 1.0f, 1.0f);
+
 		sceneCamera->setPriority(1);
 		sceneCamera->setPriority(1);
 		sceneCameraGO->setPosition(Vector3(0,50,1240));
 		sceneCameraGO->setPosition(Vector3(0,50,1240));
 		sceneCameraGO->lookAt(Vector3(0,50,-300));
 		sceneCameraGO->lookAt(Vector3(0,50,-300));

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

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

+ 1 - 1
BansheeEngine/Include/BsBuiltinResources.h

@@ -16,7 +16,7 @@ namespace BansheeEngine
 		BuiltinResources();
 		BuiltinResources();
 		~BuiltinResources();
 		~BuiltinResources();
 
 
-		const GUISkin& getSkin() const { return mSkin; }
+		const GUISkin& getGUISkin() const { return mSkin; }
 
 
 		const HSpriteTexture getWhiteSpriteTexture() const { return mWhiteSpriteTexture; }
 		const HSpriteTexture getWhiteSpriteTexture() const { return mWhiteSpriteTexture; }
 
 

+ 6 - 8
BansheeEngine/Include/BsCamera.h

@@ -514,14 +514,16 @@ namespace BansheeEngine {
 		mutable Vector3 mWorldSpaceCorners[8];
 		mutable Vector3 mWorldSpaceCorners[8];
 
 
     public:
     public:
-        /** Standard destructor.
+		/** Standard constructor.
         */
         */
-        virtual ~Camera();
-
-		void initialize(RenderTargetPtr target = nullptr,
+		Camera(const HSceneObject& parent, RenderTargetPtr target = nullptr,
 			float left = 0.0f, float top = 0.0f,
 			float left = 0.0f, float top = 0.0f,
 			float width = 1.0f, float height = 1.0f);
 			float width = 1.0f, float height = 1.0f);
 
 
+        /** Standard destructor.
+        */
+        virtual ~Camera();
+
 		ViewportPtr getViewport() const { return mViewport; }
 		ViewportPtr getViewport() const { return mViewport; }
 
 
 		/************************************************************************/
 		/************************************************************************/
@@ -530,10 +532,6 @@ namespace BansheeEngine {
 	protected:
 	protected:
 		friend class SceneObject;
 		friend class SceneObject;
 
 
-		/** Standard constructor.
-        */
-		Camera(const HSceneObject& parent);
-
 	public:
 	public:
 		virtual void update() {}
 		virtual void update() {}
 
 

+ 1 - 0
BansheeEngine/Include/BsRenderable.h

@@ -13,6 +13,7 @@ namespace BansheeEngine
 		void setMesh(HMesh mesh) { mMesh = mesh; }
 		void setMesh(HMesh mesh) { mMesh = mesh; }
 		void setNumMaterials(UINT32 numMaterials);
 		void setNumMaterials(UINT32 numMaterials);
 		void setMaterial(UINT32 idx, HMaterial material);
 		void setMaterial(UINT32 idx, HMaterial material);
+		void setMaterial(HMaterial material);
 		void setLayer(UINT64 layer);
 		void setLayer(UINT64 layer);
 
 
 		UINT64 getLayer() const { return mLayer; }
 		UINT64 getLayer() const { return mLayer; }

+ 1 - 1
BansheeEngine/Include/BsVirtualInput.h

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		static std::shared_ptr<InputConfiguration> createConfiguration();
 		static std::shared_ptr<InputConfiguration> createConfiguration();
 
 
 		void setConfiguration(const std::shared_ptr<InputConfiguration>& input);
 		void setConfiguration(const std::shared_ptr<InputConfiguration>& input);
-		const std::shared_ptr<InputConfiguration>& getConfiguration() const { return mInputConfiguration; }
+		std::shared_ptr<InputConfiguration> getConfiguration() const { return mInputConfiguration; }
 
 
 		bool isButtonDown(const VirtualButton& button) const;
 		bool isButtonDown(const VirtualButton& button) const;
 		bool isButtonUp(const VirtualButton& button) const;
 		bool isButtonUp(const VirtualButton& button) const;

+ 6 - 34
BansheeEngine/Source/BsCamera.cpp

@@ -1,30 +1,3 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
 #include "BsCamera.h"
 #include "BsCamera.h"
 #include "BsCameraRTTI.h"
 #include "BsCameraRTTI.h"
 
 
@@ -45,7 +18,9 @@ namespace BansheeEngine
 	const float Camera::INFINITE_FAR_PLANE_ADJUST = 0.00001f;
 	const float Camera::INFINITE_FAR_PLANE_ADJUST = 0.00001f;
 
 
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-	Camera::Camera(const HSceneObject& parent)
+	Camera::Camera(const HSceneObject& parent, RenderTargetPtr target,
+		float left, float top,
+		float width, float height)
         : Component(parent),
         : Component(parent),
 		mProjType(PT_PERSPECTIVE), 
 		mProjType(PT_PERSPECTIVE), 
 		mHorzFOV(Radian(Math::PI/4.0f)), 
 		mHorzFOV(Radian(Math::PI/4.0f)), 
@@ -85,18 +60,15 @@ namespace BansheeEngine
         // Init matrices
         // Init matrices
         mViewMatrix = Matrix4::ZERO;
         mViewMatrix = Matrix4::ZERO;
         mProjMatrixRS = Matrix4::ZERO;
         mProjMatrixRS = Matrix4::ZERO;
+
+		target->synchronize();
+		mViewport = cm_shared_ptr<Viewport, PoolAlloc>(target, left, top, width, height);
     }
     }
 
 
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     Camera::~Camera()
     Camera::~Camera()
     {
     {
     }
     }
-	void Camera::initialize(RenderTargetPtr target, float left, float top, float width, float height)
-	{
-		target->synchronize();
-
-		mViewport = cm_shared_ptr<Viewport, PoolAlloc>(target, left, top, width, height);
-	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	void Camera::setHorzFOV(const Radian& fov)
 	void Camera::setHorzFOV(const Radian& fov)
 	{
 	{

+ 1 - 1
BansheeEngine/Source/BsProfilerOverlay.cpp

@@ -261,7 +261,7 @@ namespace BansheeEngine
 		mWidgetSO = SceneObject::create("ProfilerOverlay");
 		mWidgetSO = SceneObject::create("ProfilerOverlay");
 		mWidget = mWidgetSO->addComponent<GUIWidget>(mTarget.get());
 		mWidget = mWidgetSO->addComponent<GUIWidget>(mTarget.get());
 		mWidget->setDepth(127);
 		mWidget->setDepth(127);
-		mWidget->setSkin(BuiltinResources::instance().getSkin());
+		mWidget->setSkin(BuiltinResources::instance().getGUISkin());
 
 
 		mBasicAreaLabels = GUIArea::create(*mWidget, 0, 0);
 		mBasicAreaLabels = GUIArea::create(*mWidget, 0, 0);
 		mPreciseAreaLabels = GUIArea::create(*mWidget, 0, 0);
 		mPreciseAreaLabels = GUIArea::create(*mWidget, 0, 0);

+ 5 - 0
BansheeEngine/Source/BsRenderable.cpp

@@ -28,6 +28,11 @@ namespace BansheeEngine
 		mMatViewProjParam[idx] = material->getParamMat4("matViewProjection");
 		mMatViewProjParam[idx] = material->getParamMat4("matViewProjection");
 	}
 	}
 
 
+	void Renderable::setMaterial(HMaterial material)
+	{
+		setMaterial(0, material);
+	}
+
 	void Renderable::render(RenderQueue& renderQueue, const Matrix4& viewProjMatrix)
 	void Renderable::render(RenderQueue& renderQueue, const Matrix4& viewProjMatrix)
 	{
 	{
 		if(mMesh == nullptr || !mMesh.isLoaded())
 		if(mMesh == nullptr || !mMesh.isLoaded())

+ 2 - 0
CamelotCore/CamelotCore.vcxproj

@@ -404,6 +404,7 @@
     <ClInclude Include="Include\CmVertexDataDescRTTI.h" />
     <ClInclude Include="Include\CmVertexDataDescRTTI.h" />
     <ClInclude Include="Include\CmVertexDeclaration.h" />
     <ClInclude Include="Include\CmVertexDeclaration.h" />
     <ClInclude Include="Include\CmVertexData.h" />
     <ClInclude Include="Include\CmVertexData.h" />
+    <ClInclude Include="Include\CmVideoModeInfo.h" />
     <ClInclude Include="Include\CmViewport.h" />
     <ClInclude Include="Include\CmViewport.h" />
     <ClInclude Include="Include\CmResourceRTTI.h" />
     <ClInclude Include="Include\CmResourceRTTI.h" />
     <ClInclude Include="Include\CmSceneObject.h" />
     <ClInclude Include="Include\CmSceneObject.h" />
@@ -516,6 +517,7 @@
     <ClCompile Include="Source\CmVertexDataDesc.cpp" />
     <ClCompile Include="Source\CmVertexDataDesc.cpp" />
     <ClCompile Include="Source\CmVertexDeclaration.cpp" />
     <ClCompile Include="Source\CmVertexDeclaration.cpp" />
     <ClCompile Include="Source\CmVertexData.cpp" />
     <ClCompile Include="Source\CmVertexData.cpp" />
+    <ClCompile Include="Source\CmVideoModeInfo.cpp" />
     <ClCompile Include="Source\CmViewport.cpp" />
     <ClCompile Include="Source\CmViewport.cpp" />
     <ClCompile Include="Source\CmSceneObject.cpp" />
     <ClCompile Include="Source\CmSceneObject.cpp" />
     <ClCompile Include="Source\CmComponent.cpp" />
     <ClCompile Include="Source\CmComponent.cpp" />

+ 6 - 0
CamelotCore/CamelotCore.vcxproj.filters

@@ -531,6 +531,9 @@
     <ClInclude Include="Include\CmTimerQuery.h">
     <ClInclude Include="Include\CmTimerQuery.h">
       <Filter>Header Files\RenderSystem</Filter>
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmVideoModeInfo.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmApplication.cpp">
     <ClCompile Include="Source\CmApplication.cpp">
@@ -836,5 +839,8 @@
     <ClCompile Include="Source\CmDrawOps.cpp">
     <ClCompile Include="Source\CmDrawOps.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmVideoModeInfo.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 4 - 0
CamelotCore/Include/CmPrerequisites.h

@@ -131,6 +131,9 @@ namespace BansheeEngine
 	class OcclusionQuery;
 	class OcclusionQuery;
 	class FrameAlloc;
 	class FrameAlloc;
 	class FolderMonitor;
 	class FolderMonitor;
+	class VideoMode;
+	class VideoOutputInfo;
+	class VideoModeInfo;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
 	class Importer;
 	class Importer;
@@ -222,6 +225,7 @@ namespace BansheeEngine
 	typedef std::shared_ptr<TimerQuery> TimerQueryPtr;
 	typedef std::shared_ptr<TimerQuery> TimerQueryPtr;
 	typedef std::shared_ptr<OcclusionQuery> OcclusionQueryPtr;
 	typedef std::shared_ptr<OcclusionQuery> OcclusionQueryPtr;
 	typedef std::shared_ptr<ResourceManifest> ResourceManifestPtr;
 	typedef std::shared_ptr<ResourceManifest> ResourceManifestPtr;
+	typedef std::shared_ptr<VideoModeInfo> VideoModeInfoPtr;
 }
 }
 
 
 /************************************************************************/
 /************************************************************************/

+ 8 - 0
CamelotCore/Include/CmRenderSystem.h

@@ -265,6 +265,13 @@ namespace BansheeEngine
 		 */
 		 */
 		void readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceDataPtr& data, AsyncOp& asyncOp);
 		void readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceDataPtr& data, AsyncOp& asyncOp);
 
 
+		/**
+		 * @brief	Returns information about available output devices and their video modes.
+		 *
+		 * @note	Thread safe.
+		 */
+		const VideoModeInfo& getVideoModeInfo() const { return *mVideoModeInfo; }
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								UTILITY METHODS                    		*/
 		/* 								UTILITY METHODS                    		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -386,6 +393,7 @@ namespace BansheeEngine
 		bool mClipPlanesDirty;
 		bool mClipPlanesDirty;
 
 
 		RenderSystemCapabilities* mCurrentCapabilities;
 		RenderSystemCapabilities* mCurrentCapabilities;
+		VideoModeInfoPtr mVideoModeInfo;
 
 
 		// TODO - Only used between initialize and initialize_internal. Handle it better?
 		// TODO - Only used between initialize and initialize_internal. Handle it better?
 		RENDER_WINDOW_DESC mPrimaryWindowDesc;
 		RENDER_WINDOW_DESC mPrimaryWindowDesc;

+ 22 - 3
CamelotCore/Include/CmRenderWindow.h

@@ -68,12 +68,31 @@ namespace BansheeEngine
 		virtual ~RenderWindow();
 		virtual ~RenderWindow();
 
 
 		/** 
 		/** 
-		 * @brief	Toggle between full-screen and windowed mode, and optionally
-		 *			change resolution.
+		 * @brief	Switches the window to fullscreen mode. Child windows cannot go into fullscreen mode.
+		 *
+		 * @param	width		Width of the window back buffer in pixels.
+		 * @param	height		Height of the window back buffer in pixels.
+		 * @param	refreshRate	Refresh rate of the window in Hertz. This is ignored in windowed mode.
+		 * @param	monitorIdx	Index of the monitor to go fullscreen on. This is ignored in windowed mode.
 		 *
 		 *
 		 * @note	Core thread.
 		 * @note	Core thread.
+		 *			If the exact provided mode isn't available, closest one is used instead.
+		 */
+		virtual void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0) { }
+
+		/**
+		* @brief	Switches the window to fullscreen mode. Child windows cannot go into fullscreen mode.
+		*
+		* @param	videoMode	Mode retrieved from VideoModeInfo in RenderSystem.
+		*
+		* @note		Core thread.
+		*/
+		virtual void setFullscreen(const VideoMode& mode) { }
+
+		/**
+		 * @brief	Switches the window to windowed mode.
 		 */
 		 */
-		virtual void setFullscreen(bool fullScreen, UINT32 width, UINT32 height) { }
+		virtual void setWindowed();
 
 
         /**
         /**
          * @brief	Hide or show the window.
          * @brief	Hide or show the window.

+ 105 - 0
CamelotCore/Include/CmVideoModeInfo.h

@@ -0,0 +1,105 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Represents a video mode usable in full-screen windows.
+	 */
+	class CM_EXPORT VideoMode
+	{
+	public:
+		VideoMode(UINT32 width, UINT32 height, VideoOutputInfo* parentOutputInfo);
+		virtual ~VideoMode();
+
+		/**
+		 * @brief	Width of the front/back buffer in pixels.
+		 */
+		UINT32 getWidth() const { return mWidth; }
+
+		/**
+		 * @brief	Height of the front/back buffer in pixels.
+		 */
+		UINT32 getHeight() const { return mHeight; }
+
+		/**
+		 * @brief	Returns the number of available refresh rates for this mode.
+		 */
+		UINT32 getNumRefreshRates() const { return (UINT32)mRefreshRates.size(); }
+
+		/**
+		 * @brief	Returns a refresh rate in Hertz for the specified index.
+		 */
+		virtual float getRefreshRate(UINT32 idx) const { return mRefreshRates.at(idx); }
+
+		/**
+		 * @brief	Returns information about the parent output.
+		 */
+		const VideoOutputInfo& getParentOutput() const { return *mParentOutputInfo; }
+	protected:
+		UINT32 mWidth = 1280;
+		UINT32 mHeight = 720;
+		VideoOutputInfo* mParentOutputInfo = nullptr;
+
+		Vector<float> mRefreshRates;
+	};
+
+	/**
+	 * @brief	Contains information about a video output device, including
+	 *			a list of all available video modes.
+	 */
+	class CM_EXPORT VideoOutputInfo
+	{
+	public:
+		virtual ~VideoOutputInfo();
+
+		/**
+		 * @brief	Name of the output device.
+		 */
+		const String& getName() const { return mName; }
+
+		/**
+		 * @brief	Number of available video modes for this output.
+		 */
+		UINT32 getNumVideoModes() const { return (UINT32)mVideoModes.size(); }
+
+		/**
+		 * @brief	Returns video mode at the specified index.
+		 */
+		const VideoMode& getVideoMode(UINT32 idx) const { return *mVideoModes.at(idx); }
+
+		/**
+		 * @brief	Returns the video mode currently used by the desktop.
+		 */
+		const VideoMode& getDesktopVideoMode() const { return *mDesktopVideoMode; }
+
+	protected:
+		String mName;
+		Vector<VideoMode*> mVideoModes;
+		VideoMode* mDesktopVideoMode = nullptr;
+	};
+
+	/**
+	 * @brief	Contains information about available output devices (e.g. monitor) 
+	 *			and their video modes.
+	 */
+	class CM_EXPORT VideoModeInfo
+	{
+	public:
+		virtual ~VideoModeInfo();
+
+		/**
+		 * @brief	Returns the number of available output devices.
+		 */
+		UINT32 getNumOutputs() const { return (UINT32)mOutputs.size(); }
+
+		/**
+		 * @brief	Returns video mode information about a specific output device.
+		 */
+		const VideoOutputInfo& getOutputInfo(UINT32 idx) const { return *mOutputs[idx]; }
+
+	protected:
+		Vector<VideoOutputInfo*> mOutputs;
+	};
+}

+ 28 - 0
CamelotCore/Source/CmVideoModeInfo.cpp

@@ -0,0 +1,28 @@
+#include "CmVideoModeInfo.h"
+
+namespace BansheeEngine
+{
+	VideoMode::VideoMode(UINT32 width, UINT32 height, VideoOutputInfo* parentOutputInfo)
+		:mWidth(width), mHeight(height), mParentOutputInfo(parentOutputInfo)
+	{
+
+	}
+
+	VideoMode::~VideoMode()
+	{ }
+
+	VideoOutputInfo::~VideoOutputInfo()
+	{ 
+		for (auto& videoMode : mVideoModes)
+			cm_delete(videoMode);
+
+		if (mDesktopVideoMode != nullptr)
+			cm_delete(mDesktopVideoMode);
+	}
+
+	VideoModeInfo::~VideoModeInfo()
+	{ 
+		for (auto& output : mOutputs)
+			cm_delete(output);
+	}
+}

+ 2 - 4
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj

@@ -267,8 +267,7 @@
     <ClInclude Include="Include\CmD3D11SamplerState.h" />
     <ClInclude Include="Include\CmD3D11SamplerState.h" />
     <ClInclude Include="Include\CmD3D11Texture.h" />
     <ClInclude Include="Include\CmD3D11Texture.h" />
     <ClInclude Include="Include\CmD3D11TextureManager.h" />
     <ClInclude Include="Include\CmD3D11TextureManager.h" />
-    <ClInclude Include="Include\CmD3D11VideoMode.h" />
-    <ClInclude Include="Include\CmD3D11VideoModeList.h" />
+    <ClInclude Include="Include\CmD3D11VideoModeInfo.h" />
     <ClInclude Include="Include\CmD3D11InputLayoutManager.h" />
     <ClInclude Include="Include\CmD3D11InputLayoutManager.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
@@ -307,8 +306,7 @@
     <ClCompile Include="Source\CmD3D11SamplerState.cpp" />
     <ClCompile Include="Source\CmD3D11SamplerState.cpp" />
     <ClCompile Include="Source\CmD3D11Texture.cpp" />
     <ClCompile Include="Source\CmD3D11Texture.cpp" />
     <ClCompile Include="Source\CmD3D11TextureManager.cpp" />
     <ClCompile Include="Source\CmD3D11TextureManager.cpp" />
-    <ClCompile Include="Source\CmD3D11VideoMode.cpp" />
-    <ClCompile Include="Source\CmD3D11VideoModeList.cpp" />
+    <ClCompile Include="Source\CmD3D11VideoModeInfo.cpp" />
   </ItemGroup>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">

+ 6 - 12
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters

@@ -30,12 +30,6 @@
     <ClInclude Include="Include\CmD3D11Device.h">
     <ClInclude Include="Include\CmD3D11Device.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\CmD3D11VideoMode.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\CmD3D11VideoModeList.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmD3D11Driver.h">
     <ClInclude Include="Include\CmD3D11Driver.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -132,6 +126,9 @@
     <ClInclude Include="Include\CmD3D11OcclusionQuery.h">
     <ClInclude Include="Include\CmD3D11OcclusionQuery.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D11VideoModeInfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
@@ -143,12 +140,6 @@
     <ClCompile Include="Source\CmD3D11Device.cpp">
     <ClCompile Include="Source\CmD3D11Device.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\CmD3D11VideoMode.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\CmD3D11VideoModeList.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmD3D11Driver.cpp">
     <ClCompile Include="Source\CmD3D11Driver.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
@@ -245,5 +236,8 @@
     <ClCompile Include="Source\CmD3D11OcclusionQuery.cpp">
     <ClCompile Include="Source\CmD3D11OcclusionQuery.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D11VideoModeInfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 3 - 5
CamelotD3D11RenderSystem/Include/CmD3D11Driver.h

@@ -18,19 +18,17 @@ namespace BansheeEngine
 		UINT32 getAdapterNumber() const { return mAdapterNumber; }
 		UINT32 getAdapterNumber() const { return mAdapterNumber; }
 		UINT32 getNumAdapterOutputs() const { return mNumOutputs; }
 		UINT32 getNumAdapterOutputs() const { return mNumOutputs; }
 		const DXGI_ADAPTER_DESC& getAdapterIdentifier() const { return mAdapterIdentifier; }
 		const DXGI_ADAPTER_DESC& getAdapterIdentifier() const { return mAdapterIdentifier; }
-		const DXGI_MODE_DESC& getDesktopMode() const { return mDesktopDisplayMode; }
 		IDXGIAdapter* getDeviceAdapter() { return mDXGIAdapter; }
 		IDXGIAdapter* getDeviceAdapter() { return mDXGIAdapter; }
 		DXGI_OUTPUT_DESC getOutputDesc(UINT32 adapterOutputIdx) const;
 		DXGI_OUTPUT_DESC getOutputDesc(UINT32 adapterOutputIdx) const;
-		const D3D11VideoModeList* getVideoModeList(UINT32 adapterOutputIdx) const;
+
+		VideoModeInfoPtr getVideoModeInfo() const { return mVideoModeInfo; }
 
 
 	private:
 	private:
-		// D3D only allows one device per adapter, so it can safely be stored here as well.
 		UINT32					mAdapterNumber;
 		UINT32					mAdapterNumber;
 		UINT32					mNumOutputs;
 		UINT32					mNumOutputs;
 		DXGI_ADAPTER_DESC		mAdapterIdentifier;
 		DXGI_ADAPTER_DESC		mAdapterIdentifier;
-		DXGI_MODE_DESC			mDesktopDisplayMode;
-		D3D11VideoModeList**	mVideoModeList;
 		IDXGIAdapter*			mDXGIAdapter;
 		IDXGIAdapter*			mDXGIAdapter;
+		VideoModeInfoPtr		mVideoModeInfo;
 
 
 		void init();
 		void init();
 	};
 	};

+ 32 - 28
CamelotD3D11RenderSystem/Include/CmD3D11RenderWindow.h

@@ -31,9 +31,19 @@ namespace BansheeEngine
 		void setActive(bool state);
 		void setActive(bool state);
 
 
 		/**
 		/**
-		 * @copydoc RenderWindow::setFullscreen
-		 */
-		void setFullscreen(bool fullScreen, UINT32 width, UINT32 height);
+		* @copydoc RenderWindow::setFullscreen
+		*/
+		void setFullscreen(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0);
+
+		/**
+		* @copydoc RenderWindow::setFullscreen
+		*/
+		void setFullscreen(const VideoMode& mode);
+
+		/**
+		* @copydoc RenderWindow::setWindowed
+		*/
+		void setWindowed();
 
 
 		/**
 		/**
 		 * @copydoc RenderWindow::copyContentsToMemory
 		 * @copydoc RenderWindow::copyContentsToMemory
@@ -77,7 +87,7 @@ namespace BansheeEngine
 
 
 		void _windowMovedOrResized();
 		void _windowMovedOrResized();
 
 
-		DXGI_SWAP_CHAIN_DESC* _getPresentationParameters(void) { return &mSwapChainDesc; }
+		DXGI_SWAP_CHAIN_DESC* _getPresentationParameters() { return &mSwapChainDesc; }
 		HWND _getWindowHandle() const { return mHWnd; }
 		HWND _getWindowHandle() const { return mHWnd; }
 
 
 	protected:
 	protected:
@@ -92,10 +102,7 @@ namespace BansheeEngine
 		bool checkMultiSampleQuality(UINT32 SampleCount, UINT32 *outQuality, DXGI_FORMAT format);
 		bool checkMultiSampleQuality(UINT32 SampleCount, UINT32 *outQuality, DXGI_FORMAT format);
 
 
 		void createSwapChain();
 		void createSwapChain();
-		void resizeSwapChainBuffers(unsigned width, unsigned height);
-
-		bool getSwitchingFullscreen() const	{ return mSwitchingFullscreen; }
-		void finishSwitchingFullscreen();
+		void resizeSwapChainBuffers(UINT32 width, UINT32 height);
 		
 		
 		/**
 		/**
 		 * @copydoc RenderWindow::initialize_internal().
 		 * @copydoc RenderWindow::initialize_internal().
@@ -107,30 +114,27 @@ namespace BansheeEngine
 		 */
 		 */
 		void destroy_internal();
 		void destroy_internal();
 	protected:
 	protected:
-		D3D11Device&	mDevice;			// D3D11 driver
-		IDXGIFactory*	mDXGIFactory;
-		bool	mIsExternal;
-		bool	mSizing;
-		bool	mClosed;
-
-		// -------------------------------------------------------
-		// DirectX-specific
-		// -------------------------------------------------------
+		D3D11Device& mDevice;
+		IDXGIFactory* mDXGIFactory;
+		bool mIsExternal;
+		bool mSizing;
+		bool mClosed;
+		bool mIsChild;
+
 		DXGI_SAMPLE_DESC mFSAAType;
 		DXGI_SAMPLE_DESC mFSAAType;
-		UINT mDisplayFrequency;
+		UINT32 mRefreshRateNumerator;
+		UINT32 mRefreshRateDenominator;
 		bool mVSync;
 		bool mVSync;
-		unsigned int mVSyncInterval;
+		UINT32 mVSyncInterval;
 
 
-		// Window size depended resources - must be released before swapchain resize and recreated later
-		ID3D11Texture2D*			mBackBuffer;
-		ID3D11RenderTargetView*		mRenderTargetView;
-		TextureViewPtr				mDepthStencilView;
-		TexturePtr					mDepthStencilBuffer;
+		ID3D11Texture2D* mBackBuffer;
+		ID3D11RenderTargetView*	mRenderTargetView;
+		TextureViewPtr mDepthStencilView;
+		TexturePtr mDepthStencilBuffer;
 
 
-		IDXGISwapChain*				mSwapChain;
-		DXGI_SWAP_CHAIN_DESC		mSwapChainDesc;
+		IDXGISwapChain*	mSwapChain;
+		DXGI_SWAP_CHAIN_DESC mSwapChainDesc;
 
 
-		HWND	mHWnd;					// Win32 window handle
-		bool	mSwitchingFullscreen;	// Are we switching from fullscreen to windowed or vice versa
+		HWND mHWnd;
 	};
 	};
 }
 }

+ 0 - 29
CamelotD3D11RenderSystem/Include/CmD3D11VideoMode.h

@@ -1,29 +0,0 @@
-#pragma once
-
-#include "CmD3D11Prerequisites.h"
-
-namespace BansheeEngine
-{
-	class CM_D3D11_EXPORT D3D11VideoMode
-	{
-	public:
-		D3D11VideoMode();
-		D3D11VideoMode(const D3D11VideoMode& ob);
-		D3D11VideoMode(DXGI_OUTPUT_DESC d3ddm, DXGI_MODE_DESC modeDesc);
-		~D3D11VideoMode();
-
-		UINT32 getWidth() const { return mModeDesc.Width; }
-		UINT32 getHeight() const { return mModeDesc.Height; }
-		DXGI_FORMAT getFormat() const { return mModeDesc.Format; }
-		DXGI_RATIONAL getRefreshRate() const { return mModeDesc.RefreshRate; }
-		UINT32 getColorDepth() const;
-		DXGI_OUTPUT_DESC getDisplayMode() const { return mDisplayMode; }
-		DXGI_MODE_DESC getModeDesc() const { return mModeDesc; }
-		String getDescription() const;
-
-	private:
-		DXGI_OUTPUT_DESC	mDisplayMode;
-		DXGI_MODE_DESC		mModeDesc;
-		UINT32				modeNumber;
-	};
-}

+ 60 - 0
CamelotD3D11RenderSystem/Include/CmD3D11VideoModeInfo.h

@@ -0,0 +1,60 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmVideoModeInfo.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @copydoc	VideoMode
+	 */
+	class CM_D3D11_EXPORT D3D11VideoMode : public VideoMode
+	{
+		struct RefreshRate
+		{
+			UINT32 numerator;
+			UINT32 denominator;
+		};
+
+	public:
+		D3D11VideoMode(UINT32 width, UINT32 height, VideoOutputInfo* outputInfo, DXGI_MODE_DESC dxgiMode);
+
+		/**
+		 * @brief	Returns an internal DXGI representation of this video mode.
+		 */
+		const DXGI_MODE_DESC& getDXGIModeDesc() const { return mDXGIMode; }
+
+	private:
+		friend class D3D11VideoOutputInfo;
+
+		Vector<RefreshRate> mD3D11RefreshRates; /**< DXGI stores refresh rates as rational numbers so we need a special storage for them. */
+		DXGI_MODE_DESC mDXGIMode;
+	};
+
+	/**
+	* @copydoc	VideoOutputInfo
+	*/
+	class CM_D3D11_EXPORT D3D11VideoOutputInfo : public VideoOutputInfo
+	{
+	public:
+		D3D11VideoOutputInfo(IDXGIOutput* output);
+		~D3D11VideoOutputInfo();
+
+		/**
+		 * @brief	Returns the internal DXGI object representing an output device.
+		 */
+		IDXGIOutput* getDXGIOutput() const { return mDXGIOutput;  }
+
+	private:
+		IDXGIOutput* mDXGIOutput;
+	};
+
+	/**
+	* @copydoc	VideoModeInfo
+	*/
+	class CM_D3D11_EXPORT D3D11VideoModeInfo : public VideoModeInfo
+	{
+	public:
+		D3D11VideoModeInfo(IDXGIAdapter* dxgiAdapter);
+	};
+}

+ 0 - 25
CamelotD3D11RenderSystem/Include/CmD3D11VideoModeList.h

@@ -1,25 +0,0 @@
-#pragma once
-
-#include "CmD3D11Prerequisites.h"
-#include "CmD3D11VideoMode.h"
-
-namespace BansheeEngine
-{
-	class CM_D3D11_EXPORT D3D11VideoModeList
-	{
-	public:
-		D3D11VideoModeList(D3D11Driver* driver, UINT32 adapterOutput = 0);
-		~D3D11VideoModeList();
-
-		UINT32 count() const;
-
-		const D3D11VideoMode& item(UINT32 idx) const;
-		const D3D11VideoMode& item(const String &name) const;
-
-	private:
-		D3D11Driver* mDriver;
-		Vector<D3D11VideoMode> mModeList;
-
-		void enumerate(UINT32 adapterOutput);
-	};
-}

+ 0 - 26
CamelotD3D11RenderSystem/Source/CmD3D11Driver.cpp

@@ -1,5 +1,4 @@
 #include "CmD3D11Driver.h"
 #include "CmD3D11Driver.h"
-#include "CmD3D11VideoModeList.h"
 #include "CmException.h"
 #include "CmException.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -8,8 +7,6 @@ namespace BansheeEngine
 	{
 	{
 		mAdapterNumber = ob.mAdapterNumber;
 		mAdapterNumber = ob.mAdapterNumber;
 		mAdapterIdentifier = ob.mAdapterIdentifier;
 		mAdapterIdentifier = ob.mAdapterIdentifier;
-		mDesktopDisplayMode = ob.mDesktopDisplayMode;
-		mVideoModeList = nullptr;
 		mDXGIAdapter = ob.mDXGIAdapter;
 		mDXGIAdapter = ob.mDXGIAdapter;
 
 
 		if(mDXGIAdapter)
 		if(mDXGIAdapter)
@@ -21,7 +18,6 @@ namespace BansheeEngine
 	D3D11Driver::D3D11Driver(unsigned int adapterNumber, IDXGIAdapter* pDXGIAdapter)
 	D3D11Driver::D3D11Driver(unsigned int adapterNumber, IDXGIAdapter* pDXGIAdapter)
 	{
 	{
 		mAdapterNumber = adapterNumber;
 		mAdapterNumber = adapterNumber;
-		mVideoModeList = nullptr;
 		mDXGIAdapter = pDXGIAdapter;
 		mDXGIAdapter = pDXGIAdapter;
 
 
 		if(mDXGIAdapter)
 		if(mDXGIAdapter)
@@ -35,15 +31,6 @@ namespace BansheeEngine
 
 
 	D3D11Driver::~D3D11Driver()
 	D3D11Driver::~D3D11Driver()
 	{
 	{
-		for(UINT32 i = 0; i < mNumOutputs; i++)
-		{
-			if(mVideoModeList[i] != nullptr)
-				cm_delete(mVideoModeList[i]);
-		}
-
-		if(mVideoModeList != nullptr)
-			cm_deleteN(mVideoModeList, mNumOutputs);
-
 		SAFE_RELEASE(mDXGIAdapter);
 		SAFE_RELEASE(mDXGIAdapter);
 	}
 	}
 
 
@@ -60,18 +47,12 @@ namespace BansheeEngine
 		}
 		}
 
 
 		mNumOutputs = outputIdx;
 		mNumOutputs = outputIdx;
-
-		mVideoModeList = cm_newN<D3D11VideoModeList*>(mNumOutputs);
-		for(UINT32 i = 0; i < mNumOutputs; i++)
-			mVideoModeList[i] = cm_new<D3D11VideoModeList>(this, i);
 	}
 	}
 
 
 	D3D11Driver& D3D11Driver::operator=(const D3D11Driver& ob)
 	D3D11Driver& D3D11Driver::operator=(const D3D11Driver& ob)
 	{
 	{
 		mAdapterNumber = ob.mAdapterNumber;
 		mAdapterNumber = ob.mAdapterNumber;
 		mAdapterIdentifier = ob.mAdapterIdentifier;
 		mAdapterIdentifier = ob.mAdapterIdentifier;
-		mDesktopDisplayMode = ob.mDesktopDisplayMode;
-		mVideoModeList = nullptr;
 
 
 		if(ob.mDXGIAdapter)
 		if(ob.mDXGIAdapter)
 			ob.mDXGIAdapter->AddRef();
 			ob.mDXGIAdapter->AddRef();
@@ -110,13 +91,6 @@ namespace BansheeEngine
 		return driverDescription;
 		return driverDescription;
 	}
 	}
 
 
-	const D3D11VideoModeList* D3D11Driver::getVideoModeList(UINT32 adapterOutputIdx) const
-	{
-		assert(adapterOutputIdx >= 0 && adapterOutputIdx < mNumOutputs);
-
-		return mVideoModeList[adapterOutputIdx];
-	}
-
 	DXGI_OUTPUT_DESC D3D11Driver::getOutputDesc(UINT32 adapterOutputIdx) const
 	DXGI_OUTPUT_DESC D3D11Driver::getOutputDesc(UINT32 adapterOutputIdx) const
 	{
 	{
 		DXGI_OUTPUT_DESC desc;
 		DXGI_OUTPUT_DESC desc;

+ 4 - 3
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -63,6 +63,7 @@ namespace BansheeEngine
 
 
 		mDriverList = cm_new<D3D11DriverList>(mDXGIFactory);
 		mDriverList = cm_new<D3D11DriverList>(mDXGIFactory);
 		mActiveD3DDriver = mDriverList->item(0); // TODO: Always get first driver, for now
 		mActiveD3DDriver = mDriverList->item(0); // TODO: Always get first driver, for now
+		mVideoModeInfo = mActiveD3DDriver->getVideoModeInfo();
 
 
 		IDXGIAdapter* selectedAdapter = mActiveD3DDriver->getDeviceAdapter();
 		IDXGIAdapter* selectedAdapter = mActiveD3DDriver->getDeviceAdapter();
 
 
@@ -91,9 +92,9 @@ namespace BansheeEngine
 			CM_EXCEPT(RenderingAPIException, "Failed to create Direct3D11 object. D3D11CreateDeviceN returned this error code: " + toString(hr));
 			CM_EXCEPT(RenderingAPIException, "Failed to create Direct3D11 object. D3D11CreateDeviceN returned this error code: " + toString(hr));
 
 
 		mDevice = cm_new<D3D11Device>(device);
 		mDevice = cm_new<D3D11Device>(device);
-
-		LARGE_INTEGER driverVersion;
-		if(SUCCEEDED(selectedAdapter->CheckInterfaceSupport(IID_ID3D10Device /* intentionally D3D10, not D3D11 */, &driverVersion)))
+		
+		LARGE_INTEGER driverVersion; 
+		if(SUCCEEDED(selectedAdapter->CheckInterfaceSupport(IID_ID3D11Device, &driverVersion)))
 		{
 		{
 			mDriverVersion.major = HIWORD(driverVersion.HighPart);
 			mDriverVersion.major = HIWORD(driverVersion.HighPart);
 			mDriverVersion.minor = LOWORD(driverVersion.HighPart);
 			mDriverVersion.minor = LOWORD(driverVersion.HighPart);

+ 77 - 89
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -8,6 +8,7 @@
 #include "CmTextureManager.h"
 #include "CmTextureManager.h"
 #include "CmD3D11DriverList.h"
 #include "CmD3D11DriverList.h"
 #include "CmD3D11Driver.h"
 #include "CmD3D11Driver.h"
+#include "CmD3D11VideoModeInfo.h"
 #include "CmInput.h"
 #include "CmInput.h"
 #include "CmException.h"
 #include "CmException.h"
 
 
@@ -20,13 +21,14 @@ namespace BansheeEngine
 		, mIsExternal(false)
 		, mIsExternal(false)
 		, mSizing(false)
 		, mSizing(false)
 		, mClosed(false)
 		, mClosed(false)
-		, mSwitchingFullscreen(false)
-		, mDisplayFrequency(0)
+		, mRefreshRateNumerator(0)
+		, mRefreshRateDenominator(0)
 		, mRenderTargetView(nullptr)
 		, mRenderTargetView(nullptr)
 		, mBackBuffer(nullptr)
 		, mBackBuffer(nullptr)
 		, mSwapChain(nullptr)
 		, mSwapChain(nullptr)
 		, mHWnd(0)
 		, mHWnd(0)
 		, mDepthStencilView(nullptr)
 		, mDepthStencilView(nullptr)
+		, mIsChild(false)
 	{
 	{
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 	}
 	}
@@ -64,7 +66,8 @@ namespace BansheeEngine
 			hMonitor = (HMONITOR)parseInt(opt->second);		
 			hMonitor = (HMONITOR)parseInt(opt->second);		
 
 
 		mName = mDesc.title;
 		mName = mDesc.title;
-		mIsFullScreen = mDesc.fullscreen;
+		mIsChild = parentHWnd != 0;
+		mIsFullScreen = mDesc.fullscreen && !mIsChild;
 		mColorDepth = mDesc.colorDepth;
 		mColorDepth = mDesc.colorDepth;
 		mWidth = mHeight = mLeft = mTop = 0;
 		mWidth = mHeight = mLeft = mTop = 0;
 
 
@@ -363,66 +366,82 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11RenderWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height)
+	void D3D11RenderWindow::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight)
-		{
-			if (fullScreen != mIsFullScreen)
-				mSwitchingFullscreen = true;
+		if (mIsChild)
+			return;
 
 
-			DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
+		const D3D11VideoModeInfo& videoModeInfo = static_cast<const D3D11VideoModeInfo&>(RenderSystem::instance().getVideoModeInfo());
+		UINT32 numOutputs = videoModeInfo.getNumOutputs();
+		if (numOutputs == 0)
+			return;
 
 
-			bool oldFullscreen = mIsFullScreen;
-			mIsFullScreen = fullScreen;
+		UINT32 actualMonitorIdx = std::min(monitorIdx, numOutputs - 1);
+		const D3D11VideoOutputInfo& outputInfo = static_cast<const D3D11VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
 
 
-			if (fullScreen)
-			{
-				dwStyle |= WS_POPUP;
-				mTop = mLeft = 0;
-				mWidth = width;
-				mHeight = height;
-				// need different ordering here
+		DXGI_MODE_DESC modeDesc;
+		ZeroMemory(&modeDesc, sizeof(modeDesc));
 
 
-				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
-			}
+		modeDesc.Width = width;
+		modeDesc.Height = height;
+		modeDesc.RefreshRate.Numerator = Math::roundToInt(refreshRate);
+		modeDesc.RefreshRate.Denominator = 1;
+		modeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+		modeDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+		modeDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
 
 
-			mSwapChainDesc.Windowed = !fullScreen;
-			mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
-			mSwapChainDesc.BufferDesc.RefreshRate.Denominator=0;
-			mSwapChainDesc.BufferDesc.Height = height;
-			mSwapChainDesc.BufferDesc.Width = width;
-		}
-	} 
+		DXGI_MODE_DESC nearestMode;
+		ZeroMemory(&nearestMode, sizeof(nearestMode));
+
+		outputInfo.getDXGIOutput()->FindClosestMatchingMode(&modeDesc, &nearestMode, nullptr);
+
+		mIsFullScreen = true;
+
+		mSwapChain->ResizeTarget(&nearestMode);
+		mSwapChain->SetFullscreenState(true, outputInfo.getDXGIOutput()); 
+	}
+
+	void D3D11RenderWindow::setFullscreen(const VideoMode& mode)
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		if (mIsChild)
+			return;
+
+		const D3D11VideoMode& videoMode = static_cast<const D3D11VideoMode&>(mode);
+		const D3D11VideoOutputInfo& outputInfo = static_cast<const D3D11VideoOutputInfo&>(mode.getParentOutput());
+
+		mIsFullScreen = true;
+
+		mSwapChain->ResizeTarget(&videoMode.getDXGIModeDesc());
+		mSwapChain->SetFullscreenState(true, outputInfo.getDXGIOutput());
+	}
+
+	void D3D11RenderWindow::setWindowed()
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		mIsFullScreen = false;
+		mSwapChainDesc.Windowed = false;
+		mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+		mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
+		mSwapChainDesc.BufferDesc.Width = mWidth;
+		mSwapChainDesc.BufferDesc.Height = mHeight;
+
+		DXGI_MODE_DESC modeDesc;
+		ZeroMemory(&modeDesc, sizeof(modeDesc));
+
+		modeDesc.Width = mWidth;
+		modeDesc.Height = mHeight;
+		modeDesc.RefreshRate.Numerator = 0;
+		modeDesc.RefreshRate.Denominator = 0;
+		modeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+
+		mSwapChain->ResizeTarget(&modeDesc);
+		mSwapChain->SetFullscreenState(false, nullptr);
+	}
 
 
 	void D3D11RenderWindow::getCustomAttribute( const String& name, void* pData ) const
 	void D3D11RenderWindow::getCustomAttribute( const String& name, void* pData ) const
 	{
 	{
@@ -593,9 +612,8 @@ namespace BansheeEngine
 		mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
 		mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
 		mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ;
 		mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ;
 
 
-		// triple buffer if VSync is on
 		mSwapChainDesc.BufferUsage			= DXGI_USAGE_RENDER_TARGET_OUTPUT;
 		mSwapChainDesc.BufferUsage			= DXGI_USAGE_RENDER_TARGET_OUTPUT;
-		mSwapChainDesc.BufferCount			= mVSync ? 2 : 1;
+		mSwapChainDesc.BufferCount			= 1;
 		mSwapChainDesc.SwapEffect			= DXGI_SWAP_EFFECT_DISCARD ;
 		mSwapChainDesc.SwapEffect			= DXGI_SWAP_EFFECT_DISCARD ;
 
 
 		mSwapChainDesc.OutputWindow 		= mHWnd;
 		mSwapChainDesc.OutputWindow 		= mHWnd;
@@ -629,7 +647,7 @@ namespace BansheeEngine
 		// obtain back buffer
 		// obtain back buffer
 		SAFE_RELEASE(mBackBuffer);
 		SAFE_RELEASE(mBackBuffer);
 
 
-		HRESULT hr = mSwapChain->GetBuffer(0,  __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer);
+		HRESULT hr = mSwapChain->GetBuffer(0,  __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBuffer);
 		if( FAILED(hr) )
 		if( FAILED(hr) )
 			CM_EXCEPT(RenderingAPIException, "Unable to Get Back Buffer for swap chain");
 			CM_EXCEPT(RenderingAPIException, "Unable to Get Back Buffer for swap chain");
 
 
@@ -675,7 +693,7 @@ namespace BansheeEngine
 		mDepthStencilBuffer = nullptr;
 		mDepthStencilBuffer = nullptr;
 	}
 	}
 
 
-	void D3D11RenderWindow::resizeSwapChainBuffers(unsigned width, unsigned height)
+	void D3D11RenderWindow::resizeSwapChainBuffers(UINT32 width, UINT32 height)
 	{
 	{
 		destroySizeDependedD3DResources();
 		destroySizeDependedD3DResources();
 
 
@@ -711,36 +729,6 @@ namespace BansheeEngine
 		return pDXGIDevice;
 		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(UINT32 SampleCount, UINT32 *outQuality, DXGI_FORMAT format)
 	bool D3D11RenderWindow::checkMultiSampleQuality(UINT32 SampleCount, UINT32 *outQuality, DXGI_FORMAT format)
 	{
 	{
 		if (SUCCEEDED(mDevice.getD3D11Device()->CheckMultisampleQualityLevels(format, SampleCount, outQuality)))
 		if (SUCCEEDED(mDevice.getD3D11Device()->CheckMultisampleQualityLevels(format, SampleCount, outQuality)))

+ 0 - 43
CamelotD3D11RenderSystem/Source/CmD3D11VideoMode.cpp

@@ -1,43 +0,0 @@
-#include "CmD3D11VideoMode.h"
-
-namespace BansheeEngine
-{
-	D3D11VideoMode::D3D11VideoMode(DXGI_OUTPUT_DESC d3ddm, DXGI_MODE_DESC modeDesc)
-		:mDisplayMode(d3ddm), mModeDesc(modeDesc)
-	{ }
-
-	D3D11VideoMode::D3D11VideoMode(const D3D11VideoMode &ob)
-		:mDisplayMode(ob.mDisplayMode), mModeDesc(ob.mModeDesc)
-	{ }
-
-	D3D11VideoMode::D3D11VideoMode()
-	{
-		ZeroMemory(&mDisplayMode, sizeof(DXGI_OUTPUT_DESC));
-		ZeroMemory(&mModeDesc, sizeof(DXGI_MODE_DESC));
-	}
-
-	D3D11VideoMode::~D3D11VideoMode()
-	{ }
-
-	String D3D11VideoMode::getDescription() const
-	{
-		return toString(mModeDesc.Width) + " x " + toString(mModeDesc.Height) + " @ " + toString(getColorDepth()) + "-bit color";
-	}
-
-	UINT32 D3D11VideoMode::getColorDepth() const
-	{
-		UINT32 colourDepth = 16;
-		if( mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_TYPELESS ||
-			mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT ||
-			mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_UINT ||
-			mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_SINT ||
-			mModeDesc.Format == DXGI_FORMAT_R32G32B32_TYPELESS ||
-			mModeDesc.Format == DXGI_FORMAT_R32G32B32_FLOAT ||
-			mModeDesc.Format == DXGI_FORMAT_R32G32B32_UINT ||
-			mModeDesc.Format == DXGI_FORMAT_R32G32B32_SINT 
-			)
-			colourDepth = 32;
-
-		return colourDepth;
-	}
-}

+ 135 - 0
CamelotD3D11RenderSystem/Source/CmD3D11VideoModeInfo.cpp

@@ -0,0 +1,135 @@
+#include "CmD3D11VideoModeInfo.h"
+#include "CmException.h"
+
+namespace BansheeEngine
+{
+	D3D11VideoModeInfo::D3D11VideoModeInfo(IDXGIAdapter* dxgiAdapter)
+	{
+		UINT32 outputIdx = 0;
+		IDXGIOutput* output = nullptr;
+		while (dxgiAdapter->EnumOutputs(outputIdx, &output) != DXGI_ERROR_NOT_FOUND)
+		{
+			outputIdx++;
+			mOutputs.push_back(cm_new<D3D11VideoOutputInfo>(output));
+		}
+	}
+
+	D3D11VideoOutputInfo::D3D11VideoOutputInfo(IDXGIOutput* output)
+		:mDXGIOutput(output)
+	{
+		DXGI_OUTPUT_DESC outputDesc;
+		output->GetDesc(&outputDesc);
+		mName = toString(WString(outputDesc.DeviceName));
+
+		UINT32 numModes = 0;
+
+		HRESULT hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, 0);
+		if (FAILED(hr))
+		{
+			SAFE_RELEASE(output);
+			CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes.");
+		}
+
+		DXGI_MODE_DESC* modeDesc = cm_newN<DXGI_MODE_DESC>(numModes);
+
+		hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, modeDesc);
+		if (FAILED(hr))
+		{
+			cm_deleteN(modeDesc, numModes);
+
+			SAFE_RELEASE(output);
+			CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes.");
+		}
+
+		for (UINT32 i = 0; i < numModes; i++)
+		{
+			DXGI_MODE_DESC displayMode = modeDesc[i];
+
+			bool foundVideoMode = false;
+			for (auto videoMode : mVideoModes)
+			{
+				D3D11VideoMode* d3d11videoMode = static_cast<D3D11VideoMode*>(videoMode);
+
+				if (d3d11videoMode->mWidth == displayMode.Width && d3d11videoMode->mHeight == displayMode.Height)
+				{
+					bool foundRefreshRate = false;
+					for (auto refreshRate : d3d11videoMode->mD3D11RefreshRates)
+					{
+						if (refreshRate.numerator != displayMode.RefreshRate.Numerator ||
+							refreshRate.denominator != displayMode.RefreshRate.Denominator)
+						{
+							foundRefreshRate = true;
+							break;
+						}
+					}
+
+					if (!foundRefreshRate)
+					{
+						D3D11VideoMode::RefreshRate refreshRate;
+						refreshRate.numerator = displayMode.RefreshRate.Numerator;
+						refreshRate.denominator = displayMode.RefreshRate.Denominator;
+
+						d3d11videoMode->mD3D11RefreshRates.push_back(refreshRate);
+						d3d11videoMode->mRefreshRates.push_back(refreshRate.numerator / (float)refreshRate.denominator);
+					}
+
+					foundVideoMode = true;
+					break;
+				}
+			}
+
+			if (!foundVideoMode)
+			{
+				D3D11VideoMode* videoMode = cm_new<D3D11VideoMode>(displayMode.Width, displayMode.Height, this, displayMode);
+
+				D3D11VideoMode::RefreshRate refreshRate;
+				refreshRate.numerator = displayMode.RefreshRate.Numerator;
+				refreshRate.denominator = displayMode.RefreshRate.Denominator;
+
+				videoMode->mD3D11RefreshRates.push_back(refreshRate);
+				videoMode->mRefreshRates.push_back(refreshRate.numerator / (float)refreshRate.denominator);
+
+				mVideoModes.push_back(videoMode);
+			}
+		}
+
+		cm_deleteN(modeDesc, numModes);
+
+		// Get desktop display mode
+		HMONITOR hMonitor = outputDesc.Monitor;
+		MONITORINFOEX monitorInfo;
+		monitorInfo.cbSize = sizeof(MONITORINFOEX);
+		GetMonitorInfo(hMonitor, &monitorInfo);
+
+		DEVMODE devMode;
+		devMode.dmSize = sizeof(DEVMODE);
+		devMode.dmDriverExtra = 0;
+		EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
+
+		DXGI_MODE_DESC currentMode;
+		currentMode.Width = devMode.dmPelsWidth;
+		currentMode.Height = devMode.dmPelsHeight;
+		bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency;
+		currentMode.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency;
+		currentMode.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1;
+		currentMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+		currentMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+		currentMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+
+		DXGI_MODE_DESC nearestMode;
+		ZeroMemory(&nearestMode, sizeof(nearestMode));
+
+		output->FindClosestMatchingMode(&currentMode, &nearestMode, nullptr);
+
+		mDesktopVideoMode = cm_new<D3D11VideoMode>(nearestMode.Width, nearestMode.Height, this, nearestMode);
+	}
+
+	D3D11VideoOutputInfo::~D3D11VideoOutputInfo()
+	{
+		SAFE_RELEASE(mDXGIOutput);
+	}
+
+	D3D11VideoMode::D3D11VideoMode(UINT32 width, UINT32 height, VideoOutputInfo* outputInfo, DXGI_MODE_DESC dxgiMode)
+		:VideoMode(width, height, outputInfo), mDXGIMode(dxgiMode)
+	{ }
+}

+ 0 - 112
CamelotD3D11RenderSystem/Source/CmD3D11VideoModeList.cpp

@@ -1,112 +0,0 @@
-#include "CmD3D11VideoModeList.h"
-#include "CmException.h"
-#include "CmD3D11Driver.h"
-
-namespace BansheeEngine
-{
-	D3D11VideoModeList::D3D11VideoModeList(D3D11Driver* driver, UINT32 adapterOutput)
-	{
-		if(driver == nullptr)
-			CM_EXCEPT(InvalidParametersException, "driver parameter is NULL");
-
-		mDriver = driver;
-		enumerate(adapterOutput);
-	}
-
-	D3D11VideoModeList::~D3D11VideoModeList()
-	{
-		mDriver = NULL;
-		mModeList.clear();
-	}
-
-	void D3D11VideoModeList::enumerate(UINT32 adapterOutput)
-	{
-		UINT adapter = mDriver->getAdapterNumber();
-		HRESULT hr;
-
-		IDXGIOutput* output;
-		hr = mDriver->getDeviceAdapter()->EnumOutputs(adapterOutput, &output);
-		if(hr == DXGI_ERROR_NOT_FOUND)
-			CM_EXCEPT(InvalidParametersException, "Adapter output " + toString(adapterOutput) + " not found!");
-
-		if(FAILED(hr))
-			CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
-
-		DXGI_OUTPUT_DESC outputDesc;
-		output->GetDesc(&outputDesc);
-
-		UINT32 numModes = 0;
-
-		hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, 0);
-		if(FAILED(hr))
-		{
-			SAFE_RELEASE(output);
-			CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
-		}
-
-		DXGI_MODE_DESC* modeDesc = cm_newN<DXGI_MODE_DESC, ScratchAlloc>(numModes);
-
-		hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, modeDesc);
-		if(FAILED(hr))
-		{
-			cm_deleteN<ScratchAlloc>(modeDesc, numModes);
-
-			SAFE_RELEASE(output);
-			CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
-		}
-
-		SAFE_RELEASE(output);
-
-		for(UINT32 i = 0; i < numModes; i++)
-		{
-			DXGI_MODE_DESC displayMode = modeDesc[i];
-
-			// Filter out low-resolutions
-			if(displayMode.Width < 640 || displayMode.Height < 400)
-				continue;
-
-			// Check to see if it is already in the list (to filter out refresh rates)
-			bool found = false;
-			for(auto it = mModeList.begin(); it != mModeList.end(); it++)
-			{
-				DXGI_MODE_DESC existingMode = it->getModeDesc();
-				if(	existingMode.Width == displayMode.Width && 
-					existingMode.Height == displayMode.Height &&
-					existingMode.Format == displayMode.Format &&
-					existingMode.RefreshRate.Numerator == displayMode.RefreshRate.Numerator &&
-					existingMode.RefreshRate.Denominator == displayMode.RefreshRate.Denominator
-					)
-				{
-					found = true;
-					break;
-				}
-			}
-
-			if(!found)
-				mModeList.push_back(D3D11VideoMode(outputDesc, displayMode));
-		}
-
-		cm_deleteN<ScratchAlloc>(modeDesc, numModes);
-	}
-
-	UINT32 D3D11VideoModeList::count() const
-	{
-		return (UINT32)mModeList.size();
-	}
-
-	const D3D11VideoMode& D3D11VideoModeList::item(UINT32 idx) const
-	{
-		return mModeList.at(idx);
-	}
-
-	const D3D11VideoMode& D3D11VideoModeList::item(const String &name) const
-	{
-		for (auto iter = mModeList.begin(); iter != mModeList.end(); ++iter)
-		{
-			if (iter->getDescription() == name)
-				return (*iter);
-		}
-
-		CM_EXCEPT(InvalidParametersException, "Cannot find video mode with the specified name.");
-	}
-}

+ 1 - 1
ExampleProject/ExampleProject.vcxproj

@@ -144,7 +144,7 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
-    <ClCompile Include="Main\Source.cpp" />
+    <ClCompile Include="Main\Main.cpp" />
   </ItemGroup>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">

+ 1 - 1
ExampleProject/ExampleProject.vcxproj.filters

@@ -15,7 +15,7 @@
     </Filter>
     </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <ClCompile Include="Main\Source.cpp">
+    <ClCompile Include="Main\Main.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
   </ItemGroup>
   </ItemGroup>

+ 192 - 0
ExampleProject/Main/Main.cpp

@@ -0,0 +1,192 @@
+#include "stdafx.h"
+#include <windows.h>
+
+#include "CmApplication.h"
+#include "CmImporter.h"
+#include "CmGpuProgramImportOptions.h"
+#include "CmMaterial.h"
+#include "CmShader.h"
+#include "CmTechnique.h"
+#include "CmPass.h"
+#include "CmCoreThreadAccessor.h"
+#include "BsApplication.h"
+#include "BsVirtualInput.h"
+#include "BsCamera.h"
+#include "BsRenderable.h"
+#include "BsGUIWidget.h"
+#include "BsGUIArea.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
+#include "BsGUILabel.h"
+#include "BsGUIButton.h"
+#include "BsGUIListBox.h"
+#include "BsBuiltinResources.h"
+#include "CmRTTIType.h"
+#include "CmHString.h"
+#include "CmRenderWindow.h"
+#include "CmSceneObject.h"
+
+using namespace BansheeEngine;
+
+Path exampleModelPath = "..\\..\\..\\..\\Data\\Examples\\Pyromancer.fbx";
+Path exampleTexturePath = "..\\..\\..\\..\\Data\\Examples\\Pyromancer.psd";
+Path exampleFragmentShaderPath = "..\\..\\..\\..\\Data\\Examples\\example_fs.gpuprog";
+Path exampleVertexShaderPath = "..\\..\\..\\..\\Data\\Examples\\example_vs.gpuprog";
+
+GUIButton* toggleFullscreenButton = nullptr;
+UINT32 resolutionWidth = 1280;
+UINT32 resolutionHeight = 720;
+
+HMesh exampleModel;
+HTexture exampleTexture;
+HGpuProgram exampleFragmentGPUProg;
+HGpuProgram exampleVertexGPUProg;
+
+HCamera sceneCamera;
+
+void setUpExample();
+
+int CALLBACK WinMain(
+	_In_  HINSTANCE hInstance,
+	_In_  HINSTANCE hPrevInstance,
+	_In_  LPSTR lpCmdLine,
+	_In_  int nCmdShow
+	)
+{
+	RENDER_WINDOW_DESC renderWindowDesc;
+	renderWindowDesc.width = resolutionWidth;
+	renderWindowDesc.height = resolutionHeight;
+	renderWindowDesc.title = "Banshee Example App";
+	renderWindowDesc.fullscreen = false;
+
+	gBansheeApp().startUp(renderWindowDesc, "CamelotD3D11RenderSystem", "BansheeForwardRenderer"); // TODO - Use enums instead of names. BansheeApp is a high level system that doesn't need to be as customizable.
+	setUpExample();
+	
+	gBansheeApp().runMainLoop();
+	gBansheeApp().shutDown();
+
+	return 0;
+}
+
+void toggleFullscreen()
+{
+	RenderWindowPtr window = gApplication().getPrimaryWindow();
+
+
+
+	//window->setFullscreen(!window->isFullScreen(), resolutionWidth, resolutionHeight);
+}
+
+void setUpExample()
+{
+	// Import assets
+	exampleModel = static_resource_cast<Mesh>(Importer::instance().import(exampleModelPath));
+	exampleTexture = static_resource_cast<Texture>(Importer::instance().import(exampleTexturePath));
+
+	ImportOptionsPtr gpuProgImportOptions = Importer::instance().createImportOptions(exampleFragmentShaderPath);
+	if(rtti_is_of_type<GpuProgramImportOptions>(gpuProgImportOptions))
+	{
+		GpuProgramImportOptions* importOptions = static_cast<GpuProgramImportOptions*>(gpuProgImportOptions.get());
+
+		importOptions->setEntryPoint("ps_main");
+		importOptions->setLanguage("hlsl");
+		importOptions->setProfile(GPP_PS_4_0);
+		importOptions->setType(GPT_FRAGMENT_PROGRAM);
+	}
+
+	exampleFragmentGPUProg = static_resource_cast<GpuProgram>(Importer::instance().import(exampleFragmentShaderPath, gpuProgImportOptions));
+
+	gpuProgImportOptions = Importer::instance().createImportOptions(exampleVertexShaderPath);
+	if(rtti_is_of_type<GpuProgramImportOptions>(gpuProgImportOptions))
+	{
+		GpuProgramImportOptions* importOptions = static_cast<GpuProgramImportOptions*>(gpuProgImportOptions.get());
+
+		importOptions->setEntryPoint("vs_main");
+		importOptions->setLanguage("hlsl");
+		importOptions->setProfile(GPP_VS_4_0);
+		importOptions->setType(GPT_VERTEX_PROGRAM);
+	}
+
+	exampleVertexGPUProg = static_resource_cast<GpuProgram>(Importer::instance().import(exampleVertexShaderPath, gpuProgImportOptions));
+
+	// TODO - Optionally make the entire import step one-time. After import save resources and the created scene. Then on next load just load them directly from disk.
+
+	// Create material
+	ShaderPtr exampleShader = Shader::create("ExampleShader");
+
+	exampleShader->addParameter("matViewProjection", "matViewProjection", GPDT_MATRIX_4X4);
+	exampleShader->addParameter("samp", "samp", GPOT_SAMPLER2D);
+	exampleShader->addParameter("tex", "tex", GPOT_TEXTURE2D);
+
+	TechniquePtr technique = exampleShader->addTechnique("D3D11RenderSystem", "ForwardRenderer"); // TODO - This render system and forward renderer names should at least match the above names used for initialization
+	PassPtr pass = technique->addPass();
+	pass->setVertexProgram(exampleVertexGPUProg);
+	pass->setFragmentProgram(exampleFragmentGPUProg);
+
+	HMaterial exampleMaterial = Material::create(exampleShader);
+	exampleMaterial->setTexture("tex", exampleTexture);
+
+	// Set up the object to render
+	HSceneObject pyromancerSO = SceneObject::create("Pyromancer");
+	HRenderable renderable = pyromancerSO->addComponent<Renderable>();
+	renderable->setMesh(exampleModel);
+	renderable->setMaterial(exampleMaterial);
+
+	// Set up scene camera
+	HSceneObject sceneCameraGO = SceneObject::create("SceneCamera");
+
+	RenderWindowPtr window = gApplication().getPrimaryWindow(); // TODO - Up until now I'm using gBansheeApp and now I'm using gApplication. It's confusing. BansheeApp should derive from application
+	sceneCamera = sceneCameraGO->addComponent<Camera>(window, 0.0f, 0.0f, 1.0f, 1.0f);
+
+	sceneCamera->setPriority(1);
+	sceneCameraGO->setPosition(Vector3(0,50,1240));
+	sceneCameraGO->lookAt(Vector3(0,50,-300));
+	sceneCamera->setNearClipDistance(5);
+	sceneCamera->setAspectRatio(resolutionWidth / (float)resolutionHeight); // TODO - This needs to get called whenever resolution changes
+
+	// Register input configuration
+	auto inputConfig = VirtualInput::instance().getConfiguration();
+
+	inputConfig->registerButton("Forward", BC_W);
+	inputConfig->registerButton("Left", BC_A);
+	inputConfig->registerButton("Right", BC_D);
+	inputConfig->registerButton("Back", BC_S);
+
+	inputConfig->registerButton("SimThreadProfilerOverlay", BC_F1);
+	inputConfig->registerButton("CoreThreadProfilerOverlay", BC_F2);
+	inputConfig->registerButton("GPUProfilerOverlay", BC_F3);
+
+	// TODO - Add vertical/horizontal axes here
+
+	HSceneObject exampleSO = SceneObject::create("Example");
+
+	HCamera guiCamera = exampleSO->addComponent<Camera>(window);
+	guiCamera->setNearClipDistance(5);
+	guiCamera->setAspectRatio(1.0f);
+	guiCamera->setIgnoreSceneRenderables(true);
+
+	HGUIWidget gui = exampleSO->addComponent<GUIWidget>();
+	gui->setDepth(128);
+	gui->setSkin(BuiltinResources::instance().getGUISkin());
+
+	// Profiler overlay GUI
+	GUIArea* topArea = GUIArea::createStretchedXY(*gui, 0, 0, 0, 0);
+	GUILayout& topLayout = topArea->getLayout().addLayoutY();
+
+	topLayout.addElement(GUILabel::create(HString(L"Press F1 to toggle Sim thread profiler overlay")));
+	topLayout.addElement(GUILabel::create(HString(L"Press F2 to toggle Core thread profiler overlay")));
+	topLayout.addElement(GUILabel::create(HString(L"Press F3 to toggle GPU profiler overlay")));
+	topLayout.addFlexibleSpace();
+
+	// Resolution/Camera options GUI
+	GUIArea* rightArea = GUIArea::createStretchedXY(*gui, 0, 0, 0, 0);
+	rightArea->getLayout().addFlexibleSpace();
+	GUILayout& rightLayout = rightArea->getLayout().addLayoutY();
+
+	rightLayout.addSpace(50);
+	toggleFullscreenButton = GUIButton::create(HString(L"Toggle fullscreen"));
+	toggleFullscreenButton->onClick.connect(&toggleFullscreen);
+	rightLayout.addElement(toggleFullscreenButton);
+
+	// TODO - add ExampleGUI component
+}

+ 0 - 41
ExampleProject/Main/Source.cpp

@@ -1,41 +0,0 @@
-#include "stdafx.h"
-#include <windows.h>
-
-#include "BsApplication.h"
-#include "CmRenderWindow.h"
-#include "CmSceneObject.h"
-
-using namespace BansheeEngine;
-
-void setUpExample();
-
-int CALLBACK WinMain(
-	_In_  HINSTANCE hInstance,
-	_In_  HINSTANCE hPrevInstance,
-	_In_  LPSTR lpCmdLine,
-	_In_  int nCmdShow
-	)
-{
-	RENDER_WINDOW_DESC renderWindowDesc;
-	renderWindowDesc.width = 1280;
-	renderWindowDesc.height = 720;
-	renderWindowDesc.title = "Banshee Example App";
-	renderWindowDesc.fullscreen = false;
-
-	gBansheeApp().startUp(renderWindowDesc, "CamelotD3D11RenderSystem", "BansheeForwardRenderer"); // TODO - Use enums instead of names. BansheeApp is a high level system that doesn't need to be as customizable.
-	setUpExample();
-	
-	gBansheeApp().runMainLoop();
-	gBansheeApp().shutDown();
-
-	return 0;
-}
-
-void setUpExample()
-{
-	HSceneObject exampleSO = SceneObject::create("Example");
-
-
-
-	// TODO - add ExampleGUI component
-}

+ 21 - 1
Polish.txt

@@ -5,4 +5,24 @@ There's still a crash regarding an uninitialized mCachedPtr on a C# class when s
 Finish GPUProfiler:
 Finish GPUProfiler:
  - Actually implement sampling and report generation
  - Actually implement sampling and report generation
  - Add timer and occlusion queries
  - Add timer and occlusion queries
- - Resource writes/reads/creation/destruction is not currently increased in RenderStats
+ - Resource writes/reads/creation/destruction is not currently increased in RenderStats
+
+ ---------------------------
+
+ Fullscreen stuff:
+
+ EnumDisplayMonitors - Get all available monitors
+ - http://msdn.microsoft.com/en-us/library/windows/desktop/dd162617(v=vs.85).aspx
+GetMonitorInfo - Get display name for monitor
+ - http://msdn.microsoft.com/en-us/library/windows/desktop/dd144901(v=vs.85).aspx
+ChangeDisplaySettingEx - For actually changing resolution and refresh rate
+ - http://msdn.microsoft.com/en-us/library/windows/desktop/dd183413(v=vs.85).aspx
+EnumDisplaySettings  - To query all available resolutions and refresh rates
+ - http://msdn.microsoft.com/en-us/library/windows/desktop/dd162611(v=vs.85).aspx
+
+RenderSystem
+ - Allow for querying multiple monitors
+ - Allow querying for all possible resolutions and refresh rates (for each monitor specifically)
+ - Allow querying for desktop resolution and refresh rate
+
+in window setFullscreen add a refresh rate setting, and a monitor index