Пример #1
0
        /// <summary>
        /// Animation rendering prolog: prepare all the global (uniform) values, start the main thread.
        /// </summary>
        private void buttonRenderAnim_Click(object sender, EventArgs e)
        {
            if (aThread != null)
            {
                return;
            }

            SetGui(false);
            lock ( progress )
            {
                progress.Continue = true;
            }

            // Global animation properties (it's safe to access GUI components here):
            time = (double)numFrom.Value;
            end  = (double)numTo.Value;
            if (end <= time)
            {
                end = time + 1.0;
            }
            double fps = (double)numFps.Value;

            dt          = (fps > 0.0) ? 1.0 / fps : 25.0;
            end        += 0.5 * dt;
            frameNumber = 0;

            width = ImageWidth;
            if (width <= 0)
            {
                width = panel1.Width;
            }
            height = ImageHeight;
            if (height <= 0)
            {
                height = panel1.Height;
            }
            superSampling = (int)numericSupersampling.Value;

            // param string:
            Dictionary <string, string> p = Util.ParseKeyValueList(textParam.Text);

            if (p.Count > 0)
            {
                // output file-name prefix:
                if (!p.TryGetValue("prefix", out prefix))
                {
                    prefix = "out";
                }
            }

            if (data == null)
            {
                data = FormSupport.getData(textParam.Text);         // animation data
            }
            // Start main rendering thread:
            aThread = new Thread(new ThreadStart(this.RenderAnimation));
            aThread.Start();
        }
Пример #2
0
        public Form1()
        {
            singleton = this;
            InitializeComponent();

            // Init rendering params:
            string name;

            FormSupport.InitializeParams(out name);
            Text += " (rev: " + rev + ") '" + name + '\'';

            buttonRes.Text = FormResolution.GetLabel(ref ImageWidth, ref ImageHeight);
        }
Пример #3
0
        private void SetGui(bool render)
        {
            IImageFunction imf        = FormSupport.getImageFunction(textParam.Text, data);
            bool           canAnimate = (imf != null) &&
                                        (imf is ITimeDependent);

            buttonRenderAnim.Enabled = render && canAnimate;
            buttonRender.Enabled     = render;
            buttonRes.Enabled        = render;
            buttonStop.Enabled       = !render;

            numTime.Enabled = canAnimate;
            numFrom.Enabled = canAnimate;
            numTo.Enabled   = canAnimate;
            numFps.Enabled  = canAnimate;
            label1.Enabled  = canAnimate;
            label2.Enabled  = canAnimate;
            label3.Enabled  = canAnimate;
            label4.Enabled  = canAnimate;
        }
Пример #4
0
        /// <summary>
        /// Redraws the whole image.
        /// </summary>
        private void RenderImage()
        {
            Cursor.Current = Cursors.WaitCursor;

            SetGui(false);

            width = ImageWidth;
            if (width <= 0)
            {
                width = panel1.Width;
            }
            height = ImageHeight;
            if (height <= 0)
            {
                height = panel1.Height;
            }
            superSampling = (int)numericSupersampling.Value;
            Bitmap im = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            MT.InitThreadData();

            if (data == null)
            {
                data = FormSupport.getData(textParam.Text);           // animation data
            }
            IImageFunction imf = FormSupport.getImageFunction(textParam.Text, data);

            imf.Width  = width;
            imf.Height = height;

            IRenderer rend = FormSupport.getRenderer(textParam.Text, imf);

            rend.Width        = width;
            rend.Height       = height;
            rend.Adaptive     = 0;
            rend.ProgressData = progress;
            progress.Continue = true;

            // animation:
            ITimeDependent imftd = imf as ITimeDependent;

            if (imftd != null)
            {
                imftd.Time = (double)numTime.Value;
            }

            Stopwatch sw = new Stopwatch();

            sw.Start();

            rend.RenderRectangle(im, 0, 0, width, height);

            sw.Stop();
            labelElapsed.Text = string.Format(CultureInfo.InvariantCulture, "Elapsed: {0:f1}s", 1.0e-3 * sw.ElapsedMilliseconds);

            SetImage((Bitmap)im.Clone());

            string fileName = Util.FileNameString(textParam.Text) + ".png";

            im.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
            im.Dispose();

            SetGui(true);

            Cursor.Current = Cursors.Default;
        }
Пример #5
0
        /// <summary>
        /// Worker thread (picks up individual frames and renders them one by one).
        /// </summary>
        protected void RenderWorker()
        {
            // thread-specific data:
            ITimeDependent datatd = data as ITimeDependent;
            object         myData = (datatd == null) ? data : datatd.Clone();

            MT.InitThreadData();

            IImageFunction imf = FormSupport.getImageFunction(textParam.Text, myData);

            imf.Width  = width;
            imf.Height = height;
            ITimeDependent imftd = imf as ITimeDependent;

            IRenderer rend = FormSupport.getRenderer(textParam.Text, imf);

            rend.Width        = width;
            rend.Height       = height;
            rend.Adaptive     = 0;          // turn off adaptive bitmap synthesis completely (interactive preview not needed)
            rend.ProgressData = progress;

            // worker loop:
            while (true)
            {
                double myTime;
                int    myFrameNumber;

                lock ( progress )
                {
                    if (!progress.Continue ||
                        time > end)
                    {
                        sem.Release();      // chance for the main animation thread to give up as well..
                        return;
                    }

                    // got a frame to compute:
                    myTime        = time;
                    time         += dt;
                    myFrameNumber = frameNumber++;
                }

                // set up the new result record:
                Result r = new Result();
                r.image       = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                r.frameNumber = myFrameNumber;

                // set specific time to my image function:
                if (imftd != null)
                {
                    imftd.Time = myTime;
                }

                // render the whole frame:
                rend.RenderRectangle(r.image, 0, 0, width, height);

                // ... and put the result into the output queue:
                lock ( queue )
                {
                    queue.Enqueue(r);
                }
                sem.Release();              // notify the main animation thread
            }
        }
Пример #6
0
        /// <summary>
        /// Main animation rendering thread.
        /// Initializes worker threads and collects the results.
        /// </summary>
        protected void RenderAnimation()
        {
            IImageFunction imf = FormSupport.getImageFunction(textParam.Text, data);

            if (imf == null ||
                !(imf is ITimeDependent))
            {
                return;
            }

            Cursor.Current = Cursors.WaitCursor;

            int threads = Environment.ProcessorCount;

            initQueue();
            sem = new Semaphore(0, 10 * threads);

            // pool of working threads:
            Thread[] pool = new Thread[threads];
            int      t;

            for (t = 0; t < threads; t++)
            {
                pool[t] = new Thread(new ThreadStart(RenderWorker));
                pool[t].Start();
            }

            // loop for collection of computed frames:
            int        frames             = 0;
            int        lastDisplayedFrame = -1;
            const long DISPLAY_GAP        = 10000L;
            long       lastDisplayedTime  = -DISPLAY_GAP;
            Stopwatch  sw = new Stopwatch();

            sw.Start();

            while (true)
            {
                sem.WaitOne();              // wait until a frame is finished

                lock ( progress )           // regular finish, escape, user break?
                {
                    if (!progress.Continue ||
                        time >= end &&
                        frames >= frameNumber)
                    {
                        break;
                    }
                }

                // there could be a frame to process:
                Result r;
                lock ( queue )
                {
                    if (queue.Count == 0)
                    {
                        continue;
                    }
                    r = queue.Dequeue();
                }

                // GUI progress indication:
                double seconds = 1.0e-3 * sw.ElapsedMilliseconds;
                double fps     = ++frames / seconds;
                SetText(string.Format(CultureInfo.InvariantCulture, "Frames (mt{0}): {1}  ({2:f0} s, {3:f2} fps)",
                                      threads, frames, seconds, fps));
                if (r.frameNumber > lastDisplayedFrame &&
                    sw.ElapsedMilliseconds > lastDisplayedTime + DISPLAY_GAP)
                {
                    lastDisplayedFrame = r.frameNumber;
                    lastDisplayedTime  = sw.ElapsedMilliseconds;
                    SetImage((Bitmap)r.image.Clone());
                }

                // save the image file:
                string fileName = string.Format("{0}{1:0000}.png", prefix, r.frameNumber);
                r.image.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
                r.image.Dispose();
            }

            for (t = 0; t < threads; t++)
            {
                pool[t].Join();
                pool[t] = null;
            }

            Cursor.Current = Cursors.Default;

            StopAnimation();
        }