Hello!
I’m developing a simple game app, I’ve started with coding a splash screen (short scene on startup) & trying to make GameWindow form fully transparent, but not content of that form.
Basically, trying to show image and some text on top of transparent window before running the game.
I’ve read few articles about WindowsExtendedStyles & DesktopWindowsManager & DirectComposition. WsExStyles set transparency to entire window, while DWM seem to work fine, except that GameWindow flickers on Loading event. Tried also setting TransparentKey value, but it leave ugly edges on a picture. I don’t quite understand how MonoGame engine managing windows (is it drawing backbuffer to winForm?? and what is blinking is the form that renders?).
I suppose, it will be easier to create wpf for this purpose, just want to be able to use Conent pipeline and not connecting many libraries.
Is it possible to achieve this goal not trying to connect MonoGame/WPF or MonoGame/WinForm, using default Game class?
Attaching Code
using System;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace xProject
{
class SplashScreen : Game
{
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte bAlpham, int dwFlags);
[DllImport("dwmapi.dll")]
static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMargins);
struct Margins
{
public int left, right, top, bottom;
}
Margins marg;
GraphicsDeviceManager GDM;
SpriteBatch sBatch;
Texture2D txr;
SpriteFont sFont;
Vector2 wndSz, txrOrig, strSz, AdRes;
int x;
float trKey, tmElapsed;
string greetings;
enum Fade { txrIn, txrOut, strIn, strOut, finish }
Fade fState;
System.Windows.Forms.Form f;
public SplashScreen()
{
GDM = new GraphicsDeviceManager(this);
AdRes = new Vector2(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width, GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height);
wndSz = AdRes / 2;
GDM.PreferredBackBufferWidth = (int)wndSz.X;
GDM.PreferredBackBufferHeight = (int)wndSz.Y;
Content.RootDirectory = "Content";
IntPtr hWnd = Window.Handle;
f = System.Windows.Forms.Control.FromHandle(hWnd).FindForm();
f.TopMost = true;
Window.IsBorderless = true;
Window.Position = ((AdRes - wndSz) / 2).ToPoint();
//Setting margins to extend frame
marg.left = marg.top = 0;
marg.right = (int)wndSz.X;
marg.bottom = (int)wndSz.Y;
DwmExtendFrameIntoClientArea(hWnd, ref marg);
//Setting ExStyle to Layered & Transparent
SetWindowLong(hWnd, -20, GetWindowLong(hWnd, -20) | 0x20 | 0x8000);
SetLayeredWindowAttributes(hWnd, 0, 128, 0x2);
greetings = "xProject";
trKey = 0;
fState = 0;
x = 2;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
sBatch = new SpriteBatch(GraphicsDevice);
txr = Content.Load<Texture2D>("Wolf");
sFont = Content.Load<SpriteFont>("SpF");
txrOrig = new Vector2(txr.Width, txr.Height) / 2;
strSz = sFont.MeasureString(greetings);
base.LoadContent();
}
protected override void UnloadContent()
{
base.UnloadContent();
}
protected override void Update(GameTime gameTime)
{
tmElapsed = (float)gameTime.ElapsedGameTime.TotalSeconds / x;
if (Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit();
switch ((int)fState)
{
case 0: if (trKey < 1) trKey += tmElapsed; else fState++; break;
case 1: if (trKey > 0) trKey -= tmElapsed; else fState++; break;
case 2: if (trKey < 1) trKey += tmElapsed; else fState++; break;
case 3: if (trKey > 0) trKey -= tmElapsed; else fState++; break;
case 4: break;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Transparent);
sBatch.Begin();
switch ((int)fState)
{
case 0:
case 1:
sBatch.Draw(txr, wndSz / 2 - txrOrig, Color.White * trKey); break;
case 2:
case 3:
sBatch.DrawString(sFont, greetings, (wndSz - strSz) / 2, Color.White * trKey); break;
}
sBatch.End();
base.Draw(gameTime);
}
}
}
^ Drawing some image and text in SpriteBatch ^
I hope I make it clear, any advice with be appreciated… Thank you