コード例 #1
0
 //Gradients
 private void gradientNameBox_KeyDown(object sender, KeyEventArgs e)
 {
     if (e.KeyCode == Keys.Return)
     {
         if (!Document.ContainsGradient(gradientNameBox.Text))
         {
             PhotonGradient pg = new PhotonGradient(PhotonInterpolationMode.Linear);
             pg.Add(new Photon(0, 0, 0), 0);
             pg.Add(new Photon(1, 1, 1), 1);
             GradientDialog gd = new GradientDialog(pg);
             if (gd.ShowDialog() == DialogResult.OK)
             {
                 if (Document.SetGradient(gradientNameBox.Text, pg))
                 {
                     Document.SelectedGradientName = gradientNameBox.Text;
                 }
             }
         }
         else
         {
             Document.SelectedGradientName = gradientNameBox.Text;
         }
         e.SuppressKeyPress = true;
     }
 }
コード例 #2
0
ファイル: GradientDialog.cs プロジェクト: liujb0319/Fountain
 private void Document_GradientRemoved(string name, PhotonGradient gradient)
 {
     if (name == gradientName)
     {
         Close();
     }
 }
コード例 #3
0
ファイル: GradientDialog.cs プロジェクト: pyxoraptor/Fountain
 public GradientDialog(PhotonGradient gradient)
 {
     CenterToParent();
     InitializeComponent();
     gradientTypeBox.DataSource = Enum.GetValues(typeof(PhotonInterpolationMode));
     Gradient = gradient;
 }
コード例 #4
0
ファイル: GradientDialog.cs プロジェクト: liujb0319/Fountain
        private void gradientBox_MouseClick(object sender, MouseEventArgs e)
        {
            PhotonGradient gradient = gradientBox.Gradient;

            float u = (float)e.X / gradientBox.Width * gradient.Length + gradient.Start;
            int   i = gradient.ClosestIndex(u);

            if (e.Button == MouseButtons.Left)
            {
                PhotonGradient.PhotonPosition pp = gradient[i];
                if (ModifierKeys == Keys.Control)
                {
                    pp.Photon   = gradient[u];
                    pp.Position = u;
                    gradient.Add(pp);
                    gradientBox.UpdateRender();
                }
                else
                {
                    PhotonDialog photonDialog = new PhotonDialog(this);
                    photonDialog.Photon = pp.Photon;
                    if (photonDialog.ShowDialog() == DialogResult.OK)
                    {
                        pp.Photon   = photonDialog.Photon;
                        gradient[i] = pp;
                        gradientBox.UpdateRender();
                    }
                }
            }
            else if (e.Button == MouseButtons.Right && i > 0 && i < gradient.PhotonPositionCount - 1)
            {
                gradient.Remove(i);
                gradientBox.UpdateRender();
            }
        }
コード例 #5
0
        public void UpdateArea(int x, int y, int width, int height, PhotonGradient gradient, IEnumerable <Effect> effects)
        {
            if (gradient == null)
            {
                gradient = new PhotonGradient(PhotonInterpolationMode.Linear);
                gradient.Add(new Photon(0.0f, 0.0f, 0.0f), heightField.ClampMin);
                gradient.Add(new Photon(1.0f, 1.0f, 1.0f), heightField.ClampMax);
            }
            if (x >= 0 && width > 0 && x + width <= Width && y >= 0 && height > 0 && y + height <= Height)
            {
                BitmapData data = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                try
                {
                    unsafe
                    {
                        byte *start = (byte *)data.Scan0.ToPointer();
                        for (int _x = x; _x < x + width; _x++)
                        {
                            for (int _y = y; _y < y + height; _y++)
                            {
                                Photon p = gradient[heightField[_x, _y]];

                                if (effects != null)
                                {
                                    foreach (Effect e in effects)
                                    {
                                        if (e != null)
                                        {
                                            p = e(_x, _y, p, heightField);
                                        }
                                    }
                                }

                                byte *pix = start + _y * Width * 4 + _x * 4;
                                *     pix = p.b;
                                pix++;
                                *pix = p.g;
                                pix++;
                                *pix = p.r;
                                pix++;
                                *pix = p.a;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
                finally
                {
                    bitmap.UnlockBits(data);
                }
            }
            else
            {
                throw new Exception("The supplied region did not lie within the height render.");
            }
        }
コード例 #6
0
 private void Document_GradientSet(string name, PhotonGradient gradient)
 {
     gradientNameBox.Items.Clear();
     foreach (string s in Document.GradientNames)
     {
         gradientNameBox.Items.Add(s);
     }
 }
コード例 #7
0
 private void editGradientToolStripMenuItem_Click(object sender, EventArgs e)
 {
     if (Document.ContainsGradient(gradientNameBox.Text))
     {
         PhotonGradient copy = Document.GetGradient(gradientNameBox.Text).MakeCopy();
         GradientDialog gd   = new GradientDialog(gradientNameBox.Text, this);
         gd.Show();
     }
 }
コード例 #8
0
 private void Document_GradientSet(string name, PhotonGradient gradient)
 {
     selectedGradientBox.Items.Clear();
     foreach (string s in Document.GradientNames)
     {
         selectedGradientBox.Items.Add(s);
     }
     selectedGradientBox.Text = Document.SelectedGradientName;
 }
コード例 #9
0
ファイル: Document.cs プロジェクト: liujb0319/Fountain
 private static void SaveGradient(Stream stream, PhotonGradient gradient)
 {
     stream.Write(BitConverter.GetBytes(gradient.PhotonPositionCount), 0, sizeof(int));
     stream.Write(BitConverter.GetBytes((int)gradient.Mode), 0, sizeof(int));
     for (int i = 0; i < gradient.PhotonPositionCount; i++)
     {
         stream.Write(gradient[i].Photon, 0, sizeof(byte) * 4);
         stream.Write(BitConverter.GetBytes(gradient[i].Position), 0, sizeof(float));
     }
 }
コード例 #10
0
 private void Document_GradientRemoved(string name, PhotonGradient gradient)
 {
     gradientNameBox.Items.Clear();
     selectedGradientBox.Items.Clear();
     foreach (string s in Document.GradientNames)
     {
         gradientNameBox.Items.Add(s);
         selectedGradientBox.Items.Add(s);
     }
     selectedGradientBox.SelectedItem = Document.SelectedGradient;
 }
コード例 #11
0
 private void Redo()
 {
     if (redoQueue.Count > 0)
     {
         BrushAction redoAction = redoQueue.Dequeue();
         //Set all of the values in the affected area to what they were before the undo action took place.
         HeightRender render   = Document.SelectedRender;
         BrushAction  opposite = new BrushAction(redoAction.Selection, redoAction.Data);
         for (int x = redoAction.Selection.Left; x < redoAction.Selection.Right; x++)
         {
             for (int y = redoAction.Selection.Top; y < redoAction.Selection.Bottom; y++)
             {
                 float oldSample;
                 if (render.HeightField.TryGetHeight(x, y, out oldSample))
                 {
                     int i = (y - redoAction.Selection.Top) * redoAction.Selection.Width + (x - redoAction.Selection.Left);
                     render.HeightField[x, y] = redoAction.Data[i];
                     opposite.Data[i]         = oldSample;
                 }
             }
         }
         PhotonGradient gradient = Document.SelectedGradient;
         IEnumerable <HeightRender.Effect> effects;
         if (paintEffectsBox.Checked)
         {
             effects = Document.SelectedEffects;
         }
         else
         {
             effects = null;                 //Don't worry about effects if we're not painting with them.
         }
         //Update each section of the selection when wrapping has been accounted for.
         foreach (FieldSelection fs in redoAction.Selection.SubSelectionsOf(render.HeightField))
         {
             //Omit any parts that have a width or height of zero.
             if (!fs.IsEmpty)
             {
                 //Update the corresponding part of the render.
                 render.UpdateArea(fs.Left, fs.Top, fs.Width, fs.Height, gradient, effects);
                 //Invalidate the corresponding part of the image panel so that it redraws itself in realtime.
                 Point start = Numerics.ToPoint(renderArea.ImageToClient(new Vector2(fs.Left, fs.Top)));
                 Point end   = Numerics.ToPoint(renderArea.ImageToClient(new Vector2(fs.Right, fs.Bottom)));
                 renderArea.Invalidate(new Rectangle(Numerics.Max(start.X, 0), Numerics.Max(start.Y, 0), Numerics.Max(end.X, 0), Numerics.Max(end.Y, 0)));
             }
         }
         undoQueue.Enqueue(opposite);
     }
 }
コード例 #12
0
ファイル: Document.cs プロジェクト: liujb0319/Fountain
 //Setting
 public static bool SetGradient(string name, PhotonGradient gradient)
 {
     if (name != null && name.Length > 0)
     {
         gradients[name] = gradient;
         if (gradientSet != null)
         {
             gradientSet(name, gradient);
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }
コード例 #13
0
 private void editGradientToolStripMenuItem_Click(object sender, EventArgs e)
 {
     if (Document.SelectedGradient != null)
     {
         PhotonGradient fallback = Document.SelectedGradient.MakeCopy();
         GradientDialog gd       = new GradientDialog(Document.SelectedGradientName, this);
         if (gd.ShowDialog() == DialogResult.OK && Document.SelectedRender != null)
         {
             Document.SelectedRender.UpdateAll(Document.SelectedGradient, Document.SelectedEffects);
             renderArea.Invalidate();
         }
         else
         {
             Document.SetGradient(Document.SelectedGradientName, fallback);
         }
     }
 }
コード例 #14
0
ファイル: GradientDialog.cs プロジェクト: liujb0319/Fountain
        private void gradientBox_MouseMove(object sender, MouseEventArgs e)
        {
            PhotonGradient gradient = gradientBox.Gradient;

            float u = (float)e.X / gradientBox.Width * gradient.Length + gradient.Start;
            int   i = gradient.ClosestIndex(u);

            if (e.Button == MouseButtons.Middle && i > 0 && i < gradient.PhotonPositionCount - 1)
            {
                PhotonGradient.PhotonPosition pp = gradient[i];
                if (ModifierKeys == Keys.Shift)
                {
                    pp.Position = (float)(int)(Math.Round(u * gradientRuler.Segments)) / gradientRuler.Segments;
                }
                else
                {
                    pp.Position = u;
                }
                gradient[i] = pp;
                gradientBox.UpdateRender();
            }
        }
コード例 #15
0
ファイル: Document.cs プロジェクト: liujb0319/Fountain
        private static PhotonGradient LoadGradient(Stream stream)
        {
            byte[] buffer = new byte[4];

            stream.Read(buffer, 0, sizeof(int));
            int count = BitConverter.ToInt32(buffer, 0);

            stream.Read(buffer, 0, sizeof(int));
            PhotonInterpolationMode mode = (PhotonInterpolationMode)BitConverter.ToInt32(buffer, 0);

            PhotonGradient gradient = new PhotonGradient(mode);

            for (int i = 0; i < count; i++)
            {
                stream.Read(buffer, 0, sizeof(byte) * 4);
                Photon p = buffer;
                stream.Read(buffer, 0, sizeof(float));
                float f = BitConverter.ToSingle(buffer, 0);
                gradient.Add(p, f);
            }

            return(gradient);
        }
コード例 #16
0
ファイル: GradientDialog.cs プロジェクト: liujb0319/Fountain
        public GradientDialog(string gradientName, Form owner)
        {
            Owner = owner;
            if (gradientName != null && gradientName.Length > 0)
            {
                CenterToParent();
                InitializeComponent();
                gradientTypeBox.DataSource = Enum.GetValues(typeof(PhotonInterpolationMode));

                if (Document.ContainsGradient(this.gradientName = gradientName))
                {
                    gradientBox.Gradient = Document.GetGradient(gradientName);
                }
                else
                {
                    PhotonGradient pg = new PhotonGradient(PhotonInterpolationMode.Linear);
                    pg.Add(new Photon(0.0f, 0.0f, 0.0f), 0.0f);
                    pg.Add(new Photon(1.0f, 1.0f, 1.0f), 1.0f);
                    Document.SetGradient(gradientName, gradientBox.Gradient = pg);
                }

                copy = gradientBox.Gradient.MakeCopy();

                gradientTypeBox.SelectedItem = gradientBox.Gradient.Mode;
                minBox.Value = (decimal)gradientBox.Gradient.Start;
                maxBox.Value = (decimal)(gradientBox.Gradient.Length - gradientBox.Gradient.Start);

                Document.Cleared         += Document_Cleared;
                Document.Loaded          += Document_Loaded;
                Document.GradientRemoved += Document_GradientRemoved;
            }
            else
            {
                throw new Exception("The supplied name was empty or null.");
            }
        }
コード例 #17
0
 public void UpdateAll(PhotonGradient gradient, IEnumerable <Effect> effects)
 {
     UpdateArea(0, 0, Width, Height, gradient, effects);
 }
コード例 #18
0
ファイル: Document.cs プロジェクト: liujb0319/Fountain
        //Loading
        public static IOEvaluation Load(string path)
        {
            Clear();
            if (File.Exists(path))
            {
                FileStream stream = null;
                try
                {
                    stream = new FileStream(path, FileMode.Open);
                }
                catch
                {
                    return(IOEvaluation.CannotOpenStream);
                }
                try
                {
                    IOBlockIdentifier block;
                    string            blockName;
                    byte[]            blockBuff = new byte[sizeof(int)];
                    stream.Read(blockBuff, 0, sizeof(int));
                    block = (IOBlockIdentifier)BitConverter.ToInt32(blockBuff, 0);
                    if (block == IOBlockIdentifier.FileBegin)
                    {
                        do
                        {
                            if (stream.Position < stream.Length)
                            {
                                stream.Read(blockBuff, 0, sizeof(int));
                                block = (IOBlockIdentifier)BitConverter.ToInt32(blockBuff, 0);
                                switch (block)
                                {
                                case IOBlockIdentifier.FileEnd:
                                    break;

                                case IOBlockIdentifier.Brush:
                                    blockName = LoadText(stream);
                                    BrushScript bs = LoadBrush(stream);
                                    SetBrush(blockName, bs.brush, bs.script);
                                    break;

                                case IOBlockIdentifier.Effect:
                                    blockName = LoadText(stream);
                                    EffectScript es = LoadEffect(stream);
                                    SetEffect(blockName, es.effect, es.script);
                                    break;

                                case IOBlockIdentifier.Gradient:
                                    blockName = LoadText(stream);
                                    PhotonGradient gradient = LoadGradient(stream);
                                    SetGradient(blockName, gradient);
                                    break;

                                case IOBlockIdentifier.Render:
                                    blockName = LoadText(stream);
                                    HeightRender render = LoadRender(stream);
                                    SetRender(blockName, render);
                                    break;

                                case IOBlockIdentifier.Generator:
                                    blockName = LoadText(stream);
                                    GeneratorScript gs = LoadGenerator(stream);
                                    SetGenerator(blockName, gs.generator, gs.script);
                                    break;

                                default:
                                    throw new Exception("Encountered a block that couldn't be identified.");
                                }
                            }
                            else
                            {
                                throw new Exception("The end of the file was reached before the appropriate 'End of File' flag was found.");
                            }
                        }while (block != IOBlockIdentifier.FileEnd);
                        //Path and Callback
                        associatedPath = path;
                        if (loaded != null)
                        {
                            loaded(path);
                        }
                        return(IOEvaluation.Success);
                    }
                    else
                    {
                        return(IOEvaluation.ConversionError);
                    }
                }
                catch
                {
                    Clear();
                    return(IOEvaluation.ConversionError);
                }
                finally
                {
                    stream.Close();
                }
            }
            else
            {
                associatedPath = path;
                return(IOEvaluation.FileDoesNotExist);
            }
        }
コード例 #19
0
ファイル: Document.cs プロジェクト: pyxoraptor/Fountain
 //Loading
 public static bool Load(string path)
 {
     Clear();
     if (File.Exists(path))
     {
         FileStream stream = new FileStream(path, FileMode.Open);
         try
         {
             byte[] countBuf = new byte[4];
             int    count;
             //Load Renders
             stream.Read(countBuf, 0, sizeof(int));
             count = BitConverter.ToInt32(countBuf, 0);
             for (int i = 0; i < count; i++)
             {
                 string       name   = LoadText(stream);
                 HeightRender render = LoadRender(stream);
                 SetRender(name, render);
             }
             //Load Gradients
             stream.Read(countBuf, 0, sizeof(int));
             count = BitConverter.ToInt32(countBuf, 0);
             for (int i = 0; i < count; i++)
             {
                 string         name     = LoadText(stream);
                 PhotonGradient gradient = LoadGradient(stream);
                 SetGradient(name, gradient);
             }
             //Load Effects
             stream.Read(countBuf, 0, sizeof(int));
             count = BitConverter.ToInt32(countBuf, 0);
             for (int i = 0; i < count; i++)
             {
                 string       name = LoadText(stream);
                 EffectScript es   = LoadEffect(stream);
                 SetEffect(name, es.effect, es.script);
             }
             //Load Brushes
             stream.Read(countBuf, 0, sizeof(int));
             count = BitConverter.ToInt32(countBuf, 0);
             for (int i = 0; i < count; i++)
             {
                 string      name = LoadText(stream);
                 BrushScript bs   = LoadBrush(stream);
                 SetBrush(name, bs.brush, bs.script);
             }
             //Path and Callback
             associatedPath = path;
             if (loaded != null)
             {
                 loaded(path);
             }
             return(true);
         }
         catch
         {
             associatedPath = null;
             return(false);
         }
         finally
         {
             stream.Close();
         }
     }
     else
     {
         associatedPath = path;
         return(false);
     }
 }
コード例 #20
0
        private void Application_Idle(object sender, EventArgs e)
        {
            Vector2 pointOnRenderArea = Numerics.ToVector(renderArea.PointToClient(Control.MousePosition));
            Vector2 pointOnRender     = renderArea.ClientToImage(pointOnRenderArea);

            if (renderArea.Focused && Document.SelectedRender != null)
            {
                #region Undo
                if (undoing)
                {
                    Undo();
                }
                #endregion
                #region Redo
                if (redoing)
                {
                    Redo();
                }
                #endregion
                #region Panning
                if (MouseButtons == MouseButtons.Middle)
                {
                    renderArea.ImageOffset += (pointOnRenderArea - lastPointOnRenderArea) / renderArea.ImageScale;
                }
                #endregion
                #region Brush
                //Select the appropriate brush based on the active mouse buttons.
                HeightBrush activeBrush = null;
                if (MouseButtons == MouseButtons.Left)
                {
                    activeBrush = Document.LeftBrush;
                }
                else if (MouseButtons == MouseButtons.Right)
                {
                    activeBrush = Document.RightBrush;
                }
                //If a mouse button was in use; paint.
                if (activeBrush != null)
                {
                    HeightRender   render   = Document.SelectedRender;
                    PhotonGradient gradient = Document.SelectedGradient;
                    IEnumerable <HeightRender.Effect> effects;
                    if (paintEffectsBox.Checked)
                    {
                        effects = Document.SelectedEffects;
                    }
                    else
                    {
                        effects = null;                     //If we aren't painting with effects then we don't care about supplying them to the update.
                    }
                    #region Process Steps
                    //The brush stroke is broken up into steps that are each a given length (in pixels). The length is denoted by the brush precision.
                    Vector2 brushDelta   = lastPointOnRender - pointOnRender;
                    float   strokeLength = (float)brushDelta.Length;
                    float   steps        = strokeLength / activeBrush.Precision + 1;
                    Vector2 brushStep    = brushDelta * (1.0f / steps);
                    for (int i = (int)steps - 1; i >= 0; i--)                    //Work backwards so the undo and redo functionality makes sense.
                    {
                        //Calculate the current brush position, based on the starting point, the step vector and the current step index.
                        Vector2 brushPosition = pointOnRender + brushStep * i;
                        #region Process Brush Paint
                        try
                        {
                            //Perform the actual brush operation and capture the selected area it affects.
                            FieldSelection brushArea;
                            float[]        previousData;
                            activeBrush.Paint(render.HeightField, (int)brushPosition.X, (int)brushPosition.Y, strokeLength, out brushArea, out previousData);
                            //Add this paint event to the undo queue.
                            undoQueue.Enqueue(new BrushAction(brushArea, previousData));
                            redoQueue.Clear();
                            //Break up the brush area into multiple parts if they intersect the edges of the image.
                            foreach (FieldSelection fs in brushArea.SubSelectionsOf(render.HeightField))
                            {
                                //Omit any parts that have a width or height of zero.
                                if (!fs.IsEmpty)
                                {
                                    //Update the corresponding part of the render.
                                    render.UpdateArea(fs.Left, fs.Top, fs.Width, fs.Height, gradient, effects);
                                    //Invalidate the corresponding part of the image panel so that it redraws itself in realtime.
                                    Point start = Numerics.ToPoint(renderArea.ImageToClient(new Vector2(fs.Left, fs.Top)));
                                    Point end   = Numerics.ToPoint(renderArea.ImageToClient(new Vector2(fs.Right, fs.Bottom)));
                                    renderArea.Invalidate(new Rectangle(Numerics.Max(start.X, 0), Numerics.Max(start.Y, 0), Numerics.Max(end.X, 0), Numerics.Max(end.Y, 0)));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            //This usually happens when activeBrush.Paint is called, because it executes the user's brush script. Shows the script error message as a message box.
                            MessageBox.Show(ex.Message, "There was a runtime error with your brush script.");
                        }
                        #endregion
                    }
                    #endregion
                }
                #endregion
            }
            else
            {
                undoing = redoing = false;
            }

            lastPointOnRenderArea = pointOnRenderArea;
            lastPointOnRender     = pointOnRender;
        }
コード例 #21
0
        private void Application_Idle(object sender, EventArgs e)
        {
            Vector2 pointOnRenderArea = Numerics.ToVector(renderArea.PointToClient(Control.MousePosition));
            Vector2 pointOnRender     = renderArea.ClientToImage(pointOnRenderArea);

            if (renderArea.Focused && Document.SelectedRender != null)
            {
                #region Panning
                if (MouseButtons == MouseButtons.Middle)
                {
                    renderArea.ImageOffset += (pointOnRenderArea - lastPointOnRenderArea) / renderArea.ImageScale;
                }
                #endregion
                #region Brush
                HeightBrush activeBrush = null;
                if (MouseButtons == MouseButtons.Left)
                {
                    activeBrush = Document.LeftBrush;
                }
                else if (MouseButtons == MouseButtons.Right)
                {
                    activeBrush = Document.RightBrush;
                }

                if (activeBrush != null)
                {
                    HeightRender   render   = Document.SelectedRender;
                    PhotonGradient gradient = Document.SelectedGradient;
                    IEnumerable <HeightRender.Effect> effects;
                    if (paintEffectsBox.Checked)
                    {
                        effects = Document.SelectedEffects;
                    }
                    else
                    {
                        effects = null;
                    }
                    #region Process Steps
                    Vector2 brushDelta   = lastPointOnRender - pointOnRender;
                    float   strokeLength = (float)brushDelta.Length;
                    float   steps        = strokeLength / activeBrush.Precision + 1;
                    Vector2 brushStep    = brushDelta * (1.0f / steps);
                    for (int i = 0; i < steps; i++)
                    {
                        Vector2 brushPosition = pointOnRender + brushStep * i;
                        #region Process Brush Paint
                        try
                        {
                            FieldSelection brushArea;
                            activeBrush.Paint(render.HeightField, (int)brushPosition.X, (int)brushPosition.Y, strokeLength, out brushArea);
                            foreach (FieldSelection fs in brushArea.SubSelectionsOf(render.HeightField))
                            {
                                if (!fs.IsEmpty)
                                {
                                    render.UpdateArea(fs.Left, fs.Top, fs.Width, fs.Height, gradient, effects);
                                    Point start = Numerics.ToPoint(renderArea.ImageToClient(new Vector2(fs.Left, fs.Top)));
                                    Point end   = Numerics.ToPoint(renderArea.ImageToClient(new Vector2(fs.Right, fs.Bottom)));
                                    renderArea.Invalidate(new Rectangle(Numerics.Max(start.X, 0), Numerics.Max(start.Y, 0), Numerics.Max(end.X, 0), Numerics.Max(end.Y, 0)));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "There was a runtime error with your brush script.");
                        }
                        #endregion
                    }
                    #endregion
                }
                #endregion
            }

            lastPointOnRenderArea = pointOnRenderArea;
            lastPointOnRender     = pointOnRender;
        }