Example #1
0
        private void DrawInitialDebug(Surface screen)
        {
            //Create the surface to draw all the debugging on
            debugsurface = new Surface(512, 512);

            //Create a 2D basis based on the camera orientation to project the rays and spheres on
            DebugYUnit = camera.getDirection(256, 256).direction.Normalized();
            Vector3 upesq = camera.getDirection(256, 200).direction.Normalized();

            DebugXUnit = (Vector3.Cross(DebugYUnit, upesq)).Normalized();

            // draw primitive spheres
            foreach (Primitive prim in scene.primitives)
            {
                if (prim is Sphere)
                {
                    Sphere  s               = (Sphere)prim;
                    Vector3 nc              = s.center - camera.Position;
                    float   nx              = Vector3.Dot(DebugXUnit, nc);
                    float   ny              = Vector3.Dot(DebugYUnit, nc);
                    Vector3 dif             = nc - (nx * DebugXUnit + ny * DebugYUnit);
                    float   distancesquared = dif.LengthSquared;
                    if (distancesquared > s.radius * s.radius)
                    {
                        continue; // outside the screen.
                    }
                    DrawCircle(debugsurface, TXDebug(nx), TYDebug(ny), (float)Math.Sqrt(s.radius * s.radius - distancesquared), Utils.GetRGBValue(s.material.diffuseColor));
                }
            }

            // Draw the camera as a point:
            debugsurface.Plot(TXDebug(0), TYDebug(0), 0xffffff);
        }
Example #2
0
        public void Plot(int x, int y, Color3 color, bool gammaCorrection)
        {
            if (float.IsNaN(color.R))
            {
                return;
            }

            var oldColor = _acc[x, y];
            var newColor = (oldColor * NumSamples + color) / (NumSamples + 1);

            _acc[x, y] = newColor;
            _screen.Plot(x, y, newColor.ToArgb(gammaCorrection));
        }
Example #3
0
        public void Render(Surface surface)
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();

            // Initial part of Debug
            screensurface = surface;
            DrawInitialDebug(surface);

            // We divide the screen between threads by x-values.
            // In this fashion: [1, 2, 3, 1, 2, 3, 1, 2, 3, ..., 1, 2 ]
            // However we begin at the end (Camera.resolution - SpeedUp).
            int[] startX = new int[nThreads];
            for (int i = 0; i < nThreads; i++)
            {
                startX[i] = Camera.resolution - (i + 1) * SpeedUp;
            }

            // Update draw params:
            drawParams.SpeedUp      = SpeedUp;
            drawParams.AntiAliasing = AntiAliasing;
            drawParams.deltaX       = nThreads * SpeedUp;
            drawParams.AAInvSq      = 1f / (AntiAliasing * AntiAliasing);
            drawParams.AAvals       = new float[AntiAliasing];
            for (int i = 0; i < AntiAliasing; i++)
            {
                // Precalculate these variables and put them in an array.
                drawParams.AAvals[i] = SpeedUp * 0.5f * (1f + 2 * i) / AntiAliasing;
            }
            drawParams.surface = surface;

            Thread[] threads = new Thread[nThreads];
            for (int i = 1; i < nThreads; i++)
            {
                threads[i] = new Thread(DrawParallel);
                threads[i].Start(startX[i]);
            }
            DrawParallel(startX[0]);
            // Wait for all OTHER threads until they are done.
            for (int i = 1; i < nThreads; i++)
            {
                threads[i].Join();
            }

            // The debug data is first drawn on a seperate surface, then drawn on the main surface so no debug data is drawn over the main raytracer image
            int[] debugdata = debugsurface.pixels;
            for (int x = 0; x < 512; x++)
            {
                for (int y = 0; y < 512; y++)
                {
                    surface.Plot(x + 512, y, debugdata[x + 512 * y]);
                }
            }

            // When we talk about 4x anti-aliasing, we actually mean 2x2 rays instead of 1 per pixel.
            surface.Print("Anti-Aliasing: " + (AntiAliasing * AntiAliasing), 522, 512 - 48, 0xffffff);
            surface.Print("Speedup: " + SpeedUp, 522, 512 - 24, 0xffffff);

            timer.Stop();
            Console.WriteLine("One render took " + timer.ElapsedMilliseconds + " ms");
        }