Пример #1
0
        public Server(int port, Scene sc)
        {
            this.port = port;

            finalBuffer = new PixelBuffer(sc.ImageWidth, sc.ImageHeight);
            work = new List<Work>();
            scene = sc;

            var workNumX = 10;
            var workNumY = 10;
            var workWidth = sc.ImageWidth / workNumX;
            var workHeight = sc.ImageHeight / workNumY;

            for (var yi = 0; yi < workNumY; yi++) {
                for (var xi = 0; xi < workNumX; xi++) {
                    var x = xi * workWidth;
                    var y = yi * workHeight;
                    work.Add (new Work() {
                        Id = work.Count,
                        Finished = false,
                        Scene = scene,
                        Width = workWidth,
                        Height = workHeight,
                        X = x,
                        Y = y,
                    });
                }
            }
        }
Пример #2
0
 public static PixelBuffer OpenBinary(Stream s)
 {
     using (var w = new BinaryReader (s)) {
         var width = w.ReadInt32 ();
         var height = w.ReadInt32 ();
         var pb = new PixelBuffer (width, height);
         for (var i = 0; i < width*height; i++) {
             pb.Buffer [i].X = w.ReadDouble ();
             pb.Buffer [i].Y = w.ReadDouble ();
             pb.Buffer [i].Z = w.ReadDouble ();
         }
         return pb;
     }
 }
Пример #3
0
        public void Execute(Random rand, PixelBuffer pb)
        {
            var w     = Scene.ImageWidth;
            var h     = Scene.ImageHeight;
            var samps = Scene.SamplesPerPixel;
            var cam   = Scene.Camera;

            var cx = new Vec(w * 0.5135 / h);
            var cy = cx.Cross(cam.Direction).Norm * 0.5135;

            for (var py = 0; py < Height; py++)
            {
                for (var px = 0; px < Width; px++)
                {
                    var x = X + px;
                    var y = Y + py;

                    var c = new Vec();

                    for (var sy = 0; sy < 2; sy++)
                    {
                        for (var sx = 0; sx < 2; sx++)
                        {
                            var r = new Vec();
                            for (var s = 0; s < samps; s++)
                            {
                                Prec r1 = 2 * rand.NextDouble(), dx = r1 < 1 ? Math.Sqrt(r1) - 1 : 1 - Math.Sqrt(2 - r1);
                                Prec r2 = 2 * rand.NextDouble(), dy = r2 < 1 ? Math.Sqrt(r2) - 1 : 1 - Math.Sqrt(2 - r2);
                                Vec  d = cx * (((sx + .5 + dx) / 2 + x) / w - .5) +
                                         cy * (((sy + .5 + dy) / 2 + y) / h - .5) + cam.Direction;

                                r += Radiance(new Ray(cam.Origin + d * 140, d.Norm), 0, rand) * (1.0 / samps);
                            }
                            c += r * 0.25;
                        }
                    }

                    pb.PutPixel(px, py, c);
                }
            }
        }
Пример #4
0
        void OnContext(IAsyncResult ar)
        {
            try {
                var ctx  = listener.EndGetContext(ar);
                var path = ctx.Request.Url.LocalPath;

                System.Console.WriteLine("{0} {1}", ctx.Request.HttpMethod, path);

                if (ctx.Request.HttpMethod == "GET")
                {
                    if (path == "/work")
                    {
                        var idx = rand.Next() % work.Count;
                        var w   = work[idx];
                        if (w.Finished || w.HandedOut)
                        {
                            w = (from ww in work where !ww.Finished && !ww.HandedOut select ww).FirstOrDefault();
                        }

                        if (w != null)
                        {
                            w.Finished               = false;
                            w.HandedOut              = true;
                            ctx.Response.StatusCode  = 200;
                            ctx.Response.ContentType = "text/xml";
                            w.Save(ctx.Response.OutputStream);
                            ctx.Response.Close();
                        }
                        else
                        {
                            ctx.Response.StatusCode = 404;
                            ctx.Response.Close();
                        }
                    }
                    else if (path == "/img" || path == "/favicon.ico")
                    {
                        ctx.Response.StatusCode  = 200;
                        ctx.Response.ContentType = "image/png";
                        finalBuffer.SavePng(ctx.Response.OutputStream);
                        ctx.Response.Close();
                    }
                    else if (path == "/")
                    {
                        ctx.Response.StatusCode  = 200;
                        ctx.Response.ContentType = "text/html";
                        using (var w = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8)) {
                            w.WriteLine("<!DOCTYPE html>");
                            w.WriteLine("<html><head><title>Frank's Distributed Raytracer</title>");
                            w.WriteLine("</head><body style='font-family:sans-serif;'>");
                            w.WriteLine("<h1>Frank's Distributed Raytracer</h1>");
                            w.WriteLine("<img src='/img' style='max-width:640px'>");
                            w.WriteLine("<h2>Progress</h2>");
                            var numFini = (from ww in work where ww.Finished select ww).Count();
                            var p       = (numFini * 100) / work.Count;
                            w.WriteLine("<p><strong>{0} of {1}</strong> blocks complete ({2}%)</p>", numFini, work.Count, p);
                            var mins = 0.0;
                            var pps  = 0.0;
                            var t    = DateTime.UtcNow;
                            if (firstBlockTime.HasValue)
                            {
                                var dt = t - firstBlockTime.Value;
                                pps = (numFini - 1) * work[0].Width * work[0].Height / dt.TotalSeconds;
                                var tt = (dt.TotalMinutes * 100) / p;
                                mins = tt - dt.TotalMinutes;
                            }
                            w.WriteLine("<p><strong>{0}</strong> mins remaining ({1})</p>", (int)(mins + 0.5), DateTime.Now.AddMinutes(mins));
                            w.WriteLine("<p><strong>{0}</strong> pixels / sec</p>", (int)pps);
                            w.WriteLine("<h2>Scene</h2>");
                            w.WriteLine("<code><pre>");
                            w.WriteLine(HtmlEscape(scene.SaveXml()));
                            w.WriteLine("</pre></code>");
                            w.WriteLine("</body></html>");
                        }
                        ctx.Response.Close();
                    }
                    else
                    {
                        ctx.Response.StatusCode = 404;
                        ctx.Response.Close();
                    }
                }
                else
                {
                    if (path.StartsWith("/work/") && path.EndsWith("/pixels"))
                    {
                        var wid = int.Parse(path.Split('/')[2]);
                        var w   = work[wid];
                        var pb  = PixelBuffer.OpenBinary(ctx.Request.InputStream);
                        finalBuffer.SetPixels(w.X, w.Y, pb);
                        w.Finished = true;
                        if (!firstBlockTime.HasValue)
                        {
                            firstBlockTime = DateTime.UtcNow;
                        }
                        ctx.Response.StatusCode  = 200;
                        ctx.Response.ContentType = "text/plain";
                        ctx.Response.Close();
                    }
                    else
                    {
                        ctx.Response.StatusCode = 404;
                        ctx.Response.Close();
                    }
                }
            }
            catch (Exception ex) {
                System.Console.WriteLine("!! {0}: {1}", ex.GetType().Name, ex.Message);
                throw;
            }
            finally {
                listener.BeginGetContext(OnContext, null);
            }
        }
Пример #5
0
 public void SetPixels(int pbx, int pby, PixelBuffer pb)
 {
     //Buffer [(Height - 1 - y)*Width + x] = color;
     for (var y = 0; y < pb.Height; y++) {
         for (var x = 0; x < pb.Width; x++) {
             Buffer [(Height - 1 - (y+pby))*Width + x + pbx] = pb.Get (x, y);
         }
     }
 }