Browse Source

Fixed issue with HString parameter placement
Fixed issue with viewport resizing

Marko Pintera 11 years ago
parent
commit
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);
 		virtual ~VideoMode();
 
+		bool operator== (const VideoMode& other) const;
+
 		/**
 		 * @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.
          */
-        INT32 getX() const { return mArea.x; }
+		INT32 getX() const;
 
         /**
          * @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.
          */
-        INT32 getWidth() const { return mArea.width; }
+		INT32 getWidth() const;
 
 		/**
          * @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.
@@ -81,7 +81,7 @@ namespace BansheeEngine
 		/**
 		 * @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.
@@ -133,7 +133,6 @@ namespace BansheeEngine
         RenderTargetPtr mTarget;
 
 		RectF mNormArea;
-		RectI mArea;
 
 		bool mRequiresColorClear;
 		bool mRequiresDepthClear;
@@ -144,8 +143,5 @@ namespace BansheeEngine
 		UINT16 mStencilClearValue;
 
 		static const Color DEFAULT_CLEAR_COLOR;
-
-        void updateArea();
-		void targetResized();
     };
 }

+ 6 - 0
BansheeCore/Source/BsVideoModeInfo.cpp

@@ -11,6 +11,12 @@ namespace BansheeEngine
 	VideoMode::~VideoMode()
 	{ }
 
+	bool VideoMode::operator== (const VideoMode& other) const
+	{
+		return mWidth == other.mWidth && mHeight == other.mHeight && 
+			mOutputIdx == other.mOutputIdx && mRefreshRate == other.mRefreshRate;
+	}
+
 	VideoOutputInfo::~VideoOutputInfo()
 	{ 
 		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), 
 		mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
 	{
-		updateArea();
+
 	}
 
     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), 
 		 mRequiresDepthClear(true), mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
     {
-        updateArea();
+
     }
 
     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)
     {
@@ -51,10 +33,22 @@ namespace BansheeEngine
         mNormArea.y = y;
         mNormArea.width = width;
         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)
 	{
 		mRequiresColorClear = colorClear;
@@ -69,6 +63,26 @@ namespace BansheeEngine
 		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()
 	{
 		return *this;

+ 5 - 0
BansheeEngine/Include/BsGUIListBox.h

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

+ 5 - 0
BansheeEngine/Source/BsGUIListBox.cpp

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

+ 2 - 0
BansheeUtility/Source/BsStringTable.cpp

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

+ 90 - 12
ExampleProject/Main/Main.cpp

@@ -35,8 +35,8 @@
 
 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.
@@ -53,6 +53,16 @@ namespace BansheeEngine
 	 */
 	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.
 	 */
@@ -73,7 +83,7 @@ int CALLBACK WinMain(
 {
 	// Descriptor used for initializing the primary application window.
 	RENDER_WINDOW_DESC renderWindowDesc;
-	renderWindowDesc.videoMode = VideoMode(resolutionWidth, resolutionHeight);
+	renderWindowDesc.videoMode = VideoMode(windowResWidth, windowResHeight);
 	renderWindowDesc.title = "Banshee Example App";
 	renderWindowDesc.fullscreen = false;
 
@@ -107,7 +117,9 @@ namespace BansheeEngine
 
 	GUIButton* toggleFullscreenButton = nullptr;
 	bool fullscreen = false;
-	const VideoMode* videoMode = nullptr;
+
+	const VideoMode* selectedVideoMode = nullptr;
+	Vector<const VideoMode*> videoModes;
 
 	HMesh exampleModel;
 	HTexture exampleTexture;
@@ -262,10 +274,13 @@ namespace BansheeEngine
 		// Like before, we create a new scene object at (0, 0, 0).
 		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();
+		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);
 
 		// Set up camera component properties
@@ -278,7 +293,7 @@ namespace BansheeEngine
 		sceneCamera->setNearClipDistance(5);
 
 		// 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.
 		sceneCameraSO->addComponent<CameraFlyer>();
@@ -394,7 +409,47 @@ namespace BansheeEngine
 		rightLayout.addElement(toggleFullscreenButton);
 
 		// 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()
@@ -430,17 +485,40 @@ namespace BansheeEngine
 		// call something from the wrong thread.
 		if (fullscreen)
 		{
-			gCoreAccessor().setWindowed(window, resolutionWidth, resolutionHeight);
+			gCoreAccessor().setWindowed(window, windowResWidth, windowResHeight);
 		}
 		else
 		{
-			//gCoreAccessor().setFullscreen(window, *videoMode);
-			gCoreAccessor().setFullscreen(window, 1920, 1200);
+			gCoreAccessor().setFullscreen(window, *selectedVideoMode);
 		}
 
 		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)
 	{
 		// 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.
  - e.g. just invalidate all handles automatically
 
+--------------------
+
+Delay this until release:
+
 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 set to 1 during the entire frame if the frame is very long and user just moved the mouse a bit.