/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); Cursor.Current = Cursors.WaitCursor; try { // Set up the graphics interface. _graphics = new GorgonGraphics(); // Create our 2D renderer to display the image. _2D = _graphics.Output.Create2DRenderer(this, 1280, 800); // Center the window on the screen. Screen currentMonitor = Screen.FromControl(this); Location = new Point(currentMonitor.WorkingArea.Left + (currentMonitor.WorkingArea.Width / 2 - Width / 2), currentMonitor.WorkingArea.Top + (currentMonitor.WorkingArea.Height / 2 - Height / 2)); // Load our base texture. _image = _graphics.Textures.FromMemory <GorgonTexture2D>("SourceTexture", Resources.SourceTexture, new GorgonCodecDDS()); // Load the custom codec. if (!LoadCodec()) { GorgonDialogs.ErrorBox(this, "Unable to load the useless image codec plug-in."); Gorgon.Quit(); return; } // Convert the image to our custom codec. ConvertImage(); // Set up our idle time processing. Gorgon.ApplicationIdleLoopMethod = () => { _2D.Clear(Color.White); // Draw to the window. Draw(); // Render with a vsync interval of 2 (typically 30 FPS). // We're not making an action game here. _2D.Render(2); return(true); }; } catch (Exception ex) { GorgonDialogs.ErrorBox(this, ex); Gorgon.Quit(); } finally { Cursor.Current = Cursors.Default; } }
/// <summary> /// Handles the ParentChanged event of the Window control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void Window_ParentChanged(object sender, EventArgs e) { try { // If the actual control has changed parents, update the top level control. if (sender == Settings.Window) { var newTopLevelParent = Gorgon.GetTopLevelControl(Settings.Window); if (newTopLevelParent != _topLevelControl) { _topLevelControl.ParentChanged -= Window_ParentChanged; // If we're not at the top of the chain, then find out which window is and set it up // to handle changes to its hierarchy. if (newTopLevelParent != Settings.Window) { _topLevelControl = newTopLevelParent; _topLevelControl.ParentChanged += Window_ParentChanged; } } } if (_parentForm != null) { _parentForm.ResizeBegin -= _parentForm_ResizeBegin; _parentForm.ResizeEnd -= _parentForm_ResizeEnd; } _parentForm = Gorgon.GetTopLevelForm(Settings.Window); if (_parentForm == null) { return; } _parentForm.ResizeBegin += _parentForm_ResizeBegin; _parentForm.ResizeEnd += _parentForm_ResizeEnd; } catch (Exception ex) { #if DEBUG GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(_parentForm, string.Format(Resources.GORGFX_CATASTROPHIC_ERROR, Gorgon.Log.LogPath), null, ex)); // If we fail in here, then we have a terminal error in Gorgon, don't risk further corruption. Gorgon.Quit(); #else GorgonException.Catch(ex); #endif } }
/// <summary> /// Handles the Resize event of the Window control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void Window_Resize(object sender, EventArgs e) { // If we're in a manual resize operation, then don't call this method just yet. if (_isInResize) { return; } // Attempt to get the parent form if we don't have one yet. if (_parentForm == null) { _parentForm = Gorgon.GetTopLevelForm(Settings.Window); _parentForm.ResizeBegin += _parentForm_ResizeBegin; _parentForm.ResizeEnd += _parentForm_ResizeEnd; } if ((!AutoResize) || ((_parentForm != null) && (_parentForm.WindowState == FormWindowState.Minimized))) { return; } // Only do this if the size has changed, if we're just restoring the window, then don't bother. if (((GISwapChain == null)) || (Settings.Window.ClientSize.Width <= 0) || (Settings.Window.ClientSize.Height <= 0)) { return; } try { // Resize the video mode. Settings.VideoMode = new GorgonVideoMode(Settings.Window.ClientSize.Width, Settings.Window.ClientSize.Height, Settings.VideoMode.Format, Settings.VideoMode.RefreshRateNumerator, Settings.VideoMode.RefreshRateDenominator); ResizeBuffers(); } catch (Exception ex) { #if DEBUG GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(_parentForm, string.Format(Resources.GORGFX_CATASTROPHIC_ERROR, Gorgon.Log.LogPath), null, ex)); // If we fail in here, then we have a terminal error in Gorgon, don't risk further corruption. Gorgon.Quit(); #else // Log the exception. GorgonException.Catch(ex); #endif } }
/// <summary> /// Function to initialize the scratch files area. /// </summary> private void InitializeScratchArea() { ScratchArea.ScratchPath = Program.Settings.ScratchPath; EditorLogging.Print("Creating scratch area at \"{0}\"", LoggingLevel.Verbose, ScratchArea.ScratchPath); _splash.UpdateVersion(Resources.GOREDIT_TEXT_CREATING_SCRATCH); // Ensure that we're not being clever and trying to mess up our system. if (ScratchArea.CanAccessScratch(Program.Settings.ScratchPath) == ScratchAccessibility.SystemArea) { GorgonDialogs.ErrorBox(null, Resources.GOREDIT_ERR_CANNOT_USESYS_SCRATCH); } else { // Destroy previous scratch area files if possible. // Do not do this when we have it set to a system area, this will keep us from // destroying anything critical. ScratchArea.CleanOldScratchAreas(); } // Ensure we can actually access the scratch area. while (ScratchArea.CanAccessScratch(Program.Settings.ScratchPath) != ScratchAccessibility.Accessible) { EditorLogging.Print("Could not access scratch area at \"{0}\"", LoggingLevel.Verbose, Program.Settings.ScratchPath); if (ScratchArea.SetScratchLocation() == ScratchAccessibility.Canceled) { // Exit the application if we cancel. MainForm.Dispose(); Gorgon.Quit(); return; } EditorLogging.Print("Setting scratch area to \"{0}\".", LoggingLevel.Verbose, Program.Settings.ScratchPath); // Update with the new scratch path. Program.Settings.Save(); } ScratchArea.InitializeScratch(); // Get only the providers that are not disabled. var plugIns = from plugIn in Gorgon.PlugIns where plugIn is GorgonFileSystemProviderPlugIn && PlugIns.UserDisabledPlugIns.All(name => !string.Equals(name, plugIn.Name, StringComparison.OrdinalIgnoreCase)) select plugIn; foreach (GorgonPlugIn plugIn in plugIns) { ScratchArea.ScratchFiles.Providers.LoadProvider(plugIn.Name); } }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { Cursor = Cursors.WaitCursor; // Initialize. Initialize(); } catch (Exception ex) { GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(this, ex)); Gorgon.Quit(); } finally { Cursor = Cursors.Default; } }
/// <summary> /// Handles the Deactivate event of the _parentForm control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void _parentForm_Deactivate(object sender, EventArgs e) { try { if ((GISwapChain == null) || (!Graphics.ResetFullscreenOnFocus)) { return; } Graphics.GetFullScreenSwapChains(); // Reset the video mode to windowed. // Note: For some reason, this is different than it was on SlimDX. I never had to do this before, but with // SharpDX I now have to handle the transition from full screen to windowed manually. if (!GISwapChain.IsFullScreen) { return; } GISwapChain.SetFullscreenState(false, null); Settings.IsWindowed = true; ((Form)Settings.Window).WindowState = FormWindowState.Minimized; } catch (Exception ex) { #if DEBUG GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(_parentForm, string.Format(Resources.GORGFX_CATASTROPHIC_ERROR, Gorgon.Log.LogPath), null, ex)); // If we fail in here, then we have a terminal error in Gorgon, don't risk further corruption. Gorgon.Quit(); #else GorgonException.Catch(ex); #endif } }
/// <summary> /// Handles the Activated event of the _parentForm control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void _parentForm_Activated(object sender, EventArgs e) { try { if ((GISwapChain == null) || (!Graphics.ResetFullscreenOnFocus)) { return; } Graphics.GetFullScreenSwapChains(); if (GISwapChain.IsFullScreen) { return; } ((Form)Settings.Window).WindowState = FormWindowState.Normal; // Get the current video output. GISwapChain.SetFullscreenState(true, null); Settings.IsWindowed = false; } catch (Exception ex) { #if DEBUG GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(_parentForm, string.Format(Resources.GORGFX_CATASTROPHIC_ERROR, Gorgon.Log.LogPath), null, ex)); // If we fail in here, then we have a terminal error in Gorgon, don't risk further corruption. Gorgon.Quit(); #else GorgonException.Catch(ex); #endif } }
private void UpdateDeferred(GorgonConstantBuffer constantBuffer) { _tasks.Add(Task.Run(() => { var wvp = new WVPBuffer { Projection = _wvp.Projection, View = _wvp.View }; if (!_bouncy[0]) { _positions[0] = new Vector3(_positions[0].X + 1.0f * GorgonTiming.Delta, _positions[0].Y - 2.5f * GorgonTiming.Delta, _positions[0].Z + 1.85f * GorgonTiming.Delta); } else { _positions[0] = new Vector3(_positions[0].X - 1.0f * GorgonTiming.Delta, _positions[0].Y + 2.5f * GorgonTiming.Delta, _positions[0].Z - 1.85f * GorgonTiming.Delta); } if ((_positions[0].X > 2.0f) || (_positions[0].Y < -2.0f) || (_positions[0].Z > 6.0)) { _bouncy[0] = true; } if ((_positions[0].X < -2.0f) || (_positions[0].Y > 2.0f) || (_positions[0].Z < 1.0f)) { _bouncy[0] = false; } Matrix.Translation(ref _positions[0], out wvp.World); Matrix.Transpose(ref wvp.World, out wvp.World); constantBuffer.Update(ref wvp, _deferred[0]); _deferred[0].Output.DrawIndexed(0, 0, 6); _commands[0] = _deferred[0].FinalizeDeferred(); })); _tasks.Add(Task.Run(() => { var wvp = new WVPBuffer(); Matrix rot; Quaternion quat; wvp.Projection = _wvp.Projection; wvp.View = _wvp.View; if (!_bouncy[1]) { _positions[1].Z += (30.0f * GorgonTiming.Delta); _positions[1].Y += (15.0f * GorgonTiming.Delta); _positions[1].X += (10.0f * GorgonTiming.Delta); } else { _positions[1].Z -= (15.0f * GorgonTiming.Delta); _positions[1].Y -= (30.0f * GorgonTiming.Delta); _positions[1].X -= (25.0f * GorgonTiming.Delta); } if (_positions[1].Z > 195.0f) { _bouncy[1] = true; _positions[1].Z = 195.0f; } if (_positions[1].Z < 0.0f) { _bouncy[1] = true; _positions[1].Z = 0.0f; } Quaternion.RotationYawPitchRoll(_positions[1].Y.Radians(), _positions[1].X.Radians() * 0, _positions[1].Z.Radians() * 0, out quat); Matrix.RotationQuaternion(ref quat, out rot); Matrix.Translation(-2.0f, 0.0f, 6.0f, out wvp.World); Matrix.Multiply(ref rot, ref wvp.World, out wvp.World); Matrix.Transpose(ref wvp.World, out wvp.World); constantBuffer.Update(ref wvp, _deferred[1]); _deferred[1].Output.DrawIndexed(0, 0, 6); _commands[1] = _deferred[1].FinalizeDeferred(); })); try { Action runDeferred = async() => { var task = await Task.WhenAny(_tasks); _tasks.Remove(task); await task; }; while (_tasks.Count > 0) { runDeferred(); Thread.Sleep(5); } } catch (Exception ex) { GorgonDialogs.ErrorBox(null, ex); Gorgon.Quit(); } }
/// <summary> /// Initializes a new instance of the <see cref="AppContext"/> class. /// </summary> public AppContext() { float startTime = GorgonTiming.SecondsSinceStart; try { PlugIns.DefaultImageEditorPlugIn = Program.Settings.DefaultImageEditor; _splash = new FormSplash(); MainForm = new FormMain(); _splash.Show(); _splash.Refresh(); // Fade in our splash screen. FadeSplashScreen(true, 500.0f); EditorLogging.Open(); InitializeGraphics(); InitializePlugIns(); InitializeScratchArea(); InitializeInput(); FileManagement.InitializeFileTypes(); // Load the last opened file. if ((Program.Settings.AutoLoadLastFile) && (!string.IsNullOrWhiteSpace(Program.Settings.LastEditorFile))) { LoadLastFile(); } // Set up the default pane. _splash.UpdateVersion(Resources.GOREDIT_TEXT_LOAD_DEFAULT); ContentManagement.DefaultContentType = typeof(DefaultContent); ContentManagement.LoadDefaultContentPane(); // Keep showing the splash screen. while ((GorgonTiming.SecondsSinceStart - startTime) < 3) { Thread.Sleep(1); } FadeSplashScreen(false, 250.0f); // Bring up our application form. MainForm.Show(); } catch (Exception ex) { GorgonDialogs.ErrorBox(null, ex); if ((MainForm != null) && (!MainForm.IsDisposed)) { MainForm.Dispose(); } // Signal quit. Gorgon.Quit(); } finally { if (_splash != null) { _splash.Dispose(); } _splash = null; } }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { // Set our default cursor. _currentCursor = Resources.hand_icon; // Load our raw input plug-in assembly. Gorgon.PlugIns.LoadPlugInAssembly(Program.PlugInPath + "Gorgon.Input.Raw.DLL"); // Create our input factory. _factory = GorgonInputFactory.CreateInputFactory("GorgonLibrary.Input.GorgonRawPlugIn"); // Get our device info. // This function is called when the factory is created. // However, I'm calling it here just to show that it exists. _factory.EnumerateDevices(); // Validate, even though it's highly unlikely we'll run into these. if (_factory.PointingDevices.Count == 0) { GorgonDialogs.ErrorBox(this, "There were no mice detected on this computer. The application requires a mouse."); Gorgon.Quit(); } if (_factory.KeyboardDevices.Count == 0) { GorgonDialogs.ErrorBox(this, "There were no keyboards detected on this computer. The application requires a keyboard."); Gorgon.Quit(); } // Get our input devices. CreateMouse(); CreateKeyboard(); CreateJoystick(); // When the display area changes size, update the spray effect // and limit the mouse. panelDisplay.Resize += panelDisplay_Resize; // Set the initial range of the mouse cursor. _mouse.PositionRange = Rectangle.Round(panelDisplay.ClientRectangle); // Set up our spray object. _spray = new Spray(panelDisplay.ClientSize); _cursor = new MouseCursor(panelDisplay) { Hotspot = new Point(-16, -3) }; // Set up our idle method. Gorgon.ApplicationIdleLoopMethod = Idle; } catch (Exception ex) { // We do this here instead of just calling the dialog because this // function will send the exception to the Gorgon log file. GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(this, ex)); Gorgon.Quit(); } }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { // Load the XInput plug-in assembly. Gorgon.PlugIns.LoadPlugInAssembly(Program.PlugInPath + "Gorgon.Input.XInput.dll"); // Create our factory. _factory = GorgonInputFactory.CreateInputFactory("GorgonLibrary.Input.GorgonXInputPlugIn"); // Ensure that we have and XBox controller to work with. if (_factory.JoystickDevices.Count == 0) { GorgonDialogs.ErrorBox(this, "No XBox controllers were found on this system.\nThis example requires an XBox controller."); Gorgon.Quit(); return; } // Enumerate the active joysticks. We'll only take 3 of the 4 available xbox controllers. _joystick = new GorgonJoystick[3]; _stickPosition = new PointF[_joystick.Count]; _sprayStates = new SprayCan[_joystick.Count]; for (int i = 0; i < _joystick.Count; i++) { var joystick = _factory.CreateJoystick(this, _factory.JoystickDevices[i].Name); // Set a dead zone on the joystick. // A dead zone will stop input from the joystick until it reaches the outside // of the specified coordinates. joystick.DeadZone.X = new GorgonRange(joystick.Capabilities.XAxisRange.Minimum / 4, joystick.Capabilities.XAxisRange.Maximum / 4); joystick.DeadZone.Y = new GorgonRange(joystick.Capabilities.YAxisRange.Minimum / 4, joystick.Capabilities.YAxisRange.Maximum / 4); joystick.DeadZone.SecondaryX = new GorgonRange(joystick.Capabilities.XAxisRange.Minimum / 128, joystick.Capabilities.XAxisRange.Maximum / 128); joystick.DeadZone.SecondaryY = new GorgonRange(joystick.Capabilities.YAxisRange.Minimum / 128, joystick.Capabilities.YAxisRange.Maximum / 128); _joystick[i] = joystick; // Start at a random spot. _stickPosition[i] = new Point(GorgonRandom.RandomInt32(64, panelDisplay.ClientSize.Width - 64), GorgonRandom.RandomInt32(64, panelDisplay.ClientSize.Height - 64)); // Turn off spray for all controllers. _sprayStates[i] = new SprayCan(joystick, i); } // Check for connected controllers. while (!_joystick.Any(item => item.IsConnected)) { if (MessageBox.Show(this, "There are no XBox controllers connected.\nPlease plug in an XBox controller and click OK.", "No Controllers", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.Cancel) { continue; } Gorgon.Quit(); return; } // Get the graphics interface for our panel. _surface = new DrawingSurface(panelDisplay); // Set up our idle loop. Gorgon.ApplicationIdleLoopMethod += Idle; } catch (Exception ex) { // We do this here instead of just calling the dialog because this // function will send the exception to the Gorgon log file. GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(this, ex)); Gorgon.Quit(); } }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load"></see> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { // Load the plug-in assembly. Gorgon.PlugIns.LoadPlugInAssembly(Program.PlugInPath + "Gorgon.Input.Raw.DLL"); // Create the factory. _input = GorgonInputFactory.CreateInputFactory("GorgonLibrary.Input.GorgonRawPlugIn"); // Create mouse, keyboard and joystick interfaces. _keyboard = _input.CreateKeyboard(this); _mouse = _input.CreatePointingDevice(this); _joystickList = new GorgonJoystick[_input.JoystickDevices.Count]; // Create each joystick interface. for (int i = 0; i < _joystickList.Length; i++) { _joystickList[i] = _input.CreateJoystick(this, _input.JoystickDevices[i].Name); } // Create the graphics interface. _graphics = new GorgonGraphics(); _screen = _graphics.Output.CreateSwapChain("Screen", new GorgonSwapChainSettings { Size = Settings.Default.Resolution, Format = BufferFormat.R8G8B8A8_UIntNormal, IsWindowed = Settings.Default.IsWindowed }); // For the backup image. Used to make it as large as the monitor that we're on. Screen currentScreen = Screen.FromHandle(Handle); // Relocate the window to the center of the screen. Location = new Point(currentScreen.Bounds.Left + (currentScreen.WorkingArea.Width / 2) - ClientSize.Width / 2, currentScreen.Bounds.Top + (currentScreen.WorkingArea.Height / 2) - ClientSize.Height / 2); // Create the 2D renderer. _2D = _graphics.Output.Create2DRenderer(_screen); // Create the text font. _font = _graphics.Fonts.CreateFont("Arial_9pt", new GorgonFontSettings { FontFamilyName = "Arial", FontStyle = FontStyle.Bold, AntiAliasingMode = FontAntiAliasMode.AntiAlias, FontHeightMode = FontHeightMode.Points, Size = 9.0f }); // Enable the mouse. Cursor = Cursors.Cross; _mouse.Enabled = true; _mouse.Exclusive = false; _mouse.PointingDeviceDown += MouseInput; _mouse.PointingDeviceMove += MouseInput; _mouse.PointingDeviceWheelMove += _mouse_PointingDeviceWheelMove; // Enable the keyboard. _keyboard.Enabled = true; _keyboard.Exclusive = false; _keyboard.KeyDown += _keyboard_KeyDown; // Create text sprite. _messageSprite = _2D.Renderables.CreateText("Message", _font, "Using mouse and keyboard."); _messageSprite.Color = Color.Black; // Create a back buffer. _backBuffer = _graphics.Output.CreateRenderTarget("BackBuffer", new GorgonRenderTarget2DSettings { Width = _screen.Settings.Width, Height = _screen.Settings.Height, Format = BufferFormat.R8G8B8A8_UIntNormal }); _backBuffer.Clear(Color.White); var settings = new GorgonTexture2DSettings { Width = currentScreen.Bounds.Width, Height = currentScreen.Bounds.Height, Format = BufferFormat.R8G8B8A8_UIntNormal, Usage = BufferUsage.Staging }; // Clear our backup image to white to match our primary screen. _backupImage = _graphics.Textures.CreateTexture("Backup", settings); using (var textureData = _backupImage.Lock(BufferLockFlags.Write)) { textureData.Data.Fill(0xFF); } // Set the mouse range and position. Cursor.Position = PointToScreen(new Point(Settings.Default.Resolution.Width / 2, Settings.Default.Resolution.Height / 2)); _mouse.SetPosition(Settings.Default.Resolution.Width / 2, Settings.Default.Resolution.Height / 2); _mouse.SetPositionRange(0, 0, Settings.Default.Resolution.Width, Settings.Default.Resolution.Height); // Set gorgon events. _screen.AfterStateTransition += (sender, args) => { OnResizeEnd(EventArgs.Empty); // Reposition after a state change. if (!args.IsWindowed) { return; } Screen monitor = Screen.FromHandle(Handle); Location = new Point(monitor.Bounds.Left + (monitor.WorkingArea.Width / 2) - args.Width / 2, monitor.Bounds.Top + (monitor.WorkingArea.Height / 2) - args.Height / 2); Cursor.Position = PointToScreen(Point.Round(_mouse.Position)); }; Gorgon.ApplicationIdleLoopMethod = Gorgon_Idle; } catch (Exception ex) { GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(this, ex)); Gorgon.Quit(); } }