Просмотр исходного кода

Fixed issue with HString parameter placement
Fixed issue with viewport resizing

Marko Pintera 11 лет назад
Родитель
Сommit
90e94fb9b2

+ 2 - 0
BansheeCore/Include/BsVideoModeInfo.h

@@ -26,6 +26,8 @@ namespace BansheeEngine
 		VideoMode(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 outputIdx = 0);
 		VideoMode(UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 outputIdx = 0);
 		virtual ~VideoMode();
 		virtual ~VideoMode();
 
 
+		bool operator== (const VideoMode& other) const;
+
 		/**
 		/**
 		 * @brief	Width of the front/back buffer in pixels.
 		 * @brief	Width of the front/back buffer in pixels.
 		 */
 		 */

+ 5 - 9
BansheeCore/Include/BsViewport.h

@@ -54,22 +54,22 @@ namespace BansheeEngine
         /**
         /**
          * @brief	Gets the actual x coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
          * @brief	Gets the actual x coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
          */
          */
-        INT32 getX() const { return mArea.x; }
+		INT32 getX() const;
 
 
         /**
         /**
          * @brief	Gets the actual y coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
          * @brief	Gets the actual y coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
          */
          */
-        INT32 getY() const { return mArea.y; }
+		INT32 getY() const;
 
 
 		/**
 		/**
          * @brief	Gets the actual width coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
          * @brief	Gets the actual width coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
          */
          */
-        INT32 getWidth() const { return mArea.width; }
+		INT32 getWidth() const;
 
 
 		/**
 		/**
          * @brief	Gets the actual height coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
          * @brief	Gets the actual height coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
          */
          */
-        INT32 getHeight() const { return mArea.height; }
+		INT32 getHeight() const;
                
                
         /**
         /**
          * @brief	Changes the area that the viewport covers.
          * @brief	Changes the area that the viewport covers.
@@ -81,7 +81,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Returns actual area of the viewport, in pixels.
 		 * @brief	Returns actual area of the viewport, in pixels.
 		 */
 		 */
-		const RectI& getArea() const { return mArea; }
+		RectI getArea() const;
 
 
 		/**
 		/**
 		 * @brief	Activates or deactivates clears for color, depth or stencil buffers.
 		 * @brief	Activates or deactivates clears for color, depth or stencil buffers.
@@ -133,7 +133,6 @@ namespace BansheeEngine
         RenderTargetPtr mTarget;
         RenderTargetPtr mTarget;
 
 
 		RectF mNormArea;
 		RectF mNormArea;
-		RectI mArea;
 
 
 		bool mRequiresColorClear;
 		bool mRequiresColorClear;
 		bool mRequiresDepthClear;
 		bool mRequiresDepthClear;
@@ -144,8 +143,5 @@ namespace BansheeEngine
 		UINT16 mStencilClearValue;
 		UINT16 mStencilClearValue;
 
 
 		static const Color DEFAULT_CLEAR_COLOR;
 		static const Color DEFAULT_CLEAR_COLOR;
-
-        void updateArea();
-		void targetResized();
     };
     };
 }
 }

+ 6 - 0
BansheeCore/Source/BsVideoModeInfo.cpp

@@ -11,6 +11,12 @@ namespace BansheeEngine
 	VideoMode::~VideoMode()
 	VideoMode::~VideoMode()
 	{ }
 	{ }
 
 
+	bool VideoMode::operator== (const VideoMode& other) const
+	{
+		return mWidth == other.mWidth && mHeight == other.mHeight && 
+			mOutputIdx == other.mOutputIdx && mRefreshRate == other.mRefreshRate;
+	}
+
 	VideoOutputInfo::~VideoOutputInfo()
 	VideoOutputInfo::~VideoOutputInfo()
 	{ 
 	{ 
 		for (auto& videoMode : mVideoModes)
 		for (auto& videoMode : mVideoModes)

+ 36 - 22
BansheeCore/Source/BsViewport.cpp

@@ -13,37 +13,19 @@ namespace BansheeEngine
 		:mTarget(nullptr), mClearColor(DEFAULT_CLEAR_COLOR), mRequiresColorClear(true), mRequiresDepthClear(true), 
 		:mTarget(nullptr), mClearColor(DEFAULT_CLEAR_COLOR), mRequiresColorClear(true), mRequiresDepthClear(true), 
 		mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
 		mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
 	{
 	{
-		updateArea();
+
 	}
 	}
 
 
     Viewport::Viewport(const RenderTargetPtr& target, float x, float y, float width, float height)
     Viewport::Viewport(const RenderTargetPtr& target, float x, float y, float width, float height)
          :mTarget(target), mNormArea(x, y, width, height), mClearColor(DEFAULT_CLEAR_COLOR), mRequiresColorClear(true), 
          :mTarget(target), mNormArea(x, y, width, height), mClearColor(DEFAULT_CLEAR_COLOR), mRequiresColorClear(true), 
 		 mRequiresDepthClear(true), mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
 		 mRequiresDepthClear(true), mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
     {
     {
-        updateArea();
+
     }
     }
 
 
     Viewport::~Viewport()
     Viewport::~Viewport()
     { }
     { }
 
 
-	void Viewport::targetResized()
-	{
-		updateArea();
-	}
-
-    void Viewport::updateArea()
-    {
-		if(mTarget != nullptr)
-		{
-			float height = (float) mTarget->getHeight();
-			float width = (float) mTarget->getWidth();
-
-			mArea.x = (int) (mNormArea.x * width);
-			mArea.y = (int) (mNormArea.y * height);
-			mArea.width = (int) (mNormArea.width * width);
-			mArea.height = (int) (mNormArea.height * height);
-		}
-    }
 
 
     void Viewport::setArea(float x, float y, float width, float height)
     void Viewport::setArea(float x, float y, float width, float height)
     {
     {
@@ -51,10 +33,22 @@ namespace BansheeEngine
         mNormArea.y = y;
         mNormArea.y = y;
         mNormArea.width = width;
         mNormArea.width = width;
         mNormArea.height = height;
         mNormArea.height = height;
-
-        updateArea();
     }
     }
 
 
+	RectI Viewport::getArea() const
+	{
+		float width = (float)mTarget->getWidth();
+		float height = (float)mTarget->getHeight();
+		
+		RectI area;
+		area.x = (int)(mNormArea.x * width);
+		area.y = (int)(mNormArea.y * height);
+		area.width = (int)(mNormArea.width * width);
+		area.height = (int)(mNormArea.height * height);
+
+		return area;
+	}
+
 	void Viewport::setRequiresClear(bool colorClear, bool depthClear, bool stencilClear)
 	void Viewport::setRequiresClear(bool colorClear, bool depthClear, bool stencilClear)
 	{
 	{
 		mRequiresColorClear = colorClear;
 		mRequiresColorClear = colorClear;
@@ -69,6 +63,26 @@ namespace BansheeEngine
 		mStencilClearValue = clearStencil;
 		mStencilClearValue = clearStencil;
 	}
 	}
 
 
+	INT32 Viewport::getX() const 
+	{ 
+		return (INT32)(mNormArea.x * mTarget->getWidth());
+	}
+
+	INT32 Viewport::getY() const 
+	{ 
+		return (INT32)(mNormArea.y * mTarget->getHeight());
+	}
+
+	INT32 Viewport::getWidth() const 
+	{ 
+		return (INT32)(mNormArea.width * mTarget->getWidth());
+	}
+
+	INT32 Viewport::getHeight() const 
+	{ 
+		return (INT32)(mNormArea.height * mTarget->getHeight());
+	}
+
 	Viewport Viewport::clone()
 	Viewport Viewport::clone()
 	{
 	{
 		return *this;
 		return *this;

+ 5 - 0
BansheeEngine/Include/BsGUIListBox.h

@@ -47,6 +47,11 @@ namespace BansheeEngine
 		 */
 		 */
 		void setElements(const Vector<HString>& elements);
 		void setElements(const Vector<HString>& elements);
 
 
+		/**
+		 * @brief	Makes the element with the specified index selected.
+		 */
+		void selectElement(UINT32 idx);
+
 		/**
 		/**
 		 * @copydoc	GUIButtonBase::getElementType
 		 * @copydoc	GUIButtonBase::getElementType
 		 */
 		 */

+ 5 - 0
BansheeEngine/Source/BsGUIListBox.cpp

@@ -58,6 +58,11 @@ namespace BansheeEngine
 			openListBox();
 			openListBox();
 	}
 	}
 
 
+	void GUIListBox::selectElement(UINT32 idx)
+	{
+		elementSelected(idx);
+	}
+
 	bool GUIListBox::mouseEvent(const GUIMouseEvent& ev)
 	bool GUIListBox::mouseEvent(const GUIMouseEvent& ev)
 	{
 	{
 		bool processed = GUIButtonBase::mouseEvent(ev);
 		bool processed = GUIButtonBase::mouseEvent(ev);

+ 2 - 0
BansheeUtility/Source/BsStringTable.cpp

@@ -115,6 +115,8 @@ namespace BansheeEngine
 					}
 					}
 
 
 					lastBracket = -1;
 					lastBracket = -1;
+
+					bracketChars.str(L"");
 					bracketChars.clear();
 					bracketChars.clear();
 				}
 				}
 			}
 			}

+ 90 - 12
ExampleProject/Main/Main.cpp

@@ -35,8 +35,8 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	UINT32 resolutionWidth = 1280;
-	UINT32 resolutionHeight = 720;
+	UINT32 windowResWidth = 1280;
+	UINT32 windowResHeight = 720;
 
 
 	/**
 	/**
 	 * Imports all of our assets and prepares GameObject that handle the example logic.
 	 * Imports all of our assets and prepares GameObject that handle the example logic.
@@ -53,6 +53,16 @@ namespace BansheeEngine
 	 */
 	 */
 	void toggleFullscreen();
 	void toggleFullscreen();
 
 
+	/**
+	 * Called whenever the main render window is resized.
+	 */
+	void renderWindowResized();
+
+	/**
+	 * Called when the selected video mode changes in the video mode list box.
+	 */
+	void videoModeChanged(UINT32 idx);
+
 	/**
 	/**
 	 * Triggered whenever a virtual button is released.
 	 * Triggered whenever a virtual button is released.
 	 */
 	 */
@@ -73,7 +83,7 @@ int CALLBACK WinMain(
 {
 {
 	// Descriptor used for initializing the primary application window.
 	// Descriptor used for initializing the primary application window.
 	RENDER_WINDOW_DESC renderWindowDesc;
 	RENDER_WINDOW_DESC renderWindowDesc;
-	renderWindowDesc.videoMode = VideoMode(resolutionWidth, resolutionHeight);
+	renderWindowDesc.videoMode = VideoMode(windowResWidth, windowResHeight);
 	renderWindowDesc.title = "Banshee Example App";
 	renderWindowDesc.title = "Banshee Example App";
 	renderWindowDesc.fullscreen = false;
 	renderWindowDesc.fullscreen = false;
 
 
@@ -107,7 +117,9 @@ namespace BansheeEngine
 
 
 	GUIButton* toggleFullscreenButton = nullptr;
 	GUIButton* toggleFullscreenButton = nullptr;
 	bool fullscreen = false;
 	bool fullscreen = false;
-	const VideoMode* videoMode = nullptr;
+
+	const VideoMode* selectedVideoMode = nullptr;
+	Vector<const VideoMode*> videoModes;
 
 
 	HMesh exampleModel;
 	HMesh exampleModel;
 	HTexture exampleTexture;
 	HTexture exampleTexture;
@@ -262,10 +274,13 @@ namespace BansheeEngine
 		// Like before, we create a new scene object at (0, 0, 0).
 		// Like before, we create a new scene object at (0, 0, 0).
 		HSceneObject sceneCameraSO = SceneObject::create("SceneCamera");
 		HSceneObject sceneCameraSO = SceneObject::create("SceneCamera");
 
 
-		// We retrieve the primary render window and add a Camera component that
-		// will output whatever it sees into that window (You could also use a render texture
-		// or another window you created).
+		// Get the primary render window we need for creating the camera. Additionally
+		// hook up a callback so we are notified when user resizes the window.
 		RenderWindowPtr window = gApplication().getPrimaryWindow();
 		RenderWindowPtr window = gApplication().getPrimaryWindow();
+		window->onResized.connect(&renderWindowResized);
+
+		// Add a Camera component that will output whatever it sees into that window 
+		// (You could also use a render texture or another window you created).
 		sceneCamera = sceneCameraSO->addComponent<Camera>(window);
 		sceneCamera = sceneCameraSO->addComponent<Camera>(window);
 
 
 		// Set up camera component properties
 		// Set up camera component properties
@@ -278,7 +293,7 @@ namespace BansheeEngine
 		sceneCamera->setNearClipDistance(5);
 		sceneCamera->setNearClipDistance(5);
 
 
 		// Set aspect ratio depending on the current resolution
 		// Set aspect ratio depending on the current resolution
-		sceneCamera->setAspectRatio(resolutionWidth / (float)resolutionHeight); // TODO - This needs to get called whenever resolution changes
+		sceneCamera->setAspectRatio(windowResWidth / (float)windowResHeight);
 
 
 		// Add a CameraFlyer component that allows us to move the camera. See CameraFlyer for more information.
 		// Add a CameraFlyer component that allows us to move the camera. See CameraFlyer for more information.
 		sceneCameraSO->addComponent<CameraFlyer>();
 		sceneCameraSO->addComponent<CameraFlyer>();
@@ -394,7 +409,47 @@ namespace BansheeEngine
 		rightLayout.addElement(toggleFullscreenButton);
 		rightLayout.addElement(toggleFullscreenButton);
 
 
 		// Add a profiler overlay object that is resposible for displaying CPU and GPU profiling GUI
 		// Add a profiler overlay object that is resposible for displaying CPU and GPU profiling GUI
-		profilerOverlay = guiSO->addComponent<ProfilerOverlay>(guiCamera->getViewport());
+		//profilerOverlay = guiSO->addComponent<ProfilerOverlay>(guiCamera->getViewport());
+
+		// Set up video mode list box
+		// First get a list of output devices
+		const VideoModeInfo& videoModeInfo = RenderSystem::instance().getVideoModeInfo();
+
+		// Get video mode info for the primary monitor
+		const VideoOutputInfo& primaryMonitorInfo = videoModeInfo.getOutputInfo(0);
+
+		// Make the current desktop mode the default video mode
+		selectedVideoMode = &primaryMonitorInfo.getDesktopVideoMode();
+
+		// Create list box elements for each available video mode
+		UINT32 numVideoModes = primaryMonitorInfo.getNumVideoModes();
+		Vector<HString> videoModeLabels(numVideoModes);
+		UINT32 selectedVideoModeIdx = 0;
+		for (UINT32 i = 0; i < numVideoModes; i++)
+		{
+			const VideoMode& curVideoMode = primaryMonitorInfo.getVideoMode(i);
+
+			HString videoModeLabel(L"{0} x {1} at {2}Hz");
+			videoModeLabel.setParameter(0, toWString(curVideoMode.getWidth()));
+			videoModeLabel.setParameter(1, toWString(curVideoMode.getHeight()));
+			videoModeLabel.setParameter(2, toWString(Math::roundToInt(curVideoMode.getRefreshRate())));
+
+			videoModeLabels[i] = videoModeLabel;
+			videoModes.push_back(&curVideoMode);
+
+			if (curVideoMode == *selectedVideoMode)
+				selectedVideoModeIdx = i;
+		}
+		
+		// Create the list box
+		GUIListBox* videoModeListBox = GUIListBox::create(videoModeLabels);
+		rightLayout.addElement(videoModeListBox);
+
+		// Select the default (desktop) video mode
+		videoModeListBox->selectElement(selectedVideoModeIdx);
+
+		// Set up a callback to be notified when video mode changes
+		videoModeListBox->onSelectionChanged.connect(&videoModeChanged);
 	}
 	}
 
 
 	void shutDownExample()
 	void shutDownExample()
@@ -430,17 +485,40 @@ namespace BansheeEngine
 		// call something from the wrong thread.
 		// call something from the wrong thread.
 		if (fullscreen)
 		if (fullscreen)
 		{
 		{
-			gCoreAccessor().setWindowed(window, resolutionWidth, resolutionHeight);
+			gCoreAccessor().setWindowed(window, windowResWidth, windowResHeight);
 		}
 		}
 		else
 		else
 		{
 		{
-			//gCoreAccessor().setFullscreen(window, *videoMode);
-			gCoreAccessor().setFullscreen(window, 1920, 1200);
+			gCoreAccessor().setFullscreen(window, *selectedVideoMode);
 		}
 		}
 
 
 		fullscreen = !fullscreen;
 		fullscreen = !fullscreen;
 	}
 	}
 
 
+	void renderWindowResized()
+	{
+		RenderWindowPtr window = gApplication().getPrimaryWindow();
+
+		if (!fullscreen)
+		{
+			windowResWidth = window->getWidth();
+			windowResHeight = window->getHeight();
+		}
+
+		sceneCamera->setAspectRatio(window->getWidth() / (float)window->getHeight());
+	}
+
+	void videoModeChanged(UINT32 idx)
+	{
+		selectedVideoMode = videoModes[idx];
+
+		if (fullscreen)
+		{
+			RenderWindowPtr window = gApplication().getPrimaryWindow();
+			gCoreAccessor().setFullscreen(window, *selectedVideoMode);
+		}
+	}
+
 	void buttonUp(const VirtualButton& button, UINT32 deviceIdx)
 	void buttonUp(const VirtualButton& button, UINT32 deviceIdx)
 	{
 	{
 		// Check if the pressed button is one of the either buttons we defined
 		// Check if the pressed button is one of the either buttons we defined

+ 4 - 0
Polish.txt

@@ -21,6 +21,10 @@ Polish TODO:
 Automatically release resources on shutdown instead of forcing the user to manually call unload() and set handles to nullptr.
 Automatically release resources on shutdown instead of forcing the user to manually call unload() and set handles to nullptr.
  - e.g. just invalidate all handles automatically
  - e.g. just invalidate all handles automatically
 
 
+--------------------
+
+Delay this until release:
+
 Input issues:
 Input issues:
  - I cannot have input of 1 one frame and input of 0 another. This happens when frames are too short. I might need to add very short smoothing times?
  - I cannot have input of 1 one frame and input of 0 another. This happens when frames are too short. I might need to add very short smoothing times?
  - I cannot have input set to 1 during the entire frame if the frame is very long and user just moved the mouse a bit.
  - I cannot have input set to 1 during the entire frame if the frame is very long and user just moved the mouse a bit.