Sign in to follow this  
BoltBait

Fire Plugin

Recommended Posts

For info see this post: Tom Jackson's Excellent Fire Tutorial

Simon Brown has created a similar plugin here. Mine is different.

For my plugin, the user (that's you) will need to draw a black to white gradient in the general shape you want the flames before running the effect.

Download here: http://forums.getpaint.net/index.php?/topic/8318-

How to install plugins: http://boltbait.googlepages.com/install

If that doesn't work, post your troubles here:

Burninate.png

This plugin shows up under the Effects > Distort menu as "Burninate". I believe Trogdor would approve.

Source code here:

using System;
using System.Text;
using System.Reflection;
using PaintDotNet;
using PaintDotNet.Effects;
using PaintDotNet.IndirectUI;
using PaintDotNet.PropertySystem;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("BurninatePlugin")]
[assembly: AssemblyDescription("Burninate Plugin for Paint.NET. Based on Tom Jackson's excellent Fire Tutorial.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BoltBait")]
[assembly: AssemblyProduct("BurninatePlugin")]
[assembly: AssemblyCopyright("Copyright © BoltBait")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.*")]

namespace BurninateEffect
{
   public class PluginSupportInfo : IPluginSupportInfo
   {
       public string Author
       {
           get
           {
               return "BoltBait";
           }
       }
       public string Copyright
       {
           get
           {
               return ((AssemblyCopyrightAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false)[0]).Copyright;
           }
       }

       public string DisplayName
       {
           get
           {
               return ((AssemblyProductAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0]).Product;
           }
       }

       public Version Version
       {
           get
           {
               return base.GetType().Assembly.GetName().Version;
           }
       }

       public Uri WebsiteUri
       {
           get
           {
               return new Uri("http://www.BoltBait.com/pdn");
           }
       }
   }

   [PluginSupportInfo(typeof(PluginSupportInfo), DisplayName = "Burninate")]
   public class BurninateEffectPlugin : PropertyBasedEffect
   {
       public static string StaticName
       {
           get
           {
               return "Burninate";
           }
       }

       public static Image StaticIcon
       {
           get
           {
               return new Bitmap(typeof(BurninateEffectPlugin), "burninate.png");
           }
       }

       public BurninateEffectPlugin()
           : base(StaticName, StaticIcon, SubmenuNames.Distort, EffectFlags.Configurable)
       {
       }

       public enum PropertyNames
       {
           Amount1,
           Amount2,
           Amount3,
           Amount4
       }

       protected override PropertyCollection OnCreatePropertyCollection()
       {
           List<Property> props = new List<Property>();

           props.Add(new Int32Property(PropertyNames.Amount1, 100, 2, 1000));
           props.Add(new DoubleProperty(PropertyNames.Amount2, 0.5, 0, 1));
           props.Add(new BooleanProperty(PropertyNames.Amount4, false));
           props.Add(new Int32Property(PropertyNames.Amount3, 0, 0, 255));

           return new PropertyCollection(props);
       }

       protected override ControlInfo OnCreateConfigUI(PropertyCollection props)
       {
           ControlInfo configUI = CreateDefaultConfigUI(props);

           configUI.SetPropertyControlValue(PropertyNames.Amount1, ControlInfoPropertyNames.DisplayName, "Scale");
           configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.DisplayName, "Roughness");
           configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.SliderLargeChange, 0.25);
           configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.SliderSmallChange, 0.05);
           configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.UpDownIncrement, 0.01);
           configUI.SetPropertyControlValue(PropertyNames.Amount4, ControlInfoPropertyNames.DisplayName, string.Empty);
           configUI.SetPropertyControlValue(PropertyNames.Amount4, ControlInfoPropertyNames.Description, "Black and White");
           configUI.SetPropertyControlValue(PropertyNames.Amount3, ControlInfoPropertyNames.DisplayName, string.Empty);
           configUI.SetPropertyControlType(PropertyNames.Amount3, PropertyControlType.IncrementButton);
           configUI.SetPropertyControlValue(PropertyNames.Amount3, ControlInfoPropertyNames.ButtonText, "Randomize");
           configUI.SetPropertyControlValue(PropertyNames.Amount3, ControlInfoPropertyNames.Description, "HINT: Start by drawing a gradient from black to white before running this effect. Try different gradient shapes to vary the flames.");

           return configUI;
       }

       protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs)
       {
           this.Amount1 = newToken.GetProperty<Int32Property>(PropertyNames.Amount1).Value;
           this.Amount2 = newToken.GetProperty<DoubleProperty>(PropertyNames.Amount2).Value;
           this.Amount3 = newToken.GetProperty<Int32Property>(PropertyNames.Amount3).Value;
           this.Amount4 = newToken.GetProperty<BooleanProperty>(PropertyNames.Amount4).Value;

           // setup for calling the clouds effect
           cloudsProps = cloudsEffect.CreatePropertyCollection();
           PropertyBasedEffectConfigToken CloudsParameters = new PropertyBasedEffectConfigToken(cloudsProps);
           CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Scale, Amount1);
           CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Power, Amount2);
           CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.BlendOp, normalOp);
           CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Seed, Amount3);
           cloudsEffect.SetRenderInfo(CloudsParameters, dstArgs, srcArgs);

           base.OnSetRenderInfo(newToken, dstArgs, srcArgs);
       }

       protected override unsafe void OnRender(Rectangle[] rois, int startIndex, int length)
       {
           if (length == 0) return;
           for (int i = startIndex; i < startIndex + length; ++i)
           {
               Render(DstArgs.Surface, SrcArgs.Surface, rois[i]);
           }
       }

       protected override void OnCustomizeConfigUIWindowProperties(PropertyCollection props)
       {
           // Change the effect's window title
           props[ControlInfoPropertyNames.WindowTitle].Value = "BoltBait's Fire Effect v1.0";
           base.OnCustomizeConfigUIWindowProperties(props);
       }

       int Amount1 = 100; // [2,1000] Scale
       double Amount2 = 0.5; // [0,1] Roughness
       int Amount3 = 0; // [255] Reseed
       bool Amount4 = false; // Black and White

       // Setup for calling the Render Clouds effect
       private CloudsEffect cloudsEffect = new CloudsEffect();
       private PropertyCollection cloudsProps;

       // Setup for using Desaturate pixel op
       private UnaryPixelOps.Desaturate desaturateOp = new UnaryPixelOps.Desaturate();

       // Setup for using various blend ops
       private UserBlendOps.OverlayBlendOp overlayOp = new UserBlendOps.OverlayBlendOp();
       private UserBlendOp normalOp = new UserBlendOps.NormalBlendOp(); // Blend Mode

       unsafe void Render(Surface dst, Surface src, Rectangle rect)
       {
           // Call the Render Clouds function
           cloudsEffect.Render(new Rectangle[1] { rect }, 0, 1);
           // Now in the main render loop, the dst canvas has a render of clouds

           for (int y = rect.Top; y < rect.Bottom; y++)
           {
               ColorBgra* srcPtr = src.GetPointAddressUnchecked(rect.Left, y);
               ColorBgra* dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
               for (int x = rect.Left; x < rect.Right; x++)
               {
                   ColorBgra CurrentPixel = *srcPtr;

                   // Make the source layer black and white
                   CurrentPixel = desaturateOp.Apply(CurrentPixel);
                   // Mix it with the clouds layer to create flames
                   CurrentPixel = overlayOp.Apply(CurrentPixel, *dstPtr);
                   // Now, make the curves adjustment to give the flames color
                   if (!Amount4)
                   {
                       CurrentPixel.G = Utility.ClampToByte((CurrentPixel.G - 140) * 2.2173);
                       CurrentPixel.B = Utility.ClampToByte((CurrentPixel.G - 204) * 5);
                   }

                   *dstPtr = CurrentPixel;
                   srcPtr++;
                   dstPtr++;
               }
           }
       }
   }
}

Note: This is NOT a CodeLab script. VS 2005+ is required to compile.

Enjoy. B):beer:

Share this post


Link to post
Share on other sites

Simon, I named the thread 'Fire' so that when people search for 'Fire' they'll find it. Everything else is named 'Burninate' including the DLL file itself.

And, if anyone is going to confuse the user, Simon, your plugin sits right next to Tom Jackson's in the Render menu and has the same name.

Share this post


Link to post
Share on other sites

BoltBait, could you move it to Stylize? I think that would fit more (which user expects fire in the distort menu?) and if you use most of the plugins available, your distort menu is rather overcrowded. Stylize has way fewer entries. Please... :o

Share this post


Link to post
Share on other sites
BoltBait, could you move it to Stylize? I think that would fit more (which user expects fire in the distort menu?) and if you use most of the plugins available, your distort menu is rather overcrowded. Stylize has way fewer entries. Please... :o

I really just made this plugin as an exercise in writing complex effects. I really don't expect anyone to use it.

If you want a fire effect, download Tom Jackson's instead of mine. His is much better: viewtopic.php?f=16&t=25180

Share this post


Link to post
Share on other sites

You can call your version "Flames"

Besides, your version is different than Tom's version.

I like em both :)

Share this post


Link to post
Share on other sites
If you want a fire effect, download Tom Jackson's instead of mine. His is much better.

But yours is more fun.

I think it could be good for doing textures and such IMO.

This is done with 11 layers of differently drawn black and white gradients.

Each layer blending mode was set to difference.

The Burninate plug-in was used on the last layer (last gradient).

texture2550x413nt3.png

Share this post


Link to post
Share on other sites

another way to make fire is to gradient then cloud until you see a fire shape then go to the color lines select RGB uncheck red and green move the blue line to the lower right corner then uncheck blue then check green and move it one square to the left or one square left and up and you have fire

Share this post


Link to post
Share on other sites

BoltBait,

why in line

 

CurrentPixel.B = Utility.ClampToByte((CurrentPixel.G - 204) * 5);

 

for CurrentPixel.B was applied a component G (CurrentPixel.G - 204)?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this