예제 #1
0
        protected override void OnUpdate(float timeStep)
        {
            base.OnUpdate(timeStep);

            //fire event
            RenderUpdate?.Invoke(this, timeStep);
        }
예제 #2
0
        public void RenderUp(int y, System.Windows.Forms.PictureBox viewport, DateTime timestart)
        {
            if (RenderUpdate != null)
            {
                double progress = (y) / (double)(viewport.Height);
                double duration = DateTime.Now.Subtract(timestart).TotalMilliseconds;

                double ETA = duration / progress - duration;
                RenderUpdate.Invoke((int)progress * 100, duration, ETA, y - 1);
            }
        }
예제 #3
0
 public void Update(double t)
 {
     if (Renderer != null)
     {
         #if DEBUG
         Renderer.UseDebugPoints(DebugPoints);
         #endif
         Renderer.Update(t);
     }
     Physics?.Step(t);
     for (int i = 0; i < objects.Count; i++)
     {
         objects[i].Update(t);
     }
     RenderUpdate?.Invoke(t);
 }
예제 #4
0
 public void Update(TimeSpan t)
 {
     Physics?.Step(t);
     for (int i = 0; i < Objects.Count; i++)
     {
         Objects[i].Update(t);
     }
     RenderUpdate?.Invoke(t);
     if (Renderer != null)
     {
         #if DEBUG
         Renderer.UseDebugPoints(DebugPoints);
         #endif
         Renderer.Update(t);
     }
 }
예제 #5
0
 public void DispatchRenderUpdate()
 {
     // Dispatch to all client render update handlers
     RenderUpdate?.Invoke(this, EventArgs.Empty);
 }
예제 #6
0
        /// <summary>
        /// 用于载入渲染数据
        /// </summary>
        /// <param name="g">画图用的画笔</param>
        /// <param name="viewport">图片的尺寸</param>
        /// <param name="scene">场景</param>
        public void RayTraceScene(Graphics g, Rectangle viewport, Scene scene)
        {
            int      maxsamples = (int)AntiAliasing;
            DateTime timestart  = DateTime.Now;

            g.FillRectangle(Brushes.Black, viewport);

            Color[] scanline1;
            Color[] scanline2 = null;
            Color[] scanline3 = null;

            Color[,] buffer = new Color[viewport.Width + 2, viewport.Height + 2];

            for (int y = 0; y < viewport.Height + 2; y++)
            {
                //使用反锯齿
                scanline1 = scanline2;
                scanline2 = scanline3;
                scanline3 = new Color[viewport.Width + 2];

                for (int x = 0; x < viewport.Width + 2; x++)
                {
                    double yp = y * 1.0f / viewport.Height * 2 - 1;
                    double xp = x * 1.0f / viewport.Width * 2 - 1;

                    Ray ray = scene.Camera.GetRay(xp, yp);

                    // 进行光线跟踪
                    buffer[x, y] = CalculateColor(ray, scene);

                    if ((x > 1) && (y > 1))
                    {
                        if (AntiAliasing != AntiAliasing.None)
                        {
                            //平均采样
                            Color avg = (buffer[x - 2, y - 2] + buffer[x - 1, y - 2] + buffer[x, y - 2] +
                                         buffer[x - 2, y - 1] + buffer[x - 1, y - 1] + buffer[x, y - 1] +
                                         buffer[x - 2, y] + buffer[x - 1, y] + buffer[x, y]) / 9;

                            if (AntiAliasing == AntiAliasing.Quick)
                            {
                                buffer[x - 1, y - 1] = avg;
                            }
                            else
                            {
                                if (avg.Distance(buffer[x - 1, y - 1]) > 0.18)
                                {
                                    for (int i = 0; i < maxsamples; i++)
                                    {
                                        // 相关范围内的 随机采样
                                        double rx = Math.Sign(i % 4 - 1.5) * (IntNoise(x + y * viewport.Width * maxsamples * 2 + i) + 1) / 4;
                                        double ry = Math.Sign(i % 2 - 0.5) * (IntNoise(x + y * viewport.Width * maxsamples * 2 + 1 + i) + 1) / 4;

                                        xp = (x - 1 + rx) * 1.0f / viewport.Width * 2 - 1;
                                        yp = (y - 1 + ry) * 1.0f / viewport.Height * 2 - 1;

                                        ray = scene.Camera.GetRay(xp, yp);

                                        buffer[x - 1, y - 1] += CalculateColor(ray, scene);
                                    }
                                    buffer[x - 1, y - 1] /= (maxsamples + 1);
                                }
                            }
                        }

                        Brush br = new SolidBrush(buffer[x - 1, y - 1].ToArgb());
                        g.FillRectangle(br, viewport.Left + x - 2, viewport.Top + y - 2, 1, 1);
                        br.Dispose();
                    }
                }

                //更新显示
                if (RenderUpdate != null)
                {
                    double progress = (y) / (double)(viewport.Height);
                    double duration = DateTime.Now.Subtract(timestart).TotalMilliseconds;

                    double ETA = duration / progress - duration;
                    RenderUpdate.Invoke((int)progress * 100, duration, ETA, y - 1);
                }
            }
        }
예제 #7
0
        /// <summary>
        /// this is the main entrypoint for rendering a scene. this method is responsible for correctly rendering
        /// the graphics device (in this case a bitmap).
        /// Note that apart from the raytracing, painting on a graphics device is rather slow
        /// </summary>
        /// <param name="g">the graphics to render on</param>
        /// <param name="viewport">basically determines the size of the bitmap to render on</param>
        /// <param name="scene">the scene to render.</param>
        public void RayTraceScene(Graphics g, Rectangle viewport, Scene scene)
        {
            int maxsamples = (int)AntiAliasing;


            g.FillRectangle(Brushes.Black, viewport);

            //Color[] scanline1;
            //Color[] scanline2 = null;
            //Color[] scanline3 = null;

            Color[,] buffer = new Color[viewport.Width + 2, viewport.Height + 2];

            for (int y = 0; y < viewport.Height + 2; y++)
            {
                DateTime timestart = DateTime.Now;
                //// used for anti-aliasing
                //scanline1 = scanline2;
                //scanline2 = scanline3;
                //scanline3 = new Color[viewport.Width + 2];

                for (int x = 0; x < viewport.Width + 2; x++)
                {
                    double yp = y * 1.0f / viewport.Height * 2 - 1;
                    double xp = x * 1.0f / viewport.Width * 2 - 1;

                    Ray ray = scene.Camera.GetRay(xp, yp);

                    // this will trigger the raytracing algorithm
                    buffer[x, y] = CalculateColor(ray, scene);

                    if ((x > 1) && (y > 1))
                    {
                        if (AntiAliasing != AntiAliasing.None)
                        {
                            Color avg = (buffer[x - 2, y - 2] + buffer[x - 1, y - 2] + buffer[x, y - 2] +
                                         buffer[x - 2, y - 1] + buffer[x - 1, y - 1] + buffer[x, y - 1] +
                                         buffer[x - 2, y] + buffer[x - 1, y] + buffer[x, y]) / 9;

                            if (AntiAliasing == AntiAliasing.Quick)
                            {
                                // this basically implements a simple mean filter
                                // it quick but not very accurate
                                buffer[x - 1, y - 1] = avg;
                            }
                            else
                            {                                                  // use a more accurate antialasing method (MonteCarlo implementation)
                                // this will fire multiple rays per pixel
                                if (avg.Distance(buffer[x - 1, y - 1]) > 0.18) // 0.18 is a treshold for detailed aliasing
                                {
                                    for (int i = 0; i < maxsamples; i++)
                                    {
                                        // get some 'random' samples
                                        double rx = Math.Sign(i % 4 - 1.5) * (IntNoise(x + y * viewport.Width * maxsamples * 2 + i) + 1) / 4;     // interval <-0.5, 0.5>
                                        double ry = Math.Sign(i % 2 - 0.5) * (IntNoise(x + y * viewport.Width * maxsamples * 2 + 1 + i) + 1) / 4; // interval <-0.5, 0.5>

                                        xp = (x - 1 + rx) * 1.0f / viewport.Width * 2 - 1;
                                        yp = (y - 1 + ry) * 1.0f / viewport.Height * 2 - 1;

                                        ray = scene.Camera.GetRay(xp, yp);
                                        // execute even more ray traces, this makes detailed anti-aliasing expensive
                                        buffer[x - 1, y - 1] += CalculateColor(ray, scene);
                                    }
                                    buffer[x - 1, y - 1] /= (maxsamples + 1);
                                }
                            }
                        }

                        // this is the slow part of the painting algorithm, it can be greatly speed up
                        // by directly accessing the bitmap data
                        Brush br = new SolidBrush(buffer[x - 1, y - 1].ToArgb());
                        g.FillRectangle(br, viewport.Left + x - 2, viewport.Top + y - 2, 1, 1);
                        br.Dispose();
                    }
                }

                // update progress after every scanline
                if (RenderUpdate != null)
                {
                    double progress = (y) / (double)(viewport.Height);
                    double duration = DateTime.Now.Subtract(timestart).TotalMilliseconds;

                    double ETA = duration / progress - duration;
                    RenderUpdate.Invoke((int)progress * 100, duration, ETA, y - 1);
                }
            }
        }