Yeah you’re right - If I want close app if it still running ( hidden from background )
Now @BlizzCrafter my dear I have got Gtk Sharp 2.x with MonoGame
But I don’t know why does it not show textures because I already copy to debug directory.
Real code:
Gtk2Backend.cs
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
namespace Microsoft.XNA.Framework.Gtk2
{
public class Gtk2Backend
{
/// <summary>
/// Gets or Sets the backend ContentManager.
/// </summary>
public static ContentManager Content
{
get { return MasterWindow.Instance.Content; }
set { MasterWindow.Instance.Content = value; }
}
/// <summary>
/// Gets the backend GraphicsDevice.
/// </summary>
public static GraphicsDevice GraphicsDevice
{
get { return MasterWindow.Instance.GraphicsDevice; }
}
/// <summary>
/// Gets the backend GraphicsDeviceManager.
/// </summary>
public static GraphicsDeviceManager GraphicsDeviceManager
{
get { return MasterWindow.Instance.DeviceManager; }
}
/// <summary>
/// Begins the drawing process making present unusable.
/// </summary>
public static bool BeginDraw(uint width, uint height)
{
return MasterWindow.Instance.BeginRender(width, height);
}
/// <summary>
/// Finalizes the drawing and makes present usable.
/// </summary>
public static void EndDraw()
{
MasterWindow.Instance.EndRender();
}
/// <summary>
/// Returns a bitmap of the BackBuffer to be drawn to a control.
/// </summary>
public static Bitmap Present()
{
return MasterWindow.Instance.BackBuffer;
}
private class MasterWindow : Game
{
internal GraphicsDeviceManager DeviceManager;
internal Bitmap BackBuffer;
private bool isDrawing;
#region Singleton
private static readonly Lazy<MasterWindow> _instance = new Lazy<MasterWindow>
(() => new MasterWindow(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
internal static MasterWindow Instance { get { return _instance.Value; } }
// Constructor
private MasterWindow() : base()
{
// Init Graphics Device
DeviceManager = new GraphicsDeviceManager(this);
// Make sure the entire game window is created
RunOneFrame();
}
protected override void Dispose(bool disposing)
{
if (BackBuffer != null)
{
BackBuffer.Dispose();
BackBuffer = null;
}
DeviceManager.Dispose();
base.Dispose(disposing);
}
#endregion
internal bool BeginRender(uint width, uint height)
{
if (isDrawing)
throw new Exception("Draw operation already in progress!");
// Clear BackBuffer if doing new render
if (BackBuffer != null)
{
BackBuffer.Dispose();
BackBuffer = null;
}
// Prepair the screen
DeviceManager.PreferredBackBufferWidth = (Int32)width;
DeviceManager.PreferredBackBufferHeight = (Int32)height;
DeviceManager.ApplyChanges();
isDrawing = true;
return true;
}
internal void EndRender()
{
// Exit if not drawing anything
if (!isDrawing) return;
// Create Surface Image
var width = DeviceManager.PreferredBackBufferWidth;
var height = DeviceManager.PreferredBackBufferHeight;
var bmp = new Bitmap(width, height, PixelFormat.Format32bppRgb);
var bmpData = bmp.LockBits(
new System.Drawing.Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppRgb);
var pixelData = new int[width * height];
// Get buffer data
GraphicsDevice.GetBackBufferData(pixelData);
for (int i = 0; i < pixelData.Length; i++)
#pragma warning disable // Caused by bitwise function requiring uint to int conversion
pixelData[i] = (int)( // Swap bgra - rgba
(pixelData[i] & 0x000000ff) << 16 |
(pixelData[i] & 0x0000FF00) |
(pixelData[i] & 0x00FF0000) >> 16 |
(pixelData[i] & 0xFF000000));
#pragma warning disable
// Convert to bitmap
Marshal.Copy(pixelData, 0, bmpData.Scan0, pixelData.Length);
bmp.UnlockBits(bmpData);
BackBuffer = bmp;
// Mark as done drawing.
isDrawing = false;
}
}
}
}
RenderArea.cs
using System;
using Cairo;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.XNA.Framework.Gtk2
{
public class RenderArea : Gtk.DrawingArea
{
private Gdk.Color _clearColor;
private Viewport _view;
public event EventHandler Render;
public RenderArea()
{
}
public Gdk.Color BackColor
{
get
{
return _clearColor;
}
set
{
_clearColor = new Gdk.Color((byte)value.Red, (byte)value.Green, (byte)value.Blue);
}
}
protected override bool OnConfigureEvent(Gdk.EventConfigure evnt)
{
BackColor = BackColor;
_view = new Viewport(0, 0, Allocation.Width, Allocation.Height);
Render += OnRender;
SizeAllocated += sizeAllocatedHandler;
return base.OnConfigureEvent(evnt);
}
private void sizeAllocatedHandler(object o, Gtk.SizeAllocatedArgs args)
{
_view = new Viewport(0, 0, args.Allocation.Width, args.Allocation.Height);
}
protected override bool OnExposeEvent(Gdk.EventExpose evnt)
{
Cairo.Context ctx;
ctx = Gdk.CairoHelper.Create(GdkWindow);
PointD p1, p2, p3, p4;
p1 = new PointD(0, 0);
p2 = new PointD(Allocation.Width, 0);
p3 = new PointD(Allocation.Width, Allocation.Height);
p4 = new PointD(0, Allocation.Height);
ctx.MoveTo(p1);
ctx.LineTo(p2);
ctx.LineTo(p3);
ctx.LineTo(p4);
ctx.LineTo(p1);
ctx.ClosePath();
#pragma warning disable CS0612 // Type or member is obsolete
#pragma warning disable CS0618 // Type or member is obsolete
ctx.Color = new Cairo.Color(_clearColor.Red, _clearColor.Green, _clearColor.Blue);
ctx.FillPreserve();
ctx.Paint();
Gtk2Backend.BeginDraw((uint)Allocation.Width, (uint)Allocation.Height);
Gtk2Backend.GraphicsDevice.Clear(new Microsoft.Xna.Framework.Color(_clearColor.Red / 65535f, _clearColor.Green / 65535f, _clearColor.Blue / 65535f, 1f));
Gtk2Backend.GraphicsDevice.Viewport = _view;
Render -= OnRender;
Gtk2Backend.EndDraw();
return base.OnExposeEvent(evnt);
}
protected virtual void OnRender(object sender, EventArgs e)
{
}
}
}
Download it and convert to texture
MainWindow.cs
using System;
using Gtk;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.XNA.Framework.Gtk2;
namespace MonoGame_Gtk2.Desktop
{
public class MainWindowWithMonoGame : Gtk.Window
{
// Gtk Sharp 2
private Gtk.Fixed _fixed;
private RenderArea _renderArea;
private RenderArea _renderArea2;
// MonoGame
private GraphicsDeviceManager graphics;
private SpriteBatch _sb;
private Texture2D texture;
public MainWindowWithMonoGame() : base(Gtk.WindowType.Toplevel)
{
Title = "MonoGame embeds into Gtk Sharp 2";
SetDefaultSize(800, 400);
DeleteEvent += DeleteEventHandler;
_fixed = new Gtk.Fixed();
_renderArea = new RenderArea();
_renderArea.SetSizeRequest(380, 380);
_renderArea.BackColor = new Gdk.Color(1, 0, 0);
_renderArea.Render += OnRender;
_fixed.Put(_renderArea, 10, 10);
Add(_fixed);
_renderArea2 = new RenderArea();
_renderArea2.SetSizeRequest(380, 380);
_renderArea2.BackColor = new Gdk.Color((byte)0.61, (byte)0.79, (byte)0.66);
_renderArea2.Render += OnRender2;
_fixed.Put(_renderArea2, 410, 10);
ShowAll();
graphics = Gtk2Backend.GraphicsDeviceManager;
Gtk2Backend.Content.RootDirectory = "Content";
_sb = new SpriteBatch(Gtk2Backend.GraphicsDevice);
texture = Gtk2Backend.Content.Load<Texture2D>("pengiun_happy");
}
private void OnRender(object sender, EventArgs e)
{
_sb.Begin();
_sb.Draw(texture, Vector2.Zero, Color.White);
_sb.End();
}
private void OnRender2(object sender, EventArgs e)
{
_sb.Begin();
_sb.Draw(texture, Vector2.Zero, Color.White);
_sb.End();
}
private void DeleteEventHandler(object o, DeleteEventArgs args)
{
Environment.Exit(-1);
Gtk.Application.Quit();
}
}
}
That is real from Ubuntu 16.04 ^^
I am too far for showing textures and flat colorable textures… I don’t know I will check vertices
/// EDIT: I found issue because Bitmap and BitmapData can’t work for Gtk Sharp 2.x Because both classes image and pixbuf for Gtk Sharp are very different to Bitmap and BitmnapData.
Is it correct or wrong? I really don’t know how do I Bitmap and BitmapData like for Gtk Sharp 2?
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
//using System.Drawing;
//using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
using Gdk;
/**
*
* I try for Gtk Sharp 2 with PixBuf it works only for Gtk Sharp 2 but Bitmap is for WinForms
* How do I fix with bixelDates from byte[] because Gdk.Color() has only byte r, byte g and byte b
* Who know pixbuf works for Gtk Sharp 2. Thanks
*
*/
namespace Microsoft.XNA.Framework.Gtk2
{
public class Gtk2Backend
{
/// <summary>
/// Gets or Sets the backend ContentManager.
/// </summary>
public static ContentManager Content
{
get { return MasterWindow.Instance.Content; }
set { MasterWindow.Instance.Content = value; }
}
/// <summary>
/// Gets the backend GraphicsDevice.
/// </summary>
public static GraphicsDevice GraphicsDevice
{
get { return MasterWindow.Instance.GraphicsDevice; }
}
/// <summary>
/// Gets the backend GraphicsDeviceManager.
/// </summary>
public static GraphicsDeviceManager GraphicsDeviceManager
{
get { return MasterWindow.Instance.DeviceManager; }
}
/// <summary>
/// Begins the drawing process making present unusable.
/// </summary>
public static bool BeginDraw(uint width, uint height)
{
return MasterWindow.Instance.BeginRender(width, height);
}
/// <summary>
/// Finalizes the drawing and makes present usable.
/// </summary>
public static void EndDraw()
{
MasterWindow.Instance.EndRender();
}
/// <summary>
/// Returns a bitmap of the BackBuffer to be drawn to a control.
/// </summary>
/*public static Bitmap Present()
{
return MasterWindow.Instance.BackBuffer;
}*/
private class MasterWindow : Game
{
internal GraphicsDeviceManager DeviceManager;
// For WinForms
//internal Bitmap BackBuffer;
// for Gtk Sharp 2
internal Pixbuf BackBufferGtk;
private bool isDrawing;
#region Singleton
private static readonly Lazy<MasterWindow> _instance = new Lazy<MasterWindow>
(() => new MasterWindow(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
internal static MasterWindow Instance { get { return _instance.Value; } }
// Constructor
private MasterWindow() : base()
{
// Init Graphics Device
DeviceManager = new GraphicsDeviceManager(this);
// Make sure the entire game window is created
RunOneFrame();
}
protected override void Dispose(bool disposing)
{
/* if (BackBuffer != null)
{
BackBuffer.Dispose();
BackBuffer = null;
}*/
if (BackBufferGtk != null)
{
BackBufferGtk.Dispose();
BackBufferGtk = null;
}
DeviceManager.Dispose();
base.Dispose(disposing);
}
#endregion
internal bool BeginRender(uint width, uint height)
{
if (isDrawing)
throw new Exception("Draw operation already in progress!");
// Clear BackBuffer if doing new render
/* if (BackBuffer != null)
{
BackBuffer.Dispose();
BackBuffer = null;
}*/
// Gtk
if(BackBufferGtk != null)
{
BackBufferGtk.Dispose();
BackBufferGtk = null;
}
// Prepair the screen
DeviceManager.PreferredBackBufferWidth = (Int32)width;
DeviceManager.PreferredBackBufferHeight = (Int32)height;
DeviceManager.ApplyChanges();
isDrawing = true;
return true;
}
internal void EndRender()
{
// Exit if not drawing anything
if (!isDrawing) return;
// Create Surface Image
var width = DeviceManager.PreferredBackBufferWidth;
var height = DeviceManager.PreferredBackBufferHeight;
/* var bmp = new Bitmap(width, height, PixelFormat.Format32bppRgb);
var bmpData = bmp.LockBits(
new System.Drawing.Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppRgb);
var pixelData = new int[width * height];
// Get buffer data
GraphicsDevice.GetBackBufferData(pixelData);
for (int i = 0; i < pixelData.Length; i++)
#pragma warning disable // Caused by bitwise function requiring uint to int conversion
pixelData[i] = (int)( // Swap bgra - rgba
(pixelData[i] & 0x000000ff) << 16 |
(pixelData[i] & 0x0000FF00) |
(pixelData[i] & 0x00FF0000) >> 16 |
(pixelData[i] & 0xFF000000));
#pragma warning disable
// Convert to bitmap
Marshal.Copy(pixelData, 0, bmpData.Scan0, pixelData.Length);
bmp.UnlockBits(bmpData);
BackBuffer = bmp; */
/*
* For Gtk Support
*/
byte[] pixelDatas = new byte[width * height];
GraphicsDevice.GetBackBufferData<byte>(pixelDatas);
Pixbuf pix = new Pixbuf(pixelDatas, width, height);
for (int i = 0; i < pixelDatas.Length; i++)
pixelDatas[i] = (byte)( // Swap bgra - rgba
(pixelDatas[i] & 0x000000ff) << 16 |
(pixelDatas[i] & 0x0000FF00) |
(pixelDatas[i] & 0x00FF0000) >> 16 );
Marshal.Copy(pixelDatas, 0, IntPtr.Zero, pixelDatas.Length);
BackBufferGtk = pix;
// Mark as done drawing.
isDrawing = false;
}
}
}
}
But I am not sure 100% what is wrong or correct for pixbuf is like BitmapData and image is like Bitmap?
/// EDIT 2:
I found Stockoverflow:
What does it mean? Gdk.Image and Gtk.Image? What is different? Gtk.Image = Bitmap and Gdk.Image means BitmapData?
Thanks!
// Yeah colors of Clear are córrectly. But I tried vertices, textures and models no successfully
How do I fix?
Because I already updated RenderArea and MainWindow
RenderArea.cs
using System;
using Gtk;
namespace Microsoft.XNA.Framework.Gtk2
{
public class RenderArea : Gtk.DrawingArea
{
private Cairo.Color _clearColor;
private Xna.Framework.Graphics.Viewport _view;
public event EventHandler Render;
public RenderArea()
{
BackColor = BackColor;
_view = new Xna.Framework.Graphics.Viewport(0, 0, Allocation.Width, Allocation.Height);
Render += OnRender;
SizeAllocated += sizeAllocatedHandler;
ExposeEvent += new ExposeEventHandler(OnDrawingAreaExposed);
}
public Cairo.Color BackColor
{
get
{
return _clearColor;
}
set
{
_clearColor = new Cairo.Color(value.R, value.G, value.B, value.A);
}
}
private void sizeAllocatedHandler(object o, Gtk.SizeAllocatedArgs args)
{
_view = new Xna.Framework.Graphics.Viewport(0, 0, args.Allocation.Width, args.Allocation.Height);
}
private void OnDrawingAreaExposed(object o, ExposeEventArgs args)
{
DrawingArea area = (DrawingArea)o;
Cairo.Context cr = Gdk.CairoHelper.Create(area.GdkWindow);
Cairo.PointD p1, p2, p3, p4;
p1 = new Cairo.PointD(0, 0);
p2 = new Cairo.PointD(Allocation.Width, 0);
p3 = new Cairo.PointD(Allocation.Width, Allocation.Height);
p4 = new Cairo.PointD(0, Allocation.Height);
cr.MoveTo(p1);
cr.LineTo(p2);
cr.LineTo(p3);
cr.LineTo(p4);
cr.LineTo(p1);
cr.ClosePath();
cr.Restore();
#pragma warning disable CS0618 // Type or member is obsolete
cr.Color = _clearColor;
#pragma warning restore CS0618 // Type or member is obsolete
cr.FillPreserve();
cr.SetSourceColor(_clearColor);
area.ModifyBg(StateType.Normal, new Gdk.Color((byte)_clearColor.R, (byte)_clearColor.G, (byte)_clearColor.B));
Gtk2Backend.BeginDraw((uint)Allocation.Width, (uint)Allocation.Height);
Microsoft.Xna.Framework.Color MgClearColor = new Microsoft.Xna.Framework.Color((float)_clearColor.R, (float)_clearColor.G, (float)_clearColor.B, (float)_clearColor.B);
Gtk2Backend.GraphicsDevice.Clear(MgClearColor);
Gtk2Backend.GraphicsDevice.Viewport = _view;
Render -= OnRender;
Gtk2Backend.EndDraw();
cr.GetTarget().Dispose();
}
protected virtual void OnRender(object sender, EventArgs e)
{
}
}
}
I tried like example of RB
But it doesn’t see MonoGame embedding Gtk Sharp 2.x
I already tried texture and font . No showing. What do I miss? Do you think I need replace Bitmap and BitmapData from GraphicsDevice.GetBackBufferData(pixelData);
?