예제 #1
0
 public XMLProcessor(XmlReader doc, World worldref)
 {
     _sceneXML = new XmlDocument();
     _sceneReader = doc;
     _sceneXML.Load(_sceneReader);
     _world = worldref;
 }
예제 #2
0
 /// <summary>
 /// Constructor, requires filename and handle for the world
 /// </summary>
 /// <param name="filename">File to open</param>
 /// <param name="worldref">World reference</param>
 public XMLProcessor(string filename, World worldref)
 {
     try {
         _sceneXML = new XmlDocument();
         _sceneReader = new XmlTextReader(filename);
         _sceneXML.Load(_sceneReader);
         _rootNode = _sceneXML.DocumentElement;
         _world = worldref;
     }
     catch (System.IO.FileNotFoundException e)
     {
         Console.WriteLine(e.ToString());
         Environment.Exit(1);
     }
 }
예제 #3
0
        /// <summary>
        /// Renders the world on a single thread [deprecated, use RenderSceneMultiThreaded]
        /// </summary>
        /// <param name="world">World reference</param>
        public override void RenderScene(World worldRef)
        {
            RGBColor lightingSum;
            ViewPlane vp = worldRef.CurrentViewPlane;
            Ray ray = new Ray(_eye,new Vect3D(0,0,0));
            int depth = 0; //Depth of recursion
            Point2D sp = new Point2D(); //Sample point on a unit square
            Point2D pp = new Point2D(); ; //Sample point translated into screen space

            worldRef.OpenWindow(vp.HorizontalResolution, vp.VerticalResolution);
            vp.PixelSize /= _zoom;

            for(int row = 0; row < vp.VerticalResolution; row++)
            {
                for(int column = 0; column < vp.HorizontalResolution; column++)
                {
                    lightingSum = GlobalVars.COLOR_BLACK; //Start with no color, everything is additive

                    for(int sample = 0; sample < vp.NumSamples; sample ++)
                    {
                        sp = worldRef.CurrentViewPlane.ViewPlaneSampler.SampleUnitSquare();
                        pp.coords.X = worldRef.CurrentViewPlane.PixelSize * (column - 0.5f * vp.HorizontalResolution + sp.coords.X);
                        pp.coords.Y = worldRef.CurrentViewPlane.PixelSize * (row - 0.5f * vp.VerticalResolution + sp.coords.Y);
                        ray.Direction = GetRayDirection(pp);
                        lightingSum = lightingSum + worldRef.CurrentTracer.TraceRay(ray, depth);
                    }

                    lightingSum /= vp.NumSamples;
                    lightingSum *= _exposureTime;
                    worldRef.DisplayPixel(row, column, lightingSum);

                    //Poll events in live render view
                    worldRef.PollEvents();
                }
            }
        }
예제 #4
0
 /// <summary>
 /// Parameterized constructor for a given render fragment
 /// </summary>
 /// <param name="w_arg">Reference to world, passed to RenderSceneFragment</param>
 /// <param name="h0_arg">Smallest horizontal render point</param>
 /// <param name="h1_arg">Largest horizontal render point</param>
 /// <param name="v0_arg">Smallest horizontal render point</param>
 /// <param name="v1_arg">Largest hozitontal render point</param>
 /// <param name="tno_arg">Thread id</param>
 public RenderFragmentParameters(World w_arg, int h0_arg, int h1_arg, int v0_arg, int v1_arg, int tno_arg)
 {
     worldRef = w_arg;
     horizontal0 = h0_arg;
     horizontal1 = h1_arg;
     vertical0 = v0_arg;
     vertical1 = v1_arg;
     threadNo = tno_arg;
     // construct new thread using lambda expression for parameterized thread start
     thread = new Thread(() => worldRef.Camera.RenderSceneFragment(worldRef, horizontal0, horizontal1, vertical0, vertical1, threadNo));
     thread.Priority = ThreadPriority.Highest;
 }
예제 #5
0
        /// <summary>
        /// Renders a frame for the current world across a given number of threads
        /// </summary>
        /// <param name="world">Current world with camera</param>
        /// <param name="numThreads">Number of threads to split workload across</param>
        public virtual void RenderSceneMultithreaded(World world, int numThreads)
        {
            // local ref for viewplane for minimized member accesses
            ViewPlane vp = world.CurrentViewPlane;

            // set zoom for frame zero to ensure animation does not cause increasing zoom
            if(GlobalVars.frameno == 0)
                vp.PixelSize /= _zoom;

            // list of all active threads, for spinwait
            List<RenderFragmentParameters> threads = new List<RenderFragmentParameters>();
            // concurrent queue for thread safe dequeue of render chunks
            taskQueue = new ConcurrentQueue<RenderFragmentParameters>();

            //Find out how many chunks the screen can be divided into;
            int hChunks = (int)Math.Floor((decimal)vp.HorizontalResolution / (decimal)GlobalVars.FRAGMENT_SIZE);
            int vChunks = (int)Math.Floor((decimal)vp.VerticalResolution / (decimal)GlobalVars.FRAGMENT_SIZE);
            //Find out the size of the boundaries which do not fit into chunks
            int hRemaining = vp.HorizontalResolution % GlobalVars.FRAGMENT_SIZE;
            int vRemaining = vp.VerticalResolution % GlobalVars.FRAGMENT_SIZE;

            int threadNo = 0; //Label for each thread created

            //Queue up render chunks
            int hor0, hor1, vert0, vert1;
            RenderFragmentParameters parameters;
            for(int v = 0; v < vChunks; v++)
            {
                for(int h = 0; h < hChunks; h++)
                {
                    //Queue up threads
                    hor0 = GlobalVars.FRAGMENT_SIZE * h;
                    hor1 = GlobalVars.FRAGMENT_SIZE * (h + 1);
                    vert0 = GlobalVars.FRAGMENT_SIZE * v;
                    vert1 = GlobalVars.FRAGMENT_SIZE * (v + 1);
                    parameters = new RenderFragmentParameters(world, hor0, hor1, vert0, vert1, threadNo);
                    threads.Add(parameters);
                    taskQueue.Enqueue(parameters);
                    threadNo++;
                }
                //Add in additional fragments for the right screen edge if resolution isn't nicely
                //divisible
                if(hRemaining != 0)
                {
                    hor0 = GlobalVars.FRAGMENT_SIZE * hChunks;
                    hor1 = vp.HorizontalResolution;
                    vert0 = GlobalVars.FRAGMENT_SIZE * v;
                    vert1 = GlobalVars.FRAGMENT_SIZE * (v + 1);
                    parameters = new RenderFragmentParameters(world, hor0, hor1, vert0, vert1, threadNo);
                    threads.Add(parameters);
                    taskQueue.Enqueue(parameters);
                }
            }
            //Add in additional fragments for the top edge if resolution isn't nicely divisible
            if(vRemaining != 0)
            {
                for(int h = 0; h < hChunks; h++)
                {
                    hor0 = GlobalVars.FRAGMENT_SIZE * h;
                    hor1 = GlobalVars.FRAGMENT_SIZE * (h + 1);
                    vert0 = GlobalVars.FRAGMENT_SIZE * vChunks;
                    vert1 = vp.VerticalResolution;
                    parameters = new RenderFragmentParameters(world, hor0, hor1, vert0, vert1, threadNo);
                    threads.Add(parameters);
                    taskQueue.Enqueue(parameters);
                }
                //Add in corner edge fragment if the right edge of the screen wasn't nicely divisible
                if (hRemaining != 0)
                {
                    hor0 = GlobalVars.FRAGMENT_SIZE * hChunks;
                    hor1 = vp.HorizontalResolution;
                    vert0 = GlobalVars.FRAGMENT_SIZE * vChunks;
                    vert1 = vp.VerticalResolution;
                    parameters = new RenderFragmentParameters(world, hor0, hor1, vert0, vert1, threadNo);
                    threads.Add(parameters);
                    taskQueue.Enqueue(parameters);
                }
            }

            // dequeue either the provided number of threads, or the total number of threads, whichever is smaller
            int numThreadsToDequeue = (numThreads < threadNo) ? numThreads : threadNo;

            // dequeue the initial thread count of threads
            RenderFragmentParameters[] initialThreads = new RenderFragmentParameters[numThreadsToDequeue];
            for (int i = 0; i < numThreadsToDequeue; i++)
            {
                while(!taskQueue.TryDequeue(out initialThreads[i])) { // ensure every dequeue succeeds
                }
            }

            // begin rendering in all dequeued threads
            foreach(RenderFragmentParameters renderFragment in initialThreads)
            {
                renderFragment.Begin();
            }

            //Set the thread priority for main thread to low
            Thread.CurrentThread.Priority = ThreadPriority.Lowest;

            //Spinwait for all threads
            bool allDone = false;
            do
            {
                allDone = true;
                foreach (RenderFragmentParameters thread in threads)
                {
                    if (thread.thread.IsAlive)
                    {
                        allDone = false;
                    }
                }
                world.PollEvents();

            } while (!allDone);

            // update liveimage
            world.LiveView.LiveImage = new SFML.Graphics.Image((uint)vp.HorizontalResolution, (uint)vp.VerticalResolution, world.RenderImage);
        }
예제 #6
0
 /// <summary>
 /// Renders a single rectangular chunk of the scene
 /// </summary>
 /// <param name="worldRef">Reference to the world</param>
 /// <param name="xCoord1">Smallest x coordinate</param>
 /// <param name="xCoord2">Largest x coordinate</param>
 /// <param name="yCoord1">Smallest y coordinate</param>
 /// <param name="yCoord2">Largest y coordinate</param>
 /// <param name="threadNum">Thread number</param>
 public abstract void RenderSceneFragment(World worldRef, int xCoord1, int xCoord2, int yCoord1, int yCoord2, int threadNum);
예제 #7
0
 /// <summary>
 /// Renders the world on a single thread [deprecated, use RenderSceneMultiThreaded]
 /// </summary>
 /// <param name="world">World reference</param>
 public abstract void RenderScene(World world);
예제 #8
0
        /// <summary>
        /// Renders a single rectangular chunk of the scene
        /// </summary>
        /// <param name="worldRef">Reference to the world</param>
        /// <param name="xCoord1">Smallest x coordinate</param>
        /// <param name="xCoord2">Largest x coordinate</param>
        /// <param name="yCoord1">Smallest y coordinate</param>
        /// <param name="yCoord2">Largest y coordinate</param>
        /// <param name="threadNum">Thread number</param>
        public override void RenderSceneFragment(World worldRef, int xCoord1, int xCoord2, int yCoord1, int yCoord2, int threadNum)
        {
            RGBColor L = new RGBColor();
            Ray ray = new Ray();
            ViewPlane vp = worldRef.CurrentViewPlane;
            int depth = 0;

            Point2D samplePoint = new Point2D();
            Point2D samplePointPixelSpace = new Point2D();
            Point2D samplePointOnDisk = new Point2D();
            Point2D samplePointOnLens = new Point2D();

            Sampler screenSamplerClone = GlobalVars.VIEWPLANE_SAMPLER.Clone();
            Sampler lensSamplerClone = depthSampler.Clone();

            //vp.s /= zoom;
            //Vector2 tmp2 = new Vector2(vp.hres * 0.5f, vp.vres*0.5f);
            for (int r = yCoord1; r < yCoord2; r++)
            {
                for (int c = xCoord1; c < xCoord2; c++)
                {
                    L = GlobalVars.COLOR_BLACK;

                    for (int n = 0; n < vp.NumSamples; n++)
                    {
                        //Sample on unit square
                        samplePoint = screenSamplerClone.SampleUnitSquare();
                        //Sample in screenspace
                        //Vector2 tmp1 = new Vector2(c, r);
                        //pp.coords = vp.s * (tmp1 - tmp2 * sp.coords);
                        samplePointPixelSpace.coords.X = vp.PixelSize * (c - vp.HorizontalResolution * 0.5f + samplePoint.coords.X);
                        samplePointPixelSpace.coords.Y = vp.PixelSize * (r - vp.VerticalResolution * 0.5f + samplePoint.coords.Y);

                        samplePointOnDisk = lensSamplerClone.SampleDisk();
                        samplePointOnLens.coords.X = samplePointOnDisk.coords.X * radius;
                        samplePointOnLens.coords.Y = samplePointOnDisk.coords.Y * radius;
                        //lp.coords = dp.coords * radius;

                        ray.Origin = _eye + samplePointOnLens.coords.X * u + samplePointOnLens.coords.Y * v;
                        ray.Direction = GetRayDirection(samplePointPixelSpace, samplePointOnLens);
                        L += worldRef.CurrentTracer.TraceRay(ray, depth);
                    }
                    L /= vp.NumSamples;
                    L *= _exposureTime;
                    worldRef.DisplayPixel(r, c, L);
                }
            }

            DequeueNextRenderFragment();
        }
예제 #9
0
        public override void RenderScene(World w)
        {
            RGBColor L = new RGBColor();
            Ray ray = new Ray();
            ViewPlane vp = w.CurrentViewPlane;
            int depth = 0;

            Point2D sp = new Point2D();
            Point2D pp = new Point2D();
            Point2D dp = new Point2D();
            Point2D lp = new Point2D();

            //w.open_window(vp.hres, vp.vres);
            vp.PixelSize /= _zoom;

            for(int r = 0; r < vp.VerticalResolution-1; r++)
            {
                for(int c = 0; c < vp.HorizontalResolution-1; c++)
                {
                    L = GlobalVars.COLOR_BLACK;

                    for(int n = 0; n < vp.NumSamples; n++)
                    {
                        //Sample on unit square
                        sp = vp.ViewPlaneSampler.SampleUnitSquare();
                        //Sample in screenspace
                        pp.coords.X = vp.PixelSize * (c - vp.HorizontalResolution * 0.5f + sp.coords.X);
                        pp.coords.Y = vp.PixelSize * (r - vp.VerticalResolution * 0.5f + sp.coords.Y);

                        dp = depthSampler.SampleDisk();
                        lp.coords.X = dp.coords.X * radius;
                        lp.coords.Y = dp.coords.Y * radius;

                        ray.Origin = _eye + lp.coords.X * u + lp.coords.Y * v;
                        ray.Direction = GetRayDirection(pp, lp);
                        L += w.CurrentTracer.TraceRay(ray, depth);
                    }
                    L /= vp.NumSamples;
                    L *= _exposureTime;
                    w.DisplayPixel(r, c, L);
                    w.PollEvents();
                }
            }
        }
예제 #10
0
 /// <summary>
 /// Parameterized constructor, hands off to base class
 /// </summary>
 /// <param name="worldPointer">Pointer to current world</param>
 public Whitted(World worldPointer)
     : base(worldPointer)
 {
 }
예제 #11
0
        /// <summary>
        /// Renders a single rectangular chunk of the scene
        /// </summary>
        /// <param name="worldRef">Reference to the world</param>
        /// <param name="xCoord1">Smallest x coordinate</param>
        /// <param name="xCoord2">Largest x coordinate</param>
        /// <param name="yCoord1">Smallest y coordinate</param>
        /// <param name="yCoord2">Largest y coordinate</param>
        /// <param name="threadNum">Thread number</param>
        public override void RenderSceneFragment(World worldRef, int xCoord1, int xCoord2, int yCoord1, int yCoord2, int threadNum)
        {
            //To avoid clashes with other threads accessing sampler, clone the main world sampler
            Sampler localSampler = worldRef.CurrentViewPlane.ViewPlaneSampler.Clone();

            RGBColor L;
            ViewPlane vp = worldRef.CurrentViewPlane;
            Ray ray = new Ray(_eye, new Vect3D(0, 0, 0));
            int depth = 0; //Depth of recursion
            Point2D unitSquareSample = new Point2D(); //Sample point on a unit square
            Point2D sampleInScreenSpace = new Point2D(); ; //Sample point translated into screen space
            int height = yCoord2 - yCoord1;
            int width = xCoord2 - xCoord1;

            for (int row = 0; row < height; row++)
            {
                for (int column = 0; column < width; column++)
                {
                    L = GlobalVars.COLOR_BLACK; //Start with no color, everything is additive

                    for (int sample = 0; sample < vp.NumSamples; sample++)
                    {
                        unitSquareSample = localSampler.SampleUnitSquare();
                        sampleInScreenSpace.coords.X = worldRef.CurrentViewPlane.PixelSize * (column + xCoord1 - 0.5f * vp.HorizontalResolution + unitSquareSample.coords.X);
                        sampleInScreenSpace.coords.Y = worldRef.CurrentViewPlane.PixelSize * (row + yCoord1 - 0.5f * vp.VerticalResolution + unitSquareSample.coords.Y);
                        ray.Direction = GetRayDirection(sampleInScreenSpace);
                        L = L + worldRef.CurrentTracer.TraceRay(ray, depth);
                    }

                    L /= vp.NumSamples;
                    L *= _exposureTime;

                    worldRef.DisplayPixel(row + yCoord1, column + xCoord1, L);
                }
            }

            DequeueNextRenderFragment();
        }
예제 #12
0
 public XMLProcessor(World worldref)
 {
     _sceneXML = new XmlDocument();
     _world = worldref;
 }
예제 #13
0
        static void Main(string[] args)
        {
            bool multithread = false;
            int threads = 2;

            int a = 0;
            int numArgs = args.Length;

            if(numArgs == 0)
            {
                Console.WriteLine("Usage: scsraytracer -I \"Input XML path\" -O \"Output bmp path\"");
                Console.WriteLine("Additional options:\n-V: Verbose output, default off\n-T #: Number of threads");
                Console.ReadKey();
                return;
            }
            try {
                //Cycle through all arguments
                while (a < numArgs)
                {
                    string arg = args[a];
                    if (arg.Equals("-I") && GlobalVars.inFile == null)
                    {
                        if ((a + 1 < numArgs) && File.Exists(args[a+1]))
                        {
                            GlobalVars.inFile = args[a + 1];
                            a += 2;
                        }
                        else
                        {
                            throw new ArgumentException("Invalid input file location");
                        }
                    }
                    else if (arg.Equals("-O") && GlobalVars.outFile == null)
                    {
                        if ((a + 1 < numArgs))
                        {
                            GlobalVars.outFile = args[a + 1];
                            a += 2;
                        }
                        else
                        {
                            throw new ArgumentException("Invalid output file location");
                        }
                    }
                    else if (arg.Equals("-V"))
                    {
                        GlobalVars.verbose = true;
                        a++;
                    }
                    else if (arg.Equals("-T"))
                    {
                        multithread = true;
                        threads = Convert.ToInt32(args[a + 1]);
                        a += 2;
                    }
                }

                if(GlobalVars.outFile == null)
                {
                    throw new ArgumentException();
                }

                if(File.Exists(GlobalVars.outFile))
                {
                    GetUserInput:
                    Console.Write("File " + GlobalVars.outFile + " exists! Overwrite? (y/n): ");
                    switch(Console.ReadKey().KeyChar)
                    {
                        case 'y':
                            //do nothing
                            break;
                        case 'n':
                            Console.WriteLine("\nOk, exiting now.");
                            return;
                        default:
                            Console.Write("\n");
                            goto GetUserInput;
                    }
                }

            }
            catch (ArgumentException e)
            {
                Console.WriteLine(e.ToString());
                Console.WriteLine("Usage: scsraytracer -I \"Input XML path\" -O \"Output bmp path\"");
                Console.WriteLine("Additional options:\n-V: Verbose output, default off\n-T #: Number of threads");
                Console.ReadKey();
                return;
            }
            //Elevate process priority to high

            using (Process p = Process.GetCurrentProcess())
                p.PriorityClass = ProcessPriorityClass.High;
            World w = new World();
            GlobalVars.WORLD_REF = w;

            w.Build();
            w.OpenWindow(w.CurrentViewPlane.HorizontalResolution, w.CurrentViewPlane.VerticalResolution);
            //GlobalVars.frameno = 120;
            //w.Animate();
            //while (GlobalVars.frameno < 130)
            //{
                //w.camera.setEye(new Point3D(200, 200, GlobalVars.cam_zcoord));
            //    w.camera.setLookat(new Point3D(0, 0, GlobalVars.lookat_zcoord));
            //    w.camera.compute_uvw();

                switch (multithread)
                {
                    case false:
                        w.Camera.RenderSceneMultithreaded(w, 1);
                        break;
                    case true:
                        w.Camera.RenderSceneMultithreaded(w, threads);
                        break;
                }

                w.SaveDisplayedImage(GlobalVars.outFile);
                //w.SaveDisplayedImage("E:\\weird\\frame_" + GlobalVars.frameno + ".bmp");
                //    GlobalVars.cam_zcoord -= 10;
                //    GlobalVars.lookat_zcoord -= 10;
                //    GlobalVars.frameno += 1;

                //GlobalVars.frameno+=1;
                //w.Animate();
            //}

            while(!GlobalVars.should_close)
            {
                w.PollEvents();
            }
        }
예제 #14
0
 public RayCaster(World w)
 {
     worldPointer = w;
 }