Преглед изворни кода

Work on transparent windows and splash screen

BearishSun пре 10 година
родитељ
комит
feba0092b2

+ 1 - 1
BansheeCore/Include/BsPrefabUtility.h

@@ -107,7 +107,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Restores instance data in the provided hierarchy, but only for objects without a link id.
 		 *			Since the objects do not have a link ID we rely on their sequential order to find out
-		 *			which instance data belong to which object.
+		 *			which instance data belongs to which object.
 		 *
 		 * @param[in]	so		Object to traverse and restore the instance data.
 		 * @param[in]	proxy	Hierarchy containing instance data for all objects and components, returned by

+ 6 - 0
BansheeCore/Include/Win32/BsWin32Platform.h

@@ -14,6 +14,12 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT Win32Platform : public Platform
 	{
 	public:
+		/**
+		 * @brief	Creates a new bitmap usable by various Win32 methods from the provided pixel data.
+		 *			Caller must ensure to call ::DeleteObject on the bitmap handle when finished.
+		 */
+		static HBITMAP createBitmap(const PixelDataPtr& pixelData, bool premultiplyAlpha);
+
 		/**
 		 * @brief	Main message loop callback that processes messages received from windows.
 		 */

+ 3 - 1
BansheeCore/Include/Win32/BsWin32Window.h

@@ -14,7 +14,7 @@ namespace BansheeEngine
 		WINDOW_DESC()
 			: module(nullptr), monitor(nullptr), parent(nullptr), external(nullptr), width(0), height(0), fullscreen(false)
 			, hidden(false), left(-1), top(-1), title(""), border(WindowBorder::Normal), outerDimensions(false)
-			, enableDoubleClick(true), toolWindow(false)
+			, enableDoubleClick(true), toolWindow(false), creationParams(nullptr), alphaBlending(false)
 		{ }
 
 		HINSTANCE module; /**< Instance to the local module. */
@@ -33,6 +33,8 @@ namespace BansheeEngine
 		bool outerDimensions; /**< Do our dimensions include space for things like title-bar and border. */
 		bool enableDoubleClick; /**< Does window accept double-clicks. */
 		bool toolWindow; /**< Tool windows have a different style than normal windows and can be created with no border or title bar. */
+		PixelDataPtr background; /**< Optional background image to apply to the window. */
+		bool alphaBlending; /**< If true the window will support transparency based on the alpha channel of the background image. */
 	};
 
 	/**

+ 52 - 1
BansheeCore/Source/Win32/BsWin32Platform.cpp

@@ -473,6 +473,57 @@ namespace BansheeEngine
 		return false;
 	}
 
+	HBITMAP Win32Platform::createBitmap(const PixelDataPtr& pixelData, bool premultiplyAlpha)
+	{
+		BITMAPINFO bi;
+
+		ZeroMemory(&bi, sizeof(BITMAPINFO));
+		bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+		bi.bmiHeader.biWidth = pixelData->getWidth();
+		bi.bmiHeader.biHeight = pixelData->getHeight();
+		bi.bmiHeader.biPlanes = 1;
+		bi.bmiHeader.biBitCount = 32;
+		bi.bmiHeader.biCompression = BI_RGB;
+
+		HDC hDC = GetDC(nullptr);
+
+		void* data = nullptr;
+		HBITMAP hBitmap = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, (void**)&data, nullptr, 0);
+
+		HDC hBitmapDC = CreateCompatibleDC(hDC);
+		ReleaseDC(nullptr, hDC);
+
+		//Select the bitmaps to DC
+		HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, hBitmap);
+
+		//Scan each pixel of the source bitmap and create the masks
+		Color pixel;
+		DWORD *dst = (DWORD*)data;
+		for (UINT32 y = 0; y < pixelData->getHeight(); ++y)
+		{
+			for (UINT32 x = 0; x < pixelData->getWidth(); ++x)
+			{
+				pixel = pixelData->getColorAt(x, pixelData->getHeight() - y - 1);
+
+				if (premultiplyAlpha)
+				{
+					pixel.r *= pixel.a;
+					pixel.g *= pixel.a;
+					pixel.b *= pixel.a;
+				}
+
+				*dst = pixel.getAsBGRA();
+
+				dst++;
+			}
+		}
+
+		SelectObject(hBitmapDC, hOldBitmap);
+		DeleteDC(hBitmapDC);
+
+		return hBitmap;
+	}
+
 	LRESULT CALLBACK Win32Platform::_win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 	{
 		if (uMsg == WM_CREATE)
@@ -480,7 +531,7 @@ namespace BansheeEngine
 			SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
 
 			RenderWindowCore* newWindow = (RenderWindowCore*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-			if(newWindow->getProperties().isModal())
+			if (newWindow != nullptr && newWindow->getProperties().isModal())
 			{
 				if(!mData->mModalWindowStack.empty())
 				{

+ 40 - 0
BansheeCore/Source/Win32/BsWin32Window.cpp

@@ -87,6 +87,11 @@ namespace BansheeEngine
 					else
 						m->style |= WS_CHILD;
 				}
+				else
+				{
+					if (desc.toolWindow)
+						m->styleEx = WS_EX_TOOLWINDOW;
+				}
 
 				if (!desc.parent || desc.toolWindow)
 				{
@@ -123,6 +128,9 @@ namespace BansheeEngine
 					if (top < 0)
 						top = (screenh - height) / 2;
 				}
+
+				if (desc.background != nullptr)
+					m->styleEx |= WS_EX_LAYERED;
 			}
 			else
 			{
@@ -161,6 +169,38 @@ namespace BansheeEngine
 		GetClientRect(m->hWnd, &rect);
 		m->width = rect.right;
 		m->height = rect.bottom;
+
+		// Set background, if any
+		if (desc.background != nullptr)
+		{
+			HBITMAP backgroundBitmap = Win32Platform::createBitmap(desc.background, true);
+
+			HDC hdcScreen = GetDC(nullptr);
+			HDC hdcMem = CreateCompatibleDC(hdcScreen);
+			HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, backgroundBitmap);
+
+			BLENDFUNCTION blend = { 0 };
+			blend.BlendOp = AC_SRC_OVER;
+			blend.SourceConstantAlpha = 255;
+			blend.AlphaFormat = AC_SRC_ALPHA;
+
+			POINT origin;
+			origin.x = m->left;
+			origin.y = m->top;
+
+			SIZE size;
+			size.cx = m->width;
+			size.cy = m->height;
+
+			POINT zero = { 0 };
+
+			UpdateLayeredWindow(m->hWnd, hdcScreen, &origin, &size,
+				hdcMem, &zero, RGB(0, 0, 0), &blend, desc.alphaBlending ? ULW_ALPHA : ULW_OPAQUE);
+
+			SelectObject(hdcMem, hOldBitmap);
+			DeleteDC(hdcMem);
+			ReleaseDC(nullptr, hdcScreen);
+		}
 	}
 
 	Win32Window::~Win32Window()

+ 28 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -8,6 +8,7 @@
 
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 #include <windows.h>
+#include "Win32/BsWin32Window.h"
 
 using namespace BansheeEngine;
 
@@ -57,6 +58,32 @@ void ShutdownDebugConsole()
 }
 #endif // End BS_DEBUG_MODE
 
+void ShowSplashScreen()
+{
+	//WINDOW_DESC windowDesc;
+	//windowDesc.border = WindowBorder::None;
+	//windowDesc.width = 600;
+	//windowDesc.height = 662;
+	//windowDesc.left = -1;
+	//windowDesc.top = -1;
+	//windowDesc.title = "Banshee Splash";
+	//windowDesc.toolWindow = true;
+	//windowDesc.alphaBlending = true;
+
+	//Path splashTexturePath = "..\\..\\..\\Data\\Raw\\Engine\\BansheeLogo.png";
+
+	//auto textureIO = std::static_pointer_cast<TextureImportOptions>(gImporter().createImportOptions(splashTexturePath));
+	//textureIO->setCPUReadable(true);
+	//HTexture splashTexture = gImporter().import<Texture>(splashTexturePath, textureIO);
+
+	//PixelDataPtr splashPixelData = splashTexture->getProperties().allocateSubresourceBuffer(0);
+	//splashTexture->readData(*splashPixelData);
+
+	//windowDesc.background = splashPixelData;
+
+	//bs_new<Win32Window>(windowDesc);
+}
+
 int CALLBACK WinMain(
 	_In_  HINSTANCE hInstance,
 	_In_  HINSTANCE hPrevInstance,
@@ -72,7 +99,7 @@ int CALLBACK WinMain(
 
 	__try
 	{
-		EditorApplication::startUp(RenderAPIPlugin::OpenGL);
+		EditorApplication::startUp(RenderAPIPlugin::DX11);
 		EditorApplication::instance().runMainLoop();
 		EditorApplication::shutDown();
 	}