示例#1
0
        public RomData Parse(string path)
        {
            var bitmap = new System.Drawing.Bitmap(path);

            var bitmapFrames = BitmapTexture.FromBitmap(bitmap);

            var romData = new RomData()
            {
                Frames      = new List <Frame>(),
                PaletteData = new List <GBPalette>(),
                TextureData = new List <GBTexture>(),
            };

            foreach (var bitmapFrame in bitmapFrames)
            {
                var frame = ParseFrame(romData, bitmapFrame);

                frame.Index    = romData.Frames.Count;
                frame.Duration = 16 * 2;

                romData.Frames.Add(frame);
            }

            return(romData);
        }
示例#2
0
        protected override void OnLoad()
        {
            base.OnLoad();
            // load texture from file
            using (var bitmap = new Bitmap("Data/Textures/crate.png"))
            {
                BitmapTexture.CreateCompatible(bitmap, out _texture);
                _texture.LoadBitmap(bitmap);
            }

            // initialize shaders
            _textureProgram = ProgramFactory.Create <SimpleTextureProgram>();

            // initialize cube object and base view matrix
            _objectView = _baseView = Matrix4.Identity;

            // initialize demonstration geometry
            _cube = ShapeBuilder.CreateTexturedCube(_textureProgram.InPosition, _textureProgram.InTexCoord);

            // Enable culling, our cube vertices are defined inside out, so we flip them
            GL.Enable(EnableCap.CullFace);
            GL.CullFace(CullFaceMode.Back);

            // initialize camera position
            ActiveCamera.Position = new Vector3(0, 0, 4);

            // set nice clear color
            GL.ClearColor(Color.MidnightBlue);

            _stopwatch.Restart();
        }
示例#3
0
        static GBPalette GetPalette(BitmapTexture texture)
        {
            if (texture == null)
            {
                return(GBPalette.Default);
            }

            var colors = new List <Color>();

            for (int y = 0; y < BitmapTexture.WidthPx; y++)
            {
                for (int x = 0; x < BitmapTexture.WidthPx; x++)
                {
                    var col = texture.Get(x, y);
                    if (colors.Contains(col) == false)
                    {
                        colors.Add(col);
                    }
                }
            }

            colors = colors.SortColors();

            while (colors.Count < GBPalette.MaxLength)
            {
                colors.Add(Color.Pink);
            }

            return(new GBPalette(colors.Take(GBPalette.MaxLength).ToArray()));
        }
示例#4
0
 public static Texture2D LoadTexture(Bitmap image, TextureMinFilter minFilter, TextureMagFilter magFilter, TextureWrapMode wrapMode)
 {
     BitmapTexture.CreateCompatible(image, out Texture2D tex, 1);
     tex.LoadBitmap(image, 0);
     tex.SetFilter(minFilter, magFilter);
     tex.SetWrapMode(wrapMode);
     return(tex);
 }
示例#5
0
文件: Sprite.cs 项目: kroltan/SmallTK
        public void SetBitmap(Bitmap bitmap, bool premultiply = true)
        {
            Texture2D tex;

            using (bitmap) {
                BitmapTexture.CreateCompatible(bitmap, out tex);
                if (premultiply)
                {
                    PremultiplyAlpha(bitmap);
                }
                tex.LoadBitmap(bitmap);
            }
            tex.GenerateMipMaps();
            tex.Bind();
            tex.SetParameter(TextureParameterName.TextureMinFilter, (int)(tex.Levels > 1 ? TextureMinFilter.NearestMipmapNearest : TextureMinFilter.Nearest));
            tex.SetParameter(TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
            Image = tex;
        }
示例#6
0
        private void GenerateTexture()
        {
            var Size = Math.Min(Rect.Width, Rect.Height);

            var Bitmap = new Bitmap(Convert.ToInt32(Rect.Width), Convert.ToInt32(Rect.Height), System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            using (Graphics G = Graphics.FromImage(Bitmap))
            {
                G.Clear(Color.FromArgb(35, Color.Red));

                var F  = GetFont(Rect.Width > Rect.Height ? Size * 0.9f : Size);
                var SS = G.MeasureString(Text, F);

                float X = (Bitmap.Width - SS.Width) / 2;
                float Y = (Bitmap.Height - SS.Height) / 2;

                G.DrawString(Text, F, Brushes.Black, new PointF(X, Y));
            }

            Texture = new BitmapTexture(Bitmap);
        }
示例#7
0
        static GBTexture GetTexture(BitmapTexture bitmapTexture, GBPalette palette)
        {
            if (bitmapTexture == null)
            {
                return(GBTexture.Default);
            }

            var tex = new GBTexture();

            for (int y = 0; y < GBTexture.WidthPx; y++)
            {
                for (int x = 0; x < GBTexture.WidthPx; x++)
                {
                    var color   = bitmapTexture.Get(x, y);
                    var bgColor = palette.GetGBColor(color);
                    tex.Set(x, y, bgColor);
                }
            }

            return(tex);
        }
示例#8
0
        protected override void OnLoad()
        {
            // load textures into array
            for (var i = 0; i < _stateTextures.Length; i++)
            {
                using (var bitmap = new Bitmap(Path.Combine("Data/Textures/", _stateTextures[i])))
                {
                    bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                    if (_textureArray == null)
                    {
                        BitmapTexture.CreateCompatible(bitmap, out _textureArray, _stateTextures.Length, 1);
                    }
                    _textureArray.LoadBitmap(bitmap, i);
                }
            }
            // initialize buffer
            var field = new Minefield[FieldWidth * FieldHeight];

            for (var i = 0; i < field.Length; i++)
            {
                field[i] = new Minefield(i % FieldWidth, i / FieldHeight, i % _stateTextures.Length);
            }
            _buffer = new Buffer <Minefield>();
            _buffer.Init(BufferTarget.ArrayBuffer, field);
            // load program
            _gridProgram = ProgramFactory.Create <TextureGridProgram>();
            _gridProgram.Use();
            // bind the texture and set uniform
            _gridProgram.TextureData.BindTexture(TextureUnit.Texture0, _textureArray);
            // set up vertex array and attributes
            _vao = new VertexArray();
            _vao.Bind();
            _vao.BindAttribute(_gridProgram.InPosition, _buffer);
            _vao.BindAttribute(_gridProgram.InTexture, _buffer, 8);
            // set nice clear color
            GL.ClearColor(Color.MidnightBlue);
            // initialize camera position
            Camera.DefaultState.Position = new Vector3(0, 5, 15);
            Camera.ResetToDefault();
        }
示例#9
0
 protected override void OnLoad()
 {
     // initialize shader
     _program = ProgramFactory.Create <SkyboxProgram>();
     // initialize cube shape
     _cube = new Cube();
     _cube.UpdateBuffers();
     // initialize vertex array and attributes
     _vao = new VertexArray();
     _vao.Bind();
     _vao.BindAttribute(_program.InPosition, _cube.VertexBuffer);
     _vao.BindElementBuffer(_cube.IndexBuffer);
     // create cubemap texture and load all faces
     for (var i = 0; i < 6; i++)
     {
         using (var bitmap = new Bitmap(string.Format("Data/Textures/city{0}.jpg", i)))
         {
             bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
             if (_skybox == null)
             {
                 BitmapTexture.CreateCompatible(bitmap, out _skybox, 1);
             }
             _skybox.LoadBitmap(bitmap, i);
         }
     }
     // activate shader and bind texture to it
     _program.Use();
     _program.Texture.BindTexture(TextureUnit.Texture0, _skybox);
     // enable seamless filtering to reduce artifacts at the edges of the cube faces
     GL.Enable(EnableCap.TextureCubeMapSeamless);
     // cull front faces because we are inside the cube
     // this is not really necessary but removes some artifacts when the user leaves the cube
     // which should be impossible for a real skybox, but in this demonstration it is possible by zooming out
     GL.Enable(EnableCap.CullFace);
     GL.CullFace(CullFaceMode.Front);
     // set a nice clear color
     GL.ClearColor(Color.MidnightBlue);
 }
示例#10
0
        protected override void OnLoad()
        {
            // load texture from file
            using (var bitmap = new Bitmap("Data/Textures/crate.png"))
            {
                BitmapTexture.CreateCompatible(bitmap, out _texture);
                _texture.LoadBitmap(bitmap);
            }

            // initialize shaders
            _textureProgram = ProgramFactory.Create <SimpleTextureProgram>();

            // initialize cube object and base view matrix
            _objectView = _baseView = Matrix4.Identity;

            // initialize demonstration geometry
            _cube = new TexturedCube();
            _cube.UpdateBuffers();

            // set up vertex attributes for the quad
            _cubeVao = new VertexArray();
            _cubeVao.Bind();
            _cubeVao.BindAttribute(_textureProgram.InPosition, _cube.VertexBuffer);
            _cubeVao.BindAttribute(_textureProgram.InTexCoord, _cube.TexCoordBuffer);

            // Enable culling, our cube vertices are defined inside out, so we flip them
            GL.Enable(EnableCap.CullFace);
            GL.CullFace(CullFaceMode.Back);

            // initialize camera position
            Camera.DefaultState.Position = new Vector3(0, 0, 4);
            Camera.ResetToDefault();

            // set nice clear color
            GL.ClearColor(Color.MidnightBlue);

            _stopwatch.Restart();
        }
示例#11
0
 public void Draw(float X, float Y, BitmapTexture Texture)
 {
     Draw(X, Y, Texture.Width, Texture.Height, Texture.Id);
 }
        private BitmapTexture CreateBitmapTexture(ParamTex tex)
        {
            if(null == tex)
                return null;

            BitmapTexture   bmptex;

            if(Bitmaps.TryGetValue(tex.TexAsset, out bmptex))
                return bmptex;

            var name    = Path.GetFileName(tex.TexAsset);
            var texname = Path.ChangeExtension(name, ".tex");
            var texinfo = DataManager.Instance.FindItem(texname) as TexSummary;

            if(null == texinfo)
                return null;

            var texdata = TexFile.FromFile(texinfo.FileName);
            var texfile = Path.Combine(Directory, name);

            File.WriteAllBytes(texfile, texdata.ImageData);

            bmptex      = new BitmapTexture();
            bmptex.ID   = "Bitmap-"+Path.GetFileNameWithoutExtension(name);
            bmptex.Name = "Bitmap-"+Path.GetFileNameWithoutExtension(name);
            bmptex.FileName= texfile;

            Root.Instances.Add(bmptex);
            Bitmaps.Add(tex.TexAsset, bmptex);

            return bmptex;
        }
示例#13
0
        protected override void OnUpdate(float dt)
        {
            base.OnUpdate(dt);
            switch (m_state)
            {
            case SubState.Waiting:
            {
                // Wait for camera press
                if (CheckCameraButton())
                {
                    m_state = SubState.Capturing;
                    m_timer = 0.0f;
                }
                else if (CheckBack())
                {
                    BackToEditor();
                }
                break;
            }

            case SubState.Capturing:
            {
                // Take the screenshot
                // Stop the action
                CameraController.AllowUserZoom   = false;
                CameraController.AllowUserRotate = false;

                // Clear the screen
                m_cameraHUD.ShowViewfinder = false;
                m_prompt.Visible           = false;

                // Request the screenshot
                m_screenshot = Game.QueueScreenshot(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
                m_state      = SubState.CameraFlash;
                break;
            }

            case SubState.CameraFlash:
            {
                // Wait for screenshot, then flash
                if (m_screenshot.Status != Status.Waiting)
                {
                    // Do the effects
                    Game.Audio.PlayMusic(null, 0.0f);
                    m_cameraHUD.Flash();
                    m_state = SubState.Approving;
                    m_timer = FLASH_DURATION;
                }
                break;
            }

            case SubState.Approving:
            {
                // Wait for a timer, then prompt to save the screenshot
                if (m_timer > 0.0f)
                {
                    m_timer -= dt;
                    if (m_timer <= 0.0f)
                    {
                        // Create the texture
                        var screenshot = m_screenshot.Result;
                        var bitmap     = new BitmapTexture(screenshot.Bitmap);
                        bitmap.Filter = true;

                        // Show the dialog
                        var dialog = DialogBox.CreateImageQueryBox(
                            Game.Language.Translate("menus.create_thumbnail.confirm_prompt"),
                            bitmap,
                            427.0f,
                            240.0f,
                            new string[] {
                                Game.Language.Translate("menus.yes"),
                                Game.Language.Translate("menus.no"),
                            }
                            );
                        dialog.OnClosed += delegate(object sender, DialogBoxClosedEventArgs e)
                        {
                            // Handle the result
                            if (e.Result == 0)
                            {
                                // Yes
                                // Save the screenshot
                                var screenshotPath = AssetPath.ChangeExtension(m_levelSavePath, "png");
                                if (m_mod != null)
                                {
                                    var fullPath = Path.Combine(m_mod.Path, "assets/" + screenshotPath);
                                    screenshot.Save(fullPath);
                                }
                                else
                                {
                                    var fullPath = Path.Combine(App.AssetPath, "main/" + screenshotPath);
                                    screenshot.Save(fullPath);
                                }
                                Assets.Reload(screenshotPath);

                                // Save the camera position
                                Level.Info.CameraPitch    = MathHelper.RadiansToDegrees(CameraController.Pitch);
                                Level.Info.CameraYaw      = MathHelper.RadiansToDegrees(CameraController.Yaw);
                                Level.Info.CameraDistance = CameraController.Distance;
                                m_modified = true;

                                // Return
                                BackToEditor();
                            }
                            else if (e.Result == 1)
                            {
                                // No
                                TryAgain();
                            }
                            else
                            {
                                // Escape
                                BackToEditor();
                            }

                            // Dispose things we no longer need
                            bitmap.Dispose();
                            screenshot.Dispose();
                        };
                        ShowDialog(dialog);
                    }
                }
                break;
            }
            }
        }
示例#14
0
 public void Draw(int X, int Y, BitmapTexture Texture)
 {
     Draw(X, Y, Texture.Width, Texture.Height, Texture.Id);
 }
示例#15
0
        public ArcadeState(Game.Game game) : base(game, "levels/startscreen.level", LevelOptions.Menu)
        {
            // Create computer
            m_computer = new Computer(GetComputerID());
            m_computer.Memory.TotalMemory = RAM;
            m_computer.Host        = App.Info.Title + " " + App.Info.Version;
            m_computer.Output      = new LogWriter(LogLevel.User);
            m_computer.ErrorOutput = new LogWriter(LogLevel.Error);
            m_computer.SetPowerStatus(PowerStatus.Charged, 1.0);

            m_devices = new RobotDevices();
            m_computer.Ports.Add(m_devices);

            // Create some textures
            m_displayBitmap  = new Bitmap(m_devices.Display.Width, m_devices.Display.Height);
            m_displayTexture = new BitmapTexture(m_displayBitmap);
            UpdateDisplay();

            // Create camera
            m_animatedCamera = new AnimatedCameraController(Level.TimeMachine);

            // Create prompts
            {
                m_zKey = Key.Z.RemapToLocal();
                m_xKey = Key.X.RemapToLocal();
                m_wKey = Key.W.RemapToLocal();
                m_sKey = Key.S.RemapToLocal();
                m_aKey = Key.A.RemapToLocal();
                m_dKey = Key.D.RemapToLocal();

                m_backPrompt                       = new InputPrompt(UIFonts.Smaller, Game.Language.Translate("menus.back"), TextAlignment.Right);
                m_backPrompt.MouseButton           = MouseButton.Left;
                m_backPrompt.Key                   = Key.Escape;
                m_backPrompt.GamepadButton         = GamepadButton.Back;
                m_backPrompt.SteamControllerButton = SteamControllerButton.ArcadeBack;
                m_backPrompt.Anchor                = Anchor.BottomRight;
                m_backPrompt.LocalPosition         = new Vector2(-16.0f, -16.0f - m_backPrompt.Font.Height);
                m_backPrompt.OnClick              += delegate
                {
                    GoBack();
                };

                m_diskSelectPrompt                       = new InputPrompt(UIFonts.Smaller, Game.Language.Translate("menus.arcade.swap_disk"), TextAlignment.Right);
                m_diskSelectPrompt.Key                   = Key.Tab;
                m_diskSelectPrompt.GamepadButton         = GamepadButton.Start;
                m_diskSelectPrompt.SteamControllerButton = SteamControllerButton.ArcadeSwapDisk;
                m_diskSelectPrompt.Anchor                = Anchor.BottomRight;
                m_diskSelectPrompt.LocalPosition         = new Vector2(-16.0f, -16.0f - m_backPrompt.Font.Height - m_diskSelectPrompt.Height);

                m_bPrompt                       = new InputPrompt(UIFonts.Smaller, Game.Language.Translate("menus.arcade.b"), TextAlignment.Left);
                m_bPrompt.Key                   = m_xKey;
                m_bPrompt.GamepadButton         = GamepadButton.B;
                m_bPrompt.SteamControllerButton = SteamControllerButton.ArcadeB;
                m_bPrompt.Anchor                = Anchor.BottomLeft;
                m_bPrompt.LocalPosition         = new Vector2(16.0f, -16.0f - m_bPrompt.Height);

                m_aPrompt                       = new InputPrompt(UIFonts.Smaller, Game.Language.Translate("menus.arcade.a"), TextAlignment.Left);
                m_aPrompt.Key                   = m_zKey;
                m_aPrompt.GamepadButton         = GamepadButton.A;
                m_aPrompt.SteamControllerButton = SteamControllerButton.ArcadeA;
                m_aPrompt.Anchor                = Anchor.BottomLeft;
                m_aPrompt.LocalPosition         = new Vector2(16.0f, -16.0f - 2.0f * m_bPrompt.Height);
            }

            // Create disk selector
            m_diskSelector  = null;
            m_activeDisk    = null;
            m_activeDiskMod = null;
            m_cachedScore   = 0;
        }
示例#16
0
        private void OnLoad(object sender, EventArgs e)
        {
            // load texture from file
            using (var bitmap = new Bitmap("Data/Textures/checker.jpg"))
            {
                BitmapTexture.CreateCompatible(bitmap, out _texture);
                _texture.LoadBitmap(bitmap);
            }
            _texture.GenerateMipMaps();

            // initialize sampler
            _sampler = new Sampler();
            _sampler.SetWrapMode(TextureWrapMode.Repeat);

            // create vertex data for a big plane
            const int a        = 10;
            const int b        = 10;
            var       vertices = new[]
            {
                new Vertex(-a, 0, -a, 0, 0),
                new Vertex(a, 0, -a, b, 0),
                new Vertex(-a, 0, a, 0, b),
                new Vertex(a, 0, a, b, b)
            };

            // create buffer object and upload vertex data
            _vbo = new Buffer <Vertex>();
            _vbo.Init(BufferTarget.ArrayBuffer, vertices);

            // initialize shader
            _program = ProgramFactory.Create <SimpleTextureProgram>();
            // activate shader program
            _program.Use();
            // bind sampler
            _sampler.Bind(TextureUnit.Texture0);
            // bind texture
            _program.Texture.BindTexture(TextureUnit.Texture0, _texture);
            // which is equivalent to
            //_program.Texture.Set(TextureUnit.Texture0);
            //_texture.Bind(TextureUnit.Texture0);

            // set up vertex array and attributes
            _vao = new VertexArray();
            _vao.Bind();
            // memory layout of our data is XYZUVXYZUV...
            // the buffer abstraction knows the total size of one "pack" of vertex data
            // and if a vertex attribute is bound without further arguments the first N elements are taken from each pack
            // where N is provided via the VertexAttribAttribute on the program property:
            _vao.BindAttribute(_program.InPosition, _vbo);
            // if data should not be taken from the start of each pack, the offset must be given in bytes
            // to reach the texture coordinates UV the XYZ coordinates must be skipped, that is 3 floats, i.e. an offset of 12 bytes is needed
            _vao.BindAttribute(_program.InTexCoord, _vbo, 12);
            // if needed all the available arguments can be specified manually, e.g.
            //_vao.BindAttribute(_program.InTexCoord, _vbo, 2, VertexAttribPointerType.Float, Marshal.SizeOf(typeof(Vertex)), 12, false);

            // set default camera
            Camera.DefaultState.Position = new Vector3(0, 0.5f, 3);
            Camera.ResetToDefault();

            // set a nice clear color
            GL.ClearColor(Color.MidnightBlue);
        }
示例#17
0
        private async Task ShowCornellBox()
        {
            var eye         = new Vector3(0, 0, -4);
            var lookAt      = new Vector3(0, 0, 6);
            var fieldOfView = 36f;

            var logger = new Action <string>(msg =>
            {
                Dispatcher.InvokeAsync(() =>
                {
                    Output.Text += msg + Environment.NewLine;

                    Output.CaretIndex = Output.Text.Length;
                    Output.ScrollToEnd();
                }, System.Windows.Threading.DispatcherPriority.Background);
            });

            var spheres      = new List <Sphere>();
            var lightSources = new List <LightSource>();

            spheres.Add(new Sphere("a", new Vector3(-1001, 0, 0), 1000f, Colors.Red, isWall: true, brightness: 0));
            spheres.Add(new Sphere("b", new Vector3(1001, 0, 0), 1000f, Colors.Blue, isWall: true, brightness: 0));
            spheres.Add(new Sphere("c", new Vector3(0, 0, 1001), 1000f, Colors.White, isWall: true, brightness: 0));
            spheres.Add(new Sphere("d", new Vector3(0, -1001, 0), 1000f, Colors.White, isWall: true, brightness: 0));
            spheres.Add(new Sphere("e", new Vector3(0, 1001, 0), 1000f, Colors.White, isWall: true, brightness: 0));

            var lotsOfSpheres        = bool.Parse(LotsOfSpheres.Text);
            var proceduralTexture    = bool.Parse(ProceduralTexture.Text);
            var bitmapTexture        = bool.Parse(BitmapTexture.Text);
            var multipleLightSources = bool.Parse(MultipleLightSources.Text);
            var coloredLight         = bool.Parse(ColoredLight.Text);

            if (!lotsOfSpheres)
            {
                ITexture procTexture = null;
                if (proceduralTexture)
                {
                    procTexture = new CheckerProceduralTexture();
                }

                ITexture bmpTexture = null;
                if (bitmapTexture)
                {
                    bmpTexture = new BitmapTexture(@"Resources\arroway.de_tiles-29_d100.jpg", BitmapTextureMode.PlanarProjection);
                }

                spheres.Add(new Sphere("f", new Vector3(-0.6f, 0.7f, -0.6f), 0.3f, Colors.Yellow, texture: procTexture, brightness: 0));
                spheres.Add(new Sphere("g", new Vector3(0.3f, 0.4f, 0.3f), 0.6f, Colors.LightCyan, texture: bmpTexture, brightness: bitmapTexture ? 1 : 0));
            }
            else
            {
                int numberOfSpheres = 4096;
                var random          = new Random(Seed: 0); // use same seed, so that we can compare results

                for (int i = 0; i < numberOfSpheres; i++)
                {
                    var x = (float)(random.NextDouble() * 2) - 1;
                    var y = (float)(random.NextDouble() * 2) - 1;
                    var z = (float)(random.NextDouble() * 2) - 1;
                    var r = 0.01f;
                    var c = new Color()
                    {
                        ScA = 1, ScR = (float)random.NextDouble(), ScG = (float)random.NextDouble(), ScB = (float)random.NextDouble()
                    };

                    spheres.Add(new Sphere($"gen{i}", new Vector3(x, y, z), r, c));
                }
            }

            if (bool.Parse(PathTracing.Text))
            {
                var lightBrightness = float.Parse(PathTracingLightBrightness.Text);

                if (!multipleLightSources)
                {
                    spheres.Add(new Sphere("w", new Vector3(0, -10.99f, 0), 10f, Colors.White, brightness: lightBrightness, reflectiveness: 1f));
                }
                else
                {
                    spheres.Add(new Sphere("c", new Vector3(0.5f, -6.99f, 0.3f), 6f, (coloredLight ? Colors.Cyan : Colors.White), brightness: lightBrightness / 3, reflectiveness: 1f));
                    spheres.Add(new Sphere("m", new Vector3(-0.5f, -6.99f, 0.3f), 6f, (coloredLight ? Colors.Magenta : Colors.White), brightness: lightBrightness / 3, reflectiveness: 1f));
                    spheres.Add(new Sphere("y", new Vector3(0, -6.99f, -0.6f), 6f, (coloredLight ? Colors.Yellow : Colors.White), brightness: lightBrightness / 3, reflectiveness: 1f));
                }
            }
            else
            {
                if (!multipleLightSources)
                {
                    // 1 Light Source
                    lightSources.Add(new LightSource("w", new Vector3(0, -0.9f, 0), (coloredLight ? Colors.LightSalmon : Colors.White)));
                }
                else
                {
                    // 3 Light Sources
                    lightSources.Add(new LightSource("c", new Vector3(0.5f, -0.9f, 0.3f), (coloredLight ? Colors.Cyan : Colors.White).ChangIntensity(0.5f)));
                    lightSources.Add(new LightSource("m", new Vector3(-0.5f, -0.9f, 0.3f), (coloredLight ? Colors.Magenta : Colors.White).ChangIntensity(0.5f)));
                    lightSources.Add(new LightSource("y", new Vector3(0, -0.9f, -0.6f), (coloredLight ? Colors.Yellow : Colors.White).ChangIntensity(0.5f)));
                }
            }

            SetControlsEnabled(false);

            var scene = new SceneA(logger, eye, lookAt, fieldOfView, spheres.ToArray(), lightSources.ToArray());

            scene.AntiAliasing           = bool.Parse(AntiAliasing.Text);
            scene.AntiAliasingSampleSize = int.Parse(AntiAliasingSampleSize.Text);
            scene.Parallelize            = bool.Parse(Parallelize.Text);
            scene.GammaCorrect           = bool.Parse(GammaCorrect.Text);
            scene.DiffuseLambert         = bool.Parse(DiffuseLambert.Text);
            scene.SpecularPhong          = bool.Parse(SpecularPhong.Text);
            scene.SpecularPhongFactor    = int.Parse(SpecularPhongFactor.Text);
            scene.Reflection             = bool.Parse(Reflection.Text);
            scene.ReflectionBounces      = int.Parse(ReflectionBounces.Text);
            scene.Shadows               = bool.Parse(Shadows.Text);
            scene.SoftShadows           = bool.Parse(SoftShadows.Text);
            scene.SoftShadowFeelers     = int.Parse(SoftShadowFeelers.Text);
            scene.AccelerationStructure = bool.Parse(AccelerationStructure.Text);
            scene.PathTracing           = bool.Parse(PathTracing.Text);
            scene.PathTracingRays       = int.Parse(PathTracingRays.Text);
            scene.PathTracingMaxBounces = int.Parse(PathTracingMaxBounces.Text);

            Image.Source = null;
            Output.Text  = "";
            Status.Text  = "Status: Running";

            var width    = (int)Image.Width;
            var height   = (int)Image.Height;
            var dpiScale = VisualTreeHelper.GetDpi(this);

            _cts = new CancellationTokenSource();

            var exportDirectory = Path.GetFullPath(@".\RayTracingResults\");
            var settingsSummary = GetSettingsSummary();

            var imageFileName = await Task.Factory.StartNew(() => scene.GetImageFileName(width, height, dpiScale.PixelsPerInchX, dpiScale.PixelsPerInchY, _cts.Token, settingsSummary, exportDirectory), TaskCreationOptions.LongRunning);

            if (!string.IsNullOrEmpty(imageFileName))
            {
                Image.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(imageFileName));
            }

            SetControlsEnabled(true);
        }