[Gtk-sharp-list] Rendering monogame in GTK

jbg77 jbgaume at gmail.com
Tue Aug 14 09:18:59 UTC 2012


I make a game engine and I would like to make a map editor. I found a very
good code. But I do not know how to display a WriteableBitmap or other in an
image or Gdk.Pixbuf.

I tried it :
Gdk.Pixbuf pixBuf = new Gdk.Pixbuf(game.m_bytes);

But I get this error :
GLib.GException: Image has zero width ---> System.Exception: 
  --- End of inner exception stack trace ---
  à Gdk.PixbufLoader.Write(Byte[] buf, UInt64 count)
  à Gdk.PixbufLoader.Write(Byte[] bytes, UInt32 count)
  à Gdk.PixbufLoader.InitFromBuffer(Byte[] buffer)
  à Gdk.PixbufLoader..ctor(Byte[] buffer)
  à Gdk.Pixbuf..ctor(Byte[] buffer)

Game code:
using System;
using System.Runtime.InteropServices;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace MonoGameInGtk
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        // Objet qui sera transmis au WPF
        public WriteableBitmap WriteableBitmap { get; set; }

        // A de multiple endroit nous avons besoin de savoir la taille de
l'affichage XNA
        private Point m_sizeViewport;
        // Objet qui contiendra notre scène après le rendu
        private RenderTarget2D m_renderTarget2D;
        // Servira pour faire la conversion du RenderTarget vers le
WritableBitmap
        public byte[] m_bytes;
        // Les fonctionnements interne de XNA étant bypassés, il faut un
timer
        private DispatcherTimer m_dispatcherTimer;

        private GraphicsDeviceManager m_graphics;
        private SpriteBatch m_spriteBatch;

        public Game1()
        {
            m_graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // On prepare la resolution du rendu, l'image de sorti, l'image
en entré, les bytes pour la conversion
            m_sizeViewport = new Point(200, 200);
            WriteableBitmap = new WriteableBitmap(m_sizeViewport.X,
m_sizeViewport.Y, 96, 96, PixelFormats.Bgra32, null);
            m_bytes = new byte[m_sizeViewport.X * m_sizeViewport.Y * 4];

            // On prepare le timer pour tourner 60 fois par seconde
            m_dispatcherTimer = new DispatcherTimer();
            m_dispatcherTimer.Interval = TimeSpan.FromSeconds(1 / 60);
            m_dispatcherTimer.Tick += new EventHandler(GameLoop);

            this.Initialize();
            this.LoadContent();
            m_dispatcherTimer.Start();
        }

        protected override void Initialize()
        {
            // Les fonctionnements interne de XNA étant bypassés , il faut
forcer la création du GraphicsDevice
            IGraphicsDeviceManager graphicsDeviceManager =
this.Services.GetService(typeof(IGraphicsDeviceManager)) as
IGraphicsDeviceManager;
            if (graphicsDeviceManager != null)
graphicsDeviceManager.CreateDevice();
            else throw new Exception("Unable to retrieve
GraphicsDeviceManager");

            // Le renderTarget2D ne peut être créé qu'après la création du
GraphicsDevice, puisqu'il l'utilise.
            m_renderTarget2D = new RenderTarget2D(GraphicsDevice,
m_sizeViewport.X, m_sizeViewport.Y);
            IsMouseVisible = true;
            base.Initialize();
        }

        protected override void LoadContent()
        {
            m_spriteBatch = new SpriteBatch(GraphicsDevice);


            base.LoadContent();
        }

        protected override void Draw(GameTime gameTime)
        {
            // Au lieu de rendre dans une fenêtre classique, XNA nous permet
de rendre la scene dans un RenderTarget2D. On le set donc.
            GraphicsDevice.SetRenderTarget(m_renderTarget2D);
           
GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.CornflowerBlue);

            m_spriteBatch.Begin();

            m_spriteBatch.End();
            base.Draw(gameTime);

            // Ne pas oublier ! Sinon une exception sera levée
            GraphicsDevice.SetRenderTarget(null);

            // On récupère les informations de l'image source
            m_renderTarget2D.GetData(m_bytes);

            // Parce que le seul format de pixel 32 bit pour WPF est BGRA et
que XNA est en RGBA, il faut intervertir la composante R et B pour tout les
pixels
            for (int i = 0; i < m_bytes.Length - 2; i += 4)
            {
                byte r = m_bytes[i];
                m_bytes[i] = m_bytes[i + 2];
                m_bytes[i + 2] = r;
            }

            // On écrit dans le WriteableBitmap les pixels résultant de la
conversion
            WriteableBitmap.Lock();
            Marshal.Copy(m_bytes, 0, WriteableBitmap.BackBuffer,
m_bytes.Length);
            WriteableBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0,
m_sizeViewport.X, m_sizeViewport.Y));
            WriteableBitmap.Unlock();
        }

        private void GameLoop(object sender, EventArgs e)
        {
            GameTime gameTime = new GameTime();

            this.Update(gameTime);
            this.Draw(gameTime);
        }
    }
}




--
View this message in context: http://mono.1490590.n4.nabble.com/Rendering-monogame-in-GTK-tp4652000.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.


More information about the Gtk-sharp-list mailing list