BlizzCrafter / MonoGame.Forms

MonoGame.Forms is the easiest way of integrating a MonoGame render window into your Windows Forms project. It should make your life much easier, when you want to create your own editor environment.
Other
287 stars 28 forks source link

TextureBox? #17

Closed Shadowblitz16 closed 4 years ago

Shadowblitz16 commented 5 years ago

is it possible to make a monogame texturebox control? I tried to derive from DrawWindow and implement my wrapper class...

    [Serializable]
    public class Img : IDrawable
    {
        Texture2D Texture;

        public event EventHandler<EventArgs> DrawOrderChanged;
        public event EventHandler<EventArgs> VisibleChanged;

        public int W { get; set; }
        public int H { get; set; }

        public int DrawOrder => 0;

        public bool Visible => true;

        internal Img()
        {
            Texture = new Texture2D(Sys.Content.GetGraphicsDevice(), 8, 8);
            W = Texture.Width;
            H = Texture.Height;
        }
        internal Img(string filename)
        {
            FileStream stream = File.Open(filename, FileMode.Open);
            Texture = Texture2D.FromStream(Sys.Content.GetGraphicsDevice(), stream);
            W = Texture.Width;
            H = Texture.Height;
            stream.Dispose();

        }
        internal Img(int w, int h)
        {
            Texture = new Texture2D(Sys.Content.GetGraphicsDevice(), W, H);
            W = Texture.Width;
            H = Texture.Height;
        }

        public static implicit operator Img(Texture2D tex)
        {
            var img = new Img();
            img.Texture = tex;
            return img;
        }
        public static implicit operator Texture2D(Img img)
        {
            return img.Texture;
        }

        public void Draw(GameTime gameTime)
        {
            Gfx.Draw(this, 0, 0, 0, 0, W, H, 0);
        }
    }

however when using a ImageConverter attribute it makes the Img property unable to load a image.

using PureFramework.Library;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PureEditor.Controls
{
    public class TextureBox : MonoGame.Forms.Controls.DrawWindow
    {
        public TextureBox()
        {
        }

        [TypeConverter(typeof(ImageConverter))]
        public Img Img { get; set; }

    }
}

image

is there a way around this?

BlizzCrafter commented 5 years ago

Can you please elaborate a bit more what exactly you are trying to achieve?

Do you want to draw a Texture2D to a MonoGame.Forms control? Do you want to convert a System.Drawing.Image to a Texture2D?

What result are you expecting?

Shadowblitz16 commented 5 years ago

I basically want a picturebox but for monogame's Texture2D

BlizzCrafter commented 5 years ago

Take a look at these lines:

https://github.com/sqrMin1/MonoGame.Forms/blob/master/MonoGame.Forms.GL/SwapChainRenderTarget.GL.cs#L67-#L85

They are converting the back buffer of the GraphicsDecvice to a regular Bitmap. This Bitmap can then be drawn to a PictureBox.

Shadowblitz16 commented 5 years ago

how would one convert the data back to the texture2d once it's edited? I am trying to make a tileset editor in which I can edit colors of a texture2d

BlizzCrafter commented 5 years ago

You could try this from stackoverflow: https://stackoverflow.com/a/2870399

Another option would be to create a more "native" way by creating an array of colors and manipulating each pixel with the mouse cursor.

After that you simply create a new Texture2D with that modified color array.

Something like this:

1. Color[] tcolor=new Color[texture.Width * texture.Height]; texture.GetData(tcolor);

2. modify color array

3. texture.SetData(tcolor);

Shadowblitz16 commented 5 years ago

@sqrMin1 so is there a way for the winforms designer to treat my wrapper image class as a system.drawing.bitmap? that was the original issue.

BlizzCrafter commented 5 years ago

No, in the moment the library is not capable of implicity convert Texture2Ds into Bitmaps and vice versa.

Shadowblitz16 commented 5 years ago

is there a way to allow the texture to be loaded or set in the winforms designer at all? or is this just not possible altogether?

BlizzCrafter commented 5 years ago

It's possible to draw an Image in the control during design-time: https://github.com/sqrMin1/MonoGame.Forms/blob/master/MonoGame.Forms.DX/Controls/GraphicsDeviceControl.cs#L405

We are using this technique to draw the MonoGame logo when a MonoGameControl was placed.

Other than this you can't directly set a Texture2D and let this draw to the control during design-time.

trigger-segfault commented 5 years ago

As a suggestion to Shadowblitz16, you could give your control design-time properties where it will display a System.Drawing.Bitmap instead of a Microsoft.Xna.Framework.Graphics.Texture2D. It is 100% possible to load an .xnb Texture2D file and convert it to a Bitmap without using the GraphicsDevice.

You can find information about reading an XNA/MonoGame texture resource from repositories like TExtract (in Java), or TConvert (C# port of TExtract). The XnbExtractor handles the major functionality, but you'll also need the LzxDecoder (and friends) in the same folder which is used to decompress certain files. (Compression is not mandatory for .xnb files.)

Shadowblitz16 commented 5 years ago

@sqrMin1 the issue is not drawing the image to the picturebox, its allowing the property inspector to set, get and create a new Texture2D like what it allows for a bitmap.

I don't necessarily need it to be converted to a bitmap. just the inspector to treat it as one.

@trigger-segfault that would be cool I might look into it later.