void ICmpUpdatable.OnUpdate() { // Prepare a list of camera controllers, if we don't already have one if (this.cameraControllers == null) { this.cameraControllers = new List <ICameraController>(); // Use Reflection to get a list of all ICameraController classes TypeInfo[] availableCameraControllerTypes = DualityApp.GetAvailDualityTypes(typeof(ICameraController)).ToArray(); foreach (TypeInfo camControllerType in availableCameraControllerTypes) { // Create an instance of each class ICameraController camController = camControllerType.CreateInstanceOf() as ICameraController; if (camController != null) { this.cameraControllers.Add(camController); } } } // Allow the user to select which camera controller to use if (DualityApp.Keyboard.KeyHit(Key.Number1)) { this.ActiveCameraController--; } if (DualityApp.Keyboard.KeyHit(Key.Number2)) { this.ActiveCameraController++; } if (DualityApp.Keyboard.KeyHit(Key.M)) { this.movementHistoryActive = !this.movementHistoryActive; } // Is there a Gamepad we can use? GamepadInput gamepad = DualityApp.Gamepads.FirstOrDefault(g => g.IsAvailable); if (gamepad != null) { if (gamepad.ButtonHit(GamepadButton.A)) { this.ActiveCameraController--; } if (gamepad.ButtonHit(GamepadButton.B)) { this.ActiveCameraController++; } if (gamepad.ButtonHit(GamepadButton.X)) { this.movementHistoryActive = !this.movementHistoryActive; } } // Every 100 ms, draw one visual log entry to document movement if (this.movementHistoryActive) { this.movementHistoryTimer += Time.MillisecondsPerFrame * Time.TimeMult; if (this.movementHistoryTimer > 100.0f) { this.movementHistoryTimer -= 100.0f; Vector2 targetPos = this.targetObj.Transform.Pos.Xy; Vector2 cameraPos = this.mainCameraObj.Transform.Pos.Xy; VisualLogs.Default.DrawPoint( targetPos.X, targetPos.Y, 0.0f) .WithColor(new ColorRgba(255, 128, 0)) .KeepAlive(3000.0f); VisualLogs.Default.DrawPoint( cameraPos.X, cameraPos.Y, 0.0f) .WithColor(new ColorRgba(0, 255, 0)) .KeepAlive(3000.0f); } } }
[Test] public void SwitchTo() { // Set up some objects Scene scene = new Scene(); Scene scene2 = new Scene(); // Switch to the first Scene regularly { Scene.SwitchTo(scene); Assert.AreEqual(Scene.Current, scene); } // Switch to the second during update { GameObject obj = new GameObject("SwitchObject"); var switchComponent = new UpdateSwitchToSceneComponent { Target = scene2 }; obj.AddComponent(switchComponent); scene.AddObject(obj); DualityApp.Update(); Assert.False(switchComponent.Switched); Assert.AreEqual(Scene.Current, scene2); Scene.SwitchTo(scene); Assert.AreEqual(Scene.Current, scene); } // Switch to the second while entering { Scene.SwitchTo(null); GameObject obj = new GameObject("SwitchObject"); var switchComponent = new InitSwitchToSceneComponent { Target = scene2 }; obj.AddComponent(switchComponent); scene.AddObject(obj); Scene.SwitchTo(scene); DualityApp.Update(); Assert.False(switchComponent.Switched); Assert.AreEqual(Scene.Current, scene2); Scene.SwitchTo(scene); Assert.AreEqual(Scene.Current, scene); } // Switch to the second while leaving { Scene.SwitchTo(null); GameObject obj = new GameObject("SwitchObject"); var switchComponent = new ShutdownSwitchToSceneComponent { Target = scene2 }; obj.AddComponent(switchComponent); scene.AddObject(obj); Scene.SwitchTo(scene); DualityApp.Update(); Assert.False(switchComponent.Switched); Assert.AreEqual(Scene.Current, scene2); Scene.SwitchTo(scene); Assert.AreEqual(Scene.Current, scene); } // Clean up scene.Dispose(); scene2.Dispose(); }
public static void Main(string[] args) { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; bool isDebugging = System.Diagnostics.Debugger.IsAttached || args.Contains(DualityApp.CmdArgDebug); bool isRunFromEditor = args.Contains(DualityApp.CmdArgEditor); bool isProfiling = args.Contains(DualityApp.CmdArgProfiling); if (isDebugging || isRunFromEditor) { ShowConsole(); } // Set up console logging Log.AddGlobalOutput(new ConsoleLogOutput()); // Set up file logging StreamWriter logfileWriter = null; TextWriterLogOutput logfileOutput = null; try { logfileWriter = new StreamWriter("logfile.txt"); logfileWriter.AutoFlush = true; logfileOutput = new TextWriterLogOutput(logfileWriter); Log.AddGlobalOutput(logfileOutput); } catch (Exception e) { Log.Core.WriteWarning("Text Logfile unavailable: {0}", Log.Exception(e)); } // Set up a global exception handler to log errors AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // Write initial log message before actually booting Duality Log.Core.Write("Running DualityLauncher with flags: {1}{0}", Environment.NewLine, new[] { isDebugging ? "Debugging" : null, isProfiling ? "Profiling" : null, isRunFromEditor ? "RunFromEditor" : null }.NotNull().ToString(", ")); // Initialize the Duality core DualityApp.Init( DualityApp.ExecutionEnvironment.Launcher, DualityApp.ExecutionContext.Game, new DefaultPluginLoader(), args); // Open up a new window WindowOptions options = new WindowOptions { Width = DualityApp.UserData.GfxWidth, Height = DualityApp.UserData.GfxHeight, ScreenMode = isDebugging ? ScreenMode.Window : DualityApp.UserData.GfxMode, RefreshMode = (isDebugging || isProfiling) ? RefreshMode.NoSync : DualityApp.UserData.RefreshMode, Title = DualityApp.AppData.AppName, SystemCursorVisible = isDebugging || DualityApp.UserData.SystemCursorVisible }; using (INativeWindow window = DualityApp.OpenWindow(options)) { // Load the starting Scene Scene.SwitchTo(DualityApp.AppData.StartScene); // Enter the applications update / render loop window.Run(); // Shut down the Duality core DualityApp.Terminate(); } // Clean up the log file if (logfileWriter != null) { Log.RemoveGlobalOutput(logfileOutput); logfileWriter.Flush(); logfileWriter.Close(); logfileWriter = null; logfileOutput = null; } }
void ICmpUpdatable.OnUpdate() { GamepadInput gamepad = DualityApp.Gamepads[0]; Vector2 moveDir = gamepad.LeftThumbstick.Normalized; float moveSpeed = MathF.Clamp((gamepad.LeftThumbstick.Length - 0.3f) / 0.7f, 0.0f, 1.0f); Vector2 lookDir = gamepad.RightThumbstick.Normalized; float lookIntensity = MathF.Clamp((gamepad.RightThumbstick.Length - 0.3f) / 0.7f, 0.0f, 1.0f); this.controlTarget.ThrusterActivity = moveDir * moveSpeed; this.controlTarget.RotateActivity = lookDir * lookIntensity; if (gamepad.RightTrigger > 0.5f) { this.controlTarget.FireWeapons(); } if (gamepad.ButtonHit(GamepadButton.Start)) { if (musicInstance != null && !musicInstance.Disposed) { musicInstance.Lowpass = 1.0f; } Scene.Reload(); } if (gamepad.ButtonHit(GamepadButton.Back)) { DualityApp.Terminate(); } if (musicInstance == null || musicInstance.Disposed) { musicInstance = DualityApp.Sound.PlaySound(this.backgroundMusic); musicInstance.Looped = true; musicInstance.Volume = 0.4f; musicInstance.BeginFadeIn(5.0f); } else { float targetLowPass = 1.0f; if (this.controlTarget == null || this.controlTarget.Disposed) { targetLowPass = 0.05f; } else { targetLowPass = 1.0f; } float changeDir = MathF.Sign(targetLowPass - musicInstance.Lowpass); float changeAbs = MathF.Abs(targetLowPass - musicInstance.Lowpass); if (changeAbs <= 0.01f) { musicInstance.Lowpass = targetLowPass; } else { musicInstance.Lowpass += changeDir * Time.TimeMult * Time.SPFMult / 8.0f; } } }
/// <summary> /// Sets up all necessary OpenGL resources for this RenderTarget. /// </summary> public void SetupOpenGLRes() { DualityApp.GuardSingleThreadState(); if (this.targetInfo == null || this.targetInfo.Count == 0) { return; } int highestAALevel = MathF.RoundToInt(MathF.Log(MathF.Max(MaxRenderTargetSamples, 1.0f), 2.0f)); int targetAALevel = highestAALevel; switch (this.multisampling) { case AAQuality.High: targetAALevel = highestAALevel; break; case AAQuality.Medium: targetAALevel = highestAALevel / 2; break; case AAQuality.Low: targetAALevel = highestAALevel / 4; break; case AAQuality.Off: targetAALevel = 0; break; } int targetSampleCount = MathF.RoundToInt(MathF.Pow(2.0f, targetAALevel)); OpenTK.Graphics.GraphicsMode sampleMode = DualityApp.AvailableModes.LastOrDefault(m => m.Samples <= targetSampleCount) ?? DualityApp.AvailableModes.Last(); this.samples = sampleMode.Samples; #region Setup FBO & RBO: Non-multisampled if (this.samples == 0) { // Generate FBO if (this.glFboId == 0) { GL.Ext.GenFramebuffers(1, out this.glFboId); } GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, this.glFboId); // Attach textures int oglWidth = 0; int oglHeight = 0; for (int i = 0; i < this.targetInfo.Count; i++) { if (!this.targetInfo[i].target.IsAvailable) { continue; } FramebufferAttachment attachment = (FramebufferAttachment)((int)FramebufferAttachment.ColorAttachment0Ext + i); GL.Ext.FramebufferTexture2D( FramebufferTarget.FramebufferExt, attachment, TextureTarget.Texture2D, this.targetInfo[i].target.Res.OglTexId, 0); oglWidth = this.targetInfo[i].target.Res.TexelWidth; oglHeight = this.targetInfo[i].target.Res.TexelHeight; } // Generate Depth Renderbuffer if (this.glRboIdDepth == 0) { GL.Ext.GenRenderbuffers(1, out this.glRboIdDepth); } GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, this.glRboIdDepth); GL.Ext.RenderbufferStorage(RenderbufferTarget.RenderbufferExt, RenderbufferStorage.DepthComponent24, oglWidth, oglHeight); GL.Ext.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, RenderbufferTarget.RenderbufferExt, this.glRboIdDepth); // Check status FramebufferErrorCode status = GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt); if (status != FramebufferErrorCode.FramebufferCompleteExt) { Log.Core.WriteError("Can't create RenderTarget '{0}'. Incomplete Framebuffer: {1}", this.path, status); } GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, 0); GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); } #endregion #region Setup FBO & RBO: Multisampled if (this.samples > 0) { // Generate texture target FBO if (this.glFboId == 0) { GL.Ext.GenFramebuffers(1, out this.glFboId); } GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, this.glFboId); // Attach textures int oglWidth = 0; int oglHeight = 0; for (int i = 0; i < this.targetInfo.Count; i++) { if (!this.targetInfo[i].target.IsAvailable) { continue; } FramebufferAttachment attachment = (FramebufferAttachment)((int)FramebufferAttachment.ColorAttachment0Ext + i); GL.Ext.FramebufferTexture2D( FramebufferTarget.FramebufferExt, attachment, TextureTarget.Texture2D, this.targetInfo[i].target.Res.OglTexId, 0); oglWidth = this.targetInfo[i].target.Res.TexelWidth; oglHeight = this.targetInfo[i].target.Res.TexelHeight; } // Check status FramebufferErrorCode status = GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt); if (status != FramebufferErrorCode.FramebufferCompleteExt) { Log.Core.WriteError("Can't create RenderTarget '{0}'. Incomplete Texture Framebuffer: {1}", this.path, status); } // Generate rendering FBO if (this.glFboIdMSAA == 0) { GL.Ext.GenFramebuffers(1, out this.glFboIdMSAA); } GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, this.glFboIdMSAA); // Attach color renderbuffers for (int i = 0; i < this.targetInfo.Count; i++) { if (!this.targetInfo[i].target.IsAvailable) { continue; } TargetInfo info = this.targetInfo[i]; FramebufferAttachment attachment = (FramebufferAttachment)((int)FramebufferAttachment.ColorAttachment0Ext + i); RenderbufferStorage rbColorFormat = TexFormatToRboFormat(info.target.Res.PixelFormat); if (info.glRboIdColorMSAA == 0) { GL.GenRenderbuffers(1, out info.glRboIdColorMSAA); } GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, info.glRboIdColorMSAA); GL.Ext.RenderbufferStorageMultisample((ExtFramebufferMultisample)(int)RenderbufferTarget.RenderbufferExt, this.samples, (ExtFramebufferMultisample)(int)rbColorFormat, oglWidth, oglHeight); GL.Ext.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, attachment, RenderbufferTarget.RenderbufferExt, info.glRboIdColorMSAA); this.targetInfo[i] = info; } GL.Ext.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0); // Attach depth renderbuffer if (this.glRboIdDepth == 0) { GL.Ext.GenRenderbuffers(1, out this.glRboIdDepth); } GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, this.glRboIdDepth); GL.Ext.RenderbufferStorageMultisample((ExtFramebufferMultisample)(int)RenderbufferTarget.RenderbufferExt, this.samples, (ExtFramebufferMultisample)(int)RenderbufferStorage.DepthComponent24, oglWidth, oglHeight); GL.Ext.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, RenderbufferTarget.RenderbufferExt, this.glRboIdDepth); GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, 0); // Check status status = GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt); if (status != FramebufferErrorCode.FramebufferCompleteExt) { Log.Core.WriteError("Can't create RenderTarget '{0}'. Incomplete Multisample Framebuffer: {1}", this.path, status); } GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); } #endregion }
protected override void OnShown(EventArgs e) { base.OnShown(e); this.itemListing.ClearSelection(); this.itemListing.Model = this.Model; this.itemListing.BeginUpdate(); this.Model.Nodes.Clear(); if (this.SelectType) { this.Text = "Select a Type"; foreach (TypeInfo type in DualityApp.GetAvailDualityTypes(this.FilteredType).Where(t => !t.IsAbstract && !t.IsInterface)) { this.Model.Nodes.Add(new ReferenceNode(type)); } } else if (typeof(GameObject).IsAssignableFrom(this.FilteredType)) { this.Text = "Select a GameObject"; foreach (GameObject currentObject in Scene.Current.AllObjects) { this.Model.Nodes.Add(new ReferenceNode(currentObject)); } } else if (typeof(Component).IsAssignableFrom(this.FilteredType)) { this.Text = string.Format("Select a {0} Component", this.FilteredType.GetTypeCSCodeName()); foreach (Component currentComponent in Scene.Current.FindComponents(this.FilteredType)) { this.Model.Nodes.Add(new ReferenceNode(currentComponent)); } } else { Type filteredType = typeof(Resource); if (this.FilteredType.IsGenericType) { filteredType = this.FilteredType.GetGenericArguments()[0]; this.Text = string.Format("Select a {0} Resource", filteredType.GetTypeCSCodeName(true)); } else { this.Text = "Select a Resource"; } foreach (IContentRef contentRef in ContentProvider.GetAvailableContent(filteredType)) { this.Model.Nodes.Add(new ReferenceNode(contentRef)); } } foreach (var treeNodeAdv in this.itemListing.AllNodes) { ReferenceNode node = treeNodeAdv.Tag as ReferenceNode; treeNodeAdv.IsExpanded = true; if (node != null && node.Origin == this.ResourcePath) { this.itemListing.SelectedNode = treeNodeAdv; } } this.itemListing.EndUpdate(); this.txtFilterInput.Focus(); }
private static void Main(string[] args) { ConsoleUtils.TryEnableUnicode(); // Try to render Jazz2 logo if (ConsoleImage.RenderFromManifestResource("ConsoleImage.udl", out int imageTop) && imageTop >= 0) { int width = Console.BufferWidth; // Show version number in the right corner string appVersion = "v" + Game.App.AssemblyVersion; int currentCursorTop = Console.CursorTop; Console.SetCursorPosition(width - appVersion.Length - 2, imageTop + 1); Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine(appVersion); Console.ResetColor(); Console.CursorTop = currentCursorTop; } // Override working directory try { Environment.CurrentDirectory = Jazz2.Game.App.AssemblyPath; } catch (Exception ex) { Log.Write(LogType.Warning, "Cannot override working directory: " + ex); } // Process parameters int port; if (!TryRemoveArg(ref args, "/port:", out port)) { port = 0; } string overrideHostname; if (!TryRemoveArg(ref args, "/override-hostname:", out overrideHostname)) { overrideHostname = null; } string name; if (!TryRemoveArg(ref args, "/name:", out name) || string.IsNullOrWhiteSpace(name)) { name = "Unnamed server"; } int minPlayers; if (!TryRemoveArg(ref args, "/min-players:", out minPlayers)) { minPlayers = 0; } int maxPlayers; if (!TryRemoveArg(ref args, "/max-players:", out maxPlayers)) { maxPlayers = 0; } string levelName; if (!TryRemoveArg(ref args, "/level:", out levelName)) { levelName = "unknown/battle2"; } string levelTypeRaw; MultiplayerLevelType levelType; if (!TryRemoveArg(ref args, "/level-type:", out levelTypeRaw) || !Enum.TryParse(levelTypeRaw, out levelType)) { levelType = MultiplayerLevelType.Battle; } string configPath; if (!TryRemoveArg(ref args, "/config:", out configPath)) { if (File.Exists("Jazz2.Server.default")) { configPath = "Jazz2.Server.default"; } else { configPath = null; } } bool startUnloaded = TryRemoveArg(ref args, "/unloaded"); bool isPrivate = TryRemoveArg(ref args, "/private"); bool enableUPnP = TryRemoveArg(ref args, "/upnp"); // Initialization Version v = Assembly.GetEntryAssembly().GetName().Version; byte neededMajor = (byte)v.Major; byte neededMinor = (byte)v.Minor; byte neededBuild = (byte)v.Build; Log.Write(LogType.Info, "Starting server..."); Log.PushIndent(); // Start game server DualityApp.Init(DualityApp.ExecutionContext.Server, null, args); AsyncManager.Init(); gameServer = new GameServer(); if (overrideHostname != null) { try { gameServer.OverrideHostname(overrideHostname); } catch { Log.Write(LogType.Error, "Cannot set override public hostname!"); } } gameServer.Run(configPath, port, name, minPlayers, maxPlayers, isPrivate, enableUPnP, neededMajor, neededMinor, neededBuild); Log.PopIndent(); if (!startUnloaded) { if (gameServer.ActivePlaylistIndex == -1) { gameServer.ChangeLevel(levelName, levelType); } else { gameServer.ChangeLevelFromPlaylist(gameServer.ActivePlaylistIndex); } Log.Write(LogType.Info, "Ready to play!"); } else { Log.Write(LogType.Verbose, "Server is unloaded."); } Log.Write(LogType.Info, ""); // Check for updates Updater.CheckUpdates(OnCheckUpdates); // Processing of console commands ProcessConsoleCommands(); // Shutdown Log.Write(LogType.Info, "Closing..."); gameServer.Dispose(); }
private static void Initialize() { DualityApp.InitBackend(out prefBack); DualityApp.Terminating += OnDualityAppTerminating; }
private static void OnDualityAppTerminating(object sender, EventArgs e) { DualityApp.Terminating -= OnDualityAppTerminating; DualityApp.ShutdownBackend(ref prefBack); }
private void OnExitPressed() { DualityApp.Terminate(); }
public override void Execute(Duality.GameObject inSource, object inParameter) { DualityApp.Terminate(); }
[Test] public void TransformHierarchyVelocity() { // In this test case, we'll set up a parent and a child transform // to see if changes to the parent affect the child transforms velocity value GameObject parentObj = new GameObject("Parent"); GameObject obj = new GameObject("Child", parentObj); Transform parentTransform = parentObj.AddComponent <Transform>(); Transform transform = obj.AddComponent <Transform>(); // Since velocity values are only updated after the frame ends, we need // a full scene setup to simulate an update cycle using (Scene testScene = new Scene()) { // Setup and enter the scene testScene.AddObject(parentObj); Scene.SwitchTo(testScene, true); DualityApp.Update(true); // Identity parent and a moving child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = Vector3.Zero; transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.Vel, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // Transformed parent and a moving child parentTransform.Pos = new Vector3(1.0f, 2.0f, 3.0f); parentTransform.Angle = MathF.DegToRad(90.0f); parentTransform.Scale = 2.0f; transform.Pos = Vector3.Zero; transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(0.0f, 2.0f, 0.0f), transform.Vel, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // Moving parent and a transformed child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = 0.0f; transform.Scale = 1.0f; parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); DualityApp.Update(true); AssertEqual(new Vector3(0.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.Vel, "Absolute child velocity"); // Moving parent and a transformed, moving child parentTransform.Pos = Vector3.Zero; parentTransform.Angle = 0.0f; parentTransform.Scale = 1.0f; transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); transform.Angle = 0.0f; transform.Scale = 1.0f; transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); transform.TurnBy(MathF.DegToRad(90.0f)); parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); DualityApp.Update(true); AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); AssertEqual(new Vector3(2.0f, 0.0f, 0.0f), transform.Vel, "Absolute child velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // ToDo: Fix how Transform adds up velocity due to parent transform // rotation in order to make the test cases below work. The current // implementation only works with small per-frame rotations, not big, // sudden ones. // Moving parent and a transformed child //parentTransform.Pos = Vector3.Zero; //parentTransform.Angle = 0.0f; //parentTransform.Scale = 1.0f; //transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); //transform.Angle = 0.0f; //transform.Scale = 1.0f; // //parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); //parentTransform.TurnBy(MathF.DegToRad(90.0f)); //DualityApp.Update(true); // //AssertEqual(new Vector3(0.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); //AssertEqual(new Vector3(0.0f, 1.0f, 0.0f), transform.Vel, "Absolute child velocity"); //AssertEqual(MathF.DegToRad(0.0f), transform.RelativeAngleVel, "Relative child angle velocity"); //AssertEqual(MathF.DegToRad(90.0f), transform.AngleVel, "Absolute child angle velocity"); // Moving parent and a transformed, moving child //parentTransform.Pos = Vector3.Zero; //parentTransform.Angle = 0.0f; //parentTransform.Scale = 1.0f; //transform.Pos = new Vector3(1.0f, 0.0f, 0.0f); //transform.Angle = 0.0f; //transform.Scale = 1.0f; // //transform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); //transform.TurnBy(MathF.DegToRad(90.0f)); //parentTransform.MoveBy(new Vector3(1.0f, 0.0f, 0.0f)); //parentTransform.TurnBy(MathF.DegToRad(90.0f)); //DualityApp.Update(true); // //AssertEqual(new Vector3(1.0f, 0.0f, 0.0f), transform.RelativeVel, "Relative child velocity"); //AssertEqual(new Vector3(-1.0f, 3.0f, 0.0f), transform.Vel, "Absolute child velocity"); //AssertEqual(MathF.DegToRad(90.0f), transform.RelativeAngleVel, "Relative child angle velocity"); //AssertEqual(MathF.DegToRad(180.0f), transform.AngleVel, "Absolute child angle velocity"); } }
/// <summary> /// Compiles the shader. This is done automatically when loading the shader /// or attaching it to a <see cref="Duality.Resources.ShaderProgram"/>. /// </summary> public void Compile() { DualityApp.GuardSingleThreadState(); if (this.compiled) { return; } var source = this.source; if (String.IsNullOrEmpty(source)) { return; } #if __ANDROID__ source = ExtractPlatformShader(source, "__ANDROID__"); #else source = ExtractPlatformShader(source, "__PC__"); #endif if (this.glShaderId == 0) { this.glShaderId = GL.CreateShader(this.OglShaderType); } GL.ShaderSource(this.glShaderId, source); GL.CompileShader(this.glShaderId); int result; GL.GetShader(this.glShaderId, ShaderParameter.CompileStatus, out result); if (result == 0) { string infoLog = GL.GetShaderInfoLog(this.glShaderId); Log.Core.WriteError("Error compiling {0}. InfoLog:\n{1}", this.OglShaderType, infoLog); return; } this.compiled = true; // Remove comments from source code before extracting variables string sourceWithoutComments; { const string blockComments = @"/\*(.*?)\*/"; const string lineComments = @"//(.*?)\r?\n"; const string strings = @"""((\\[^\n]|[^""\n])*)"""; const string verbatimStrings = @"@(""[^""]*"")+"; sourceWithoutComments = Regex.Replace(source, blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, me => { if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) { return(me.Value.StartsWith("//") ? Environment.NewLine : ""); } // Keep the literal strings return(me.Value); }, RegexOptions.Singleline); } // Scan remaining code chunk for variable declarations List <ShaderVarInfo> varInfoList = new List <ShaderVarInfo>(); string[] lines = sourceWithoutComments.Split(new[] { ';', '\n' }, StringSplitOptions.RemoveEmptyEntries); ShaderVarInfo varInfo = new ShaderVarInfo(); foreach (string t in lines) { string curLine = t.TrimStart(); if (curLine.StartsWith("uniform")) { varInfo.scope = ShaderVarScope.Uniform; } else if (curLine.StartsWith("attribute")) { varInfo.scope = ShaderVarScope.Attribute; } else { continue; } string[] curLineSplit = curLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); switch (curLineSplit[1].ToUpper()) { case "FLOAT": varInfo.type = ShaderVarType.Float; break; case "VEC2": varInfo.type = ShaderVarType.Vec2; break; case "VEC3": varInfo.type = ShaderVarType.Vec3; break; case "VEC4": varInfo.type = ShaderVarType.Vec4; break; case "MAT2": varInfo.type = ShaderVarType.Mat2; break; case "MAT3": varInfo.type = ShaderVarType.Mat3; break; case "MAT4": varInfo.type = ShaderVarType.Mat4; break; case "INT": varInfo.type = ShaderVarType.Int; break; case "SAMPLER2D": varInfo.type = ShaderVarType.Sampler2D; break; } curLineSplit = curLineSplit[2].Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries); varInfo.name = curLineSplit[0]; varInfo.arraySize = (curLineSplit.Length > 1) ? int.Parse(curLineSplit[1]) : 1; varInfo.glVarLoc = -1; varInfoList.Add(varInfo); } this.varInfo = varInfoList.ToArray(); }
public static bool Play() { if (state == SandboxState.Playing) { return(true); } // If the current Scene is unsaved when entering sandbox mode, ask whether this should be done before if (askUnsaved && state == SandboxState.Inactive && Scene.Current.IsRuntimeResource && !Scene.Current.IsEmpty) { askUnsaved = false; DialogResult result = MessageBox.Show(DualityEditorApp.MainForm, GeneralRes.Msg_EnterSandboxUnsavedScene_Desc, GeneralRes.Msg_EnterSandboxUnsavedScene_Caption, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (result == DialogResult.Cancel) { return(false); } if (result == DialogResult.Yes) { DualityEditorApp.SaveCurrentScene(false); } } stateChange = true; if (state == SandboxState.Paused) { OnUnpausingSandbox(); state = SandboxState.Playing; } else { OnEnteringSandbox(); // Save the current scene DualityEditorApp.SaveCurrentScene(); ContentRef <Scene> activeScene = Scene.Current; startScene = activeScene; // Leave the current Scene Scene.SwitchTo(null, true); // Force later Scene reload by disposing it if (!activeScene.IsRuntimeResource) { activeScene.Res.Dispose(); } state = SandboxState.Playing; DualityApp.SwitchExecutionContext(DualityApp.ExecutionContext.Game); // (Re)Load Scene - now in playing context Scene.SwitchTo(activeScene); } OnSandboxStateChanged(); stateChange = false; return(true); }
protected override void OnFocusedChanged(EventArgs e) { base.OnFocusedChanged(e); DualityApp.OnFocusChanged(this.Focused); }
/// <summary> /// Advances this physics world simulation by <paramref name="timestep"/> seconds. /// /// If <see cref="IsFixedTimestep"/> is true, this may actually simulate multiple smaller /// steps, or none at all while accumulating the internal fixed step timer. Otherwise, /// it will perform exactly one physics stept with the specified <paramref name="timestep"/>. /// </summary> /// <param name="timestep"></param> public void Simulate(float timestep) { bool physUpdate = false; double physBegin = Time.MainTimer.TotalSeconds; if (this.IsFixedTimestep) { this.fixedStepTimer += timestep; int iterations = 0; if (this.fixedStepTimer >= this.fixedStepPeriod) { Profile.TimeUpdatePhysics.BeginMeasure(); DualityApp.EditorGuard(() => { double timeUpdateBegin = Time.MainTimer.TotalSeconds; while (this.fixedStepTimer >= this.fixedStepPeriod) { // Catch up on updating progress this.UpdateNativeSettings(); this.native.Step(this.fixedStepPeriod); this.fixedStepTimer -= this.fixedStepPeriod; iterations++; double timeSpent = Time.MainTimer.TotalSeconds - timeUpdateBegin; if (timeSpent >= Time.SecondsPerFrame * 10.0f) { break; // Emergency exit } } }); physUpdate = true; Profile.TimeUpdatePhysics.EndMeasure(); } } else { Profile.TimeUpdatePhysics.BeginMeasure(); DualityApp.EditorGuard(() => { this.UpdateNativeSettings(); this.native.Step(timestep); if (timestep == 0.0f) { this.native.ClearForces(); // Complete freeze? Clear forces, so they don't accumulate. } this.fixedStepTimer = this.fixedStepPeriod; }); physUpdate = true; Profile.TimeUpdatePhysics.EndMeasure(); } double physTime = Time.MainTimer.TotalSeconds - physBegin; // Apply Farseers internal measurements to Duality if (physUpdate) { Profile.TimeUpdatePhysicsAddRemove.Set(1000.0f * this.native.AddRemoveTime / Stopwatch.Frequency); Profile.TimeUpdatePhysicsContacts.Set(1000.0f * this.native.ContactsUpdateTime / Stopwatch.Frequency); Profile.TimeUpdatePhysicsContinous.Set(1000.0f * this.native.ContinuousPhysicsTime / Stopwatch.Frequency); Profile.TimeUpdatePhysicsController.Set(1000.0f * this.native.ControllersUpdateTime / Stopwatch.Frequency); Profile.TimeUpdatePhysicsSolve.Set(1000.0f * this.native.SolveUpdateTime / Stopwatch.Frequency); } // Update low fps physics state if (!this.lowFramerateMode) { this.lowFramerateMode = Time.UnscaledDeltaTime > Time.SecondsPerFrame && physTime > Time.UnscaledDeltaTime * 0.85f; } else { this.lowFramerateMode = !(Time.UnscaledDeltaTime < Time.SecondsPerFrame * 0.9f || physTime < Time.UnscaledDeltaTime * 0.6f); } }
void ICmpUpdatable.OnUpdate() { //Obter da scene o objecto ShipBlock (bloco ativo) GameObject theShipObject = Duality.Resources.Scene.Current.FindGameObject("ShipBlock"); RigidBody body = theShipObject.GetComponent<RigidBody>(); //Transform transformComponent = this.GameObj.GetComponent<Transform>(); Transform transformComponent = theShipObject.GetComponent<Transform>(); //position.X = 0; position.Y = 382; Vector2 targetMovement = Vector2.Zero; //Tecla ESC para sair do jogo if (DualityApp.Keyboard[Key.Escape]) { DualityApp.Terminate(); } //Se em Modo Inicial if (isInit) { //Se pressionar tecla SPACE, aplicar impulso e muda estado inical=false if (DualityApp.Keyboard[Key.Space]) { isInit = false; model.applyForce(); model.setTextLabel("", false); } else { return; } } //Tecla P para Pausa if (DualityApp.Keyboard[Key.P]) { if (!isPause) { isPause = true; Time.Freeze(); } else { isPause = false; Time.Resume(); } } //Tecla cursor - Esq ou Dir if (DualityApp.Keyboard[Key.Left]) { targetMovement = -Vector2.UnitX; } else if (DualityApp.Keyboard[Key.Right]) { targetMovement = Vector2.UnitX; } //Aplicar movimento do Bloco model.moveBlock(theShipObject,body,targetMovement); //Validar localizacao da Bola model.validateBallPosition(); }
private static void Application_Idle(object sender, EventArgs e) { Application.Idle -= Application_Idle; // Trigger global event loop idle event. OnEventLoopIdling(); // Perform some global operations, if no modal dialog is open if (mainWindow.Visible && mainWindow.CanFocus) { // Trigger global editor idle event. OnEditorIdling(); // Trigger autosave after a while /*if (autosaveFrequency != AutosaveFrequency.Disabled) { * TimeSpan timeSinceLastAutosave = DateTime.Now - autosaveLast; * if ((autosaveFrequency == AutosaveFrequency.OneHour && timeSinceLastAutosave.TotalMinutes > 60) || * (autosaveFrequency == AutosaveFrequency.ThirtyMinutes && timeSinceLastAutosave.TotalMinutes > 30) || * (autosaveFrequency == AutosaveFrequency.TenMinutes && timeSinceLastAutosave.TotalMinutes > 10)) { * SaveAllProjectData(); * autosaveLast = DateTime.Now; * } * }*/ } // Update Duality engine var watch = new System.Diagnostics.Stopwatch(); while (AppStillIdle) { watch.Restart(); if (!isSuspended) { bool fixedSingleStep = /*Sandbox.TakeSingleStep()*/ true; try { DualityApp.EditorUpdate( editorObjects.ActiveObjects.Concat(updateObjects), fixedSingleStep /*|| (Sandbox.State == SandboxState.Playing && !Sandbox.IsFreezed)*/, fixedSingleStep); updateObjects.Clear(); } catch (Exception exception) { Console.WriteLine("An error occurred during a core update: {0}", /*LogFormat.Exception(*/ exception /*)*/); } OnUpdatingEngine(); } // Perform a buffer swap PerformBufferSwap(); // Give the processor a rest if we have the time, don't use 100% CPU while (watch.Elapsed.TotalSeconds < 0.01d) { // Sleep a little System.Threading.Thread.Sleep(1); // App wants to do something? Stop waiting. if (!AppStillIdle) { break; } } } Application.Idle += Application_Idle; }
void ICmpUpdatable.OnUpdate() { // If the object we're controlling has been destroyed, forget about it if (this.controlObj != null && this.controlObj.Disposed) { this.controlObj = null; } // See what player inputs there are to handle if (this.input == null) { this.input = new InputMapping(); } bool hasInputMethod = this.input.Method != InputMethod.Unknown; if (this.controlObj != null) { this.input.Update(this.controlObj.GameObj.Transform); } else { this.input.Update(null); } // Spawn the player object for the first time when input is detected if (this.controlObj != null && this.input.Method != InputMethod.Unknown && !hasInputMethod) { // Find an alive player or determine that no one has started playing yet bool gameAlreadyOver = false; Player alivePlayer = Player.AlivePlayers.FirstOrDefault(); if (alivePlayer != null) { // Move near already alive player Vector3 alivePlayerPos = alivePlayer.controlObj.GameObj.Transform.Pos; this.controlObj.GameObj.Transform.Pos = alivePlayerPos; } else if (Player.AllPlayers.Any(p => p != this && p.IsPlaying)) { // If we don't have an alive player, but do have playing players, the game must be already over. gameAlreadyOver = true; } else { // Move near initial spawn point this.controlObj.GameObj.Transform.Pos = SpawnPoint.SpawnPos; } // Spawn for the first time / enter the game if (!gameAlreadyOver) { this.controlObj.GameObj.Active = true; } } // Manage the object this player is supposed to control if (this.controlObj != null) { if (this.hasReachedGoal) { RigidBody body = this.controlObj.GameObj.RigidBody; SpriteRenderer sprite = this.controlObj.GameObj.GetComponent <SpriteRenderer>(); // If we've reached the goal, update the final animation and do nothing else float goalAnim = MathF.Clamp(((float)Time.GameTimer.TotalMilliseconds - this.goalReachTime) / 2000.0f, 0.0f, 1.0f); // Don't move body.LinearVelocity *= MathF.Pow(0.9f, Time.TimeMult); this.controlObj.TargetAngleRatio = 0.1f; this.controlObj.TargetThrust = Vector2.Zero; // Fade out if (sprite.CustomMaterial == null) { sprite.CustomMaterial = new BatchInfo(sprite.SharedMaterial.Res); } sprite.CustomMaterial.Technique = DrawTechnique.SharpAlpha; sprite.ColorTint = sprite.ColorTint.WithAlpha(1.0f - goalAnim); // Spawn a goal reached effect if (goalAnim > 0.2f && this.goalEffect != null && this.goalEffectInstance == null) { this.goalEffectInstance = this.goalEffect.Res.Instantiate(this.controlObj.GameObj.Transform.Pos); Scene.Current.AddObject(this.goalEffectInstance); } // Let the ship disappear if (goalAnim >= 1.0f) { this.controlObj.GameObj.Active = false; } } else if (this.controlObj.Active) { // Apply control inputs to the controlled object this.controlObj.TargetAngle = this.input.ControlLookAngle; this.controlObj.TargetAngleRatio = this.input.ControlLookSpeed; this.controlObj.TargetThrust = this.input.ControlMovement; if (this.input.ControlFireWeapon) { this.controlObj.FireWeapon(); } } else if (hasInputMethod && Player.IsAnyPlayerAlive && !this.hasReachedGoal) { // Respawn when possible this.respawnTime += Time.MsPFMult * Time.TimeMult; if (this.respawnTime > RespawnDelay) { // Move near alive player Player alivePlayer = Player.AlivePlayers.FirstOrDefault(); Vector3 alivePlayerPos = alivePlayer.controlObj.GameObj.Transform.Pos; this.controlObj.GameObj.Transform.Pos = alivePlayerPos; // Respawn this.respawnTime = 0.0f; this.controlObj.Revive(); } } } // Quit the game when requested if (this.input.ControlQuit) { DualityApp.Terminate(); } // If it's game over, allow to restart the game GameOverScreen gameOverScreen = Scene.Current.FindComponent <GameOverScreen>(); if (gameOverScreen != null && gameOverScreen.HasGameEnded) { if (this.input.ControlStart) { Scene.Reload(); } } }
public static void Main(string[] args) { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; isDebugging = System.Diagnostics.Debugger.IsAttached || args.Contains(DualityApp.CmdArgDebug); isRunFromEditor = args.Contains(DualityApp.CmdArgEditor); isProfiling = args.Contains(DualityApp.CmdArgProfiling); if (isDebugging || isRunFromEditor) { ShowConsole(); } DualityApp.Init(DualityApp.ExecutionEnvironment.Launcher, DualityApp.ExecutionContext.Game, args); int windowWidth = DualityApp.UserData.GfxWidth; int windowHeight = DualityApp.UserData.GfxHeight; bool isFullscreen = (DualityApp.UserData.GfxMode == ScreenMode.Fullscreen || DualityApp.UserData.GfxMode == ScreenMode.Native) && !isDebugging; if (DualityApp.UserData.GfxMode == ScreenMode.Native && !isDebugging) { windowWidth = DisplayDevice.Default.Width; windowHeight = DisplayDevice.Default.Height; } using (DualityLauncher launcherWindow = new DualityLauncher( windowWidth, windowHeight, DualityApp.DefaultMode, DualityApp.AppData.AppName, isFullscreen ? GameWindowFlags.Fullscreen : GameWindowFlags.Default)) { // Retrieve icon from executable file and set it as window icon string executablePath = System.IO.Path.GetFullPath(System.Reflection.Assembly.GetExecutingAssembly().Location); if (System.IO.File.Exists(executablePath)) { launcherWindow.Icon = System.Drawing.Icon.ExtractAssociatedIcon(executablePath); } // Go into native fullscreen mode if (DualityApp.UserData.GfxMode == ScreenMode.FullWindow && !isDebugging) { launcherWindow.WindowState = WindowState.Fullscreen; } if (DualityApp.UserData.GfxMode == ScreenMode.FixedWindow) { launcherWindow.WindowBorder = WindowBorder.Fixed; } else if (DualityApp.UserData.GfxMode == ScreenMode.Window) { launcherWindow.WindowBorder = WindowBorder.Resizable; } // Specify additional window settings and initialize default content launcherWindow.MakeCurrent(); launcherWindow.CursorVisible = isDebugging || DualityApp.UserData.SystemCursorVisible; launcherWindow.VSync = (isProfiling || isDebugging || DualityApp.UserData.RefreshMode != RefreshMode.VSync) ? VSyncMode.Off : VSyncMode.On; DualityApp.TargetResolution = new Vector2(launcherWindow.ClientSize.Width, launcherWindow.ClientSize.Height); DualityApp.TargetMode = launcherWindow.Context.GraphicsMode; ContentProvider.InitDefaultContent(); // Input setup DualityApp.Mouse.Source = new GameWindowMouseInputSource(launcherWindow.Mouse, launcherWindow.SetMouseDeviceX, launcherWindow.SetMouseDeviceY); DualityApp.Keyboard.Source = new GameWindowKeyboardInputSource(launcherWindow.Keyboard); // Debug Logs Log.Core.Write("Graphics window initialized: {0}Mode: {1}{0}VSync: {2}{0}SwapInterval: {3}{0}Flags: {4}{0}", Environment.NewLine, launcherWindow.Context.GraphicsMode, launcherWindow.VSync, launcherWindow.Context.SwapInterval, new[] { isDebugging ? "Debugging" : null, isProfiling ? "Profiling" : null, isRunFromEditor ? "RunFromEditor" : null }.NotNull().ToString(", ")); // Load the starting Scene Scene.SwitchTo(DualityApp.AppData.StartScene); // Run the DualityApp launcherWindow.Run(); // Shut down the DualityApp DualityApp.Terminate(); } }
protected override void OnUnload(EventArgs e) { base.OnUnload(e); DualityApp.Terminate(); }
public override void DoAction() { base.DoAction(); DualityApp.Terminate(); }
/// <summary> /// Loads the specified <see cref="Duality.Resources.Pixmap">Pixmaps</see> pixel data. /// </summary> /// <param name="basePixmap">The <see cref="Duality.Resources.Pixmap"/> that is used as pixel data source.</param> /// <param name="sizeMode">Specifies behaviour in case the source data has non-power-of-two dimensions.</param> public void LoadData(ContentRef <Pixmap> basePixmap, SizeMode sizeMode) { DualityApp.GuardSingleThreadState(); if (this.glTexId == 0) { this.glTexId = GL.GenTexture(); } this.needsReload = false; this.basePixmap = basePixmap; this.texSizeMode = sizeMode; int lastTexId; GL.GetInteger(GetPName.TextureBinding2D, out lastTexId); GL.BindTexture(TextureTarget.Texture2D, this.glTexId); if (!this.basePixmap.IsExplicitNull) { Pixmap.Layer pixelData = null; Pixmap basePixmapRes = this.basePixmap.IsAvailable ? this.basePixmap.Res : null; if (basePixmapRes != null) { pixelData = basePixmapRes.ProcessedLayer; this.atlas = basePixmapRes.Atlas != null?basePixmapRes.Atlas.ToArray() : null; } if (pixelData == null) { pixelData = Pixmap.Checkerboard.Res.MainLayer; } this.AdjustSize(pixelData.Width, pixelData.Height); this.SetupOpenGLRes(); if (this.texSizeMode != SizeMode.NonPowerOfTwo && (this.pxWidth != this.texWidth || this.pxHeight != this.texHeight)) { if (this.texSizeMode == SizeMode.Enlarge) { Pixmap.Layer oldData = pixelData; pixelData = oldData.CloneResize(this.texWidth, this.texHeight); // Fill border pixels manually - that's cheaper than ColorTransparentPixels here. oldData.DrawOnto(pixelData, BlendMode.Solid, this.pxWidth, 0, 1, this.pxHeight, this.pxWidth - 1, 0); oldData.DrawOnto(pixelData, BlendMode.Solid, 0, this.pxHeight, this.pxWidth, 1, 0, this.pxHeight - 1); pixelData.Dispose(); } else { pixelData = pixelData.CloneRescale(this.texWidth, this.texHeight, Pixmap.FilterMethod.Linear); } } // Load pixel data to video memory if (Compressed && pixelData.CompressedData != null) { GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.CompressedRgbaS3tcDxt5Ext, pixelData.Width, pixelData.Height, 0, pixelData.CompressedImageSize, pixelData.CompressedData); } else { GL.TexImage2D(TextureTarget.Texture2D, 0, this.pixelformat, pixelData.Width, pixelData.Height, 0, GLPixelFormat.Rgba, PixelType.UnsignedByte, pixelData.Data); } // Adjust atlas to represent UV coordinates if (this.atlas != null) { Vector2 scale; scale.X = this.uvRatio.X / this.pxWidth; scale.Y = this.uvRatio.Y / this.pxHeight; for (int i = 0; i < this.atlas.Length; i++) { this.atlas[i].X *= scale.X; this.atlas[i].W *= scale.X; this.atlas[i].Y *= scale.Y; this.atlas[i].H *= scale.Y; } } } else { this.atlas = null; this.AdjustSize(this.size.X, this.size.Y); this.SetupOpenGLRes(); } GL.BindTexture(TextureTarget.Texture2D, lastTexId); if (this.keepPixmapDataResident == false && basePixmap.IsLoaded) { basePixmap.Res.Dispose(); } }
/// <summary> /// Schedules this object for disposal at the end of the current update cycle. /// </summary> /// <param name="obj"></param> public static void DisposeLater(this IManageableObject obj) { DualityApp.DisposeLater(obj); }
private static System.Collections.IEnumerable async_RenameContentRefs(ProcessingBigTaskDialog.WorkerInterface state) { var renameData = state.Data as List <ResourceRenamedEventArgs>; int totalCounter = 0; int fileCounter = 0; // Rename in static application data state.StateDesc = "DualityApp Data"; yield return(null); DualityApp.LoadAppData(); DualityApp.LoadUserData(); state.Progress += 0.04f; yield return(null); totalCounter += async_RenameContentRefs_Perform(DualityApp.AppData, renameData); totalCounter += async_RenameContentRefs_Perform(DualityApp.UserData, renameData); state.Progress += 0.02f; yield return(null); DualityApp.SaveAppData(); DualityApp.SaveUserData(); state.Progress += 0.04f; yield return(null); // Special case: Current Scene in sandbox mode if (Sandbox.IsActive) { // Because changes we'll do will be discarded when leaving the sandbox we'll need to // do it the hard way - manually load an save the file. state.StateDesc = "Current Scene"; yield return(null); Scene curScene = Resource.Load <Scene>(Scene.CurrentPath, null, false); fileCounter = async_RenameContentRefs_Perform(curScene, renameData); totalCounter += fileCounter; if (fileCounter > 0) { curScene.Save(Scene.CurrentPath, false); } } // Special case: Current Scene NOT in sandbox mode, but still unsaved else if (Scene.Current.IsRuntimeResource) { state.StateDesc = "Current Scene"; yield return(null); fileCounter = async_RenameContentRefs_Perform(Scene.Current, renameData); if (fileCounter > 0) { DualityEditorApp.NotifyObjPropChanged(null, new ObjectSelection(Scene.Current.AllObjects)); } totalCounter += fileCounter; } // Rename in actual content var targetResTypes = renameData.Any(e => e.IsDirectory) ? null : renameData.Select(e => e.ContentType).ToArray(); var loadedContent = ContentProvider.GetLoadedContent <Resource>(); var reloadContent = new List <IContentRef>(); List <string> resFiles = Resource.GetResourceFiles(); List <Resource> modifiedRes = new List <Resource>(); foreach (string file in resFiles) { // Early-out, if this kind of Resource isn't able to reference the renamed Resource if (targetResTypes != null) { Type resType = Resource.GetTypeByFileName(file); bool canReferenceRes = false; foreach (Type targetType in targetResTypes) { if (ReflectionHelper.CanReferenceResource(resType, targetType)) { canReferenceRes = true; break; } } if (!canReferenceRes) { state.Progress += 0.9f / resFiles.Count; continue; } } // Set displayed name state.StateDesc = file; yield return(null); // Wasn't loaded before? Unload it later to keep the memory footprint small. bool wasLoaded = loadedContent.Any(r => r.Path == file); // Keep in mind that this operation is performed while Duality content was // in an inconsistent state. Loading Resources now may lead to wrong data. // Because the ContentRefs might be wrong right now. if (wasLoaded) { // Retrieve already loaded content IContentRef cr = ContentProvider.RequestContent(file); state.Progress += 0.45f / resFiles.Count; yield return(null); // Perform rename and flag unsaved / modified fileCounter = async_RenameContentRefs_Perform(cr.Res, renameData); if (fileCounter > 0) { modifiedRes.Add(cr.Res); } } else { // Load content without initializing it Resource res = Resource.Load <Resource>(file, null, false); state.Progress += 0.45f / resFiles.Count; yield return(null); // Perform rename and save it without making it globally available fileCounter = async_RenameContentRefs_Perform(res, renameData); if (fileCounter > 0) { res.Save(null, false); } } totalCounter += fileCounter; state.Progress += 0.45f / resFiles.Count; yield return(null); } // Notify the editor about modified Resources if (modifiedRes.Count > 0) { DualityEditorApp.NotifyObjPropChanged(null, new ObjectSelection(modifiedRes)); } }
private static void Main(string[] args) { // Override working directory try { Environment.CurrentDirectory = AssemblyPath; } catch (Exception ex) { Console.WriteLine("Cannot override current directory: " + ex); } DualityApp.Init(DualityApp.ExecutionContext.Game, new DefaultAssemblyLoader(), args); ScreenMode screenMode; switch (Preferences.Get <int>("Screen", 0)) { default: case 0: screenMode = ScreenMode.Window; break; case 1: screenMode = ScreenMode.FullWindow; break; } RefreshMode refreshMode = (RefreshMode)Preferences.Get <int>("RefreshMode", (int)RefreshMode.VSync); i18n.Language = Preferences.Get <string>("Language", "en"); ContentResolver.Current.Init(); using (INativeWindow window = DualityApp.OpenWindow(new WindowOptions { Title = AssemblyTitle, RefreshMode = refreshMode, Size = LevelRenderSetup.TargetSize, ScreenMode = screenMode })) { ContentResolver.Current.InitPostWindow(); current = new App(window); bool suppressMainMenu = false; #if MULTIPLAYER for (int i = 0; i < args.Length; i++) { if (args[i].StartsWith("/connect:", StringComparison.InvariantCulture)) { int idx = args[i].LastIndexOf(':', 10); if (idx == -1) { continue; } int port; if (!int.TryParse(args[i].Substring(idx + 1), NumberStyles.Any, CultureInfo.InvariantCulture, out port)) { continue; } try { System.Net.IPAddress ip = Lidgren.Network.NetUtility.Resolve(args[i].Substring(9, idx - 9)); current.ConnectToServer(new System.Net.IPEndPoint(ip, port)); suppressMainMenu = true; } catch { // Nothing to do... } } } #endif if (!suppressMainMenu) { current.PlayCinematics("intro", endOfStream => { current.ShowMainMenu(endOfStream); }); } window.Run(); } DualityApp.Terminate(); // ToDo: Linux-specific workaround Environment.Exit(0); }
private System.Collections.IEnumerable async_ChangeDataFormat(ProcessingBigTaskDialog.WorkerInterface state) { state.StateDesc = "DualityApp Data"; yield return(null); DualityApp.LoadAppData(); DualityApp.LoadUserData(); DualityApp.LoadMetaData(); state.Progress += 0.05f; yield return(null); DualityApp.SaveAppData(); DualityApp.SaveUserData(); DualityApp.SaveMetaData(); state.Progress += 0.05f; yield return(null); // Special case: Current Scene in sandbox mode if (Sandbox.IsActive && !string.IsNullOrEmpty(Scene.CurrentPath)) { // Because changes we'll do will be discarded when leaving the sandbox we'll need to // do it the hard way - manually load an save the file. state.StateDesc = "Current Scene"; yield return(null); Scene curScene = Resource.Load <Scene>(Scene.CurrentPath, null, false); if (curScene != null) { curScene.Save(null, false); } } var loadedContent = ContentProvider.GetLoadedContent <Resource>(); List <string> resFiles = Resource.GetResourceFiles(); foreach (string file in resFiles) { if (Sandbox.IsActive && file == Scene.CurrentPath) { continue; // Skip current Scene in Sandbox } state.StateDesc = file; yield return(null); // Wasn't loaded before? Unload it later to keep the memory footprint small. bool wasLoaded = loadedContent.Any(r => r.Path == file); if (wasLoaded) { // Retrieve already loaded content var cr = ContentProvider.RequestContent(file); state.Progress += 0.45f / resFiles.Count; yield return(null); // Perform rename and flag unsaved / modified cr.Res.Save(); state.Progress += 0.45f / resFiles.Count; yield return(null); } else { // Load content without initializing it Resource res = Resource.Load <Resource>(file, null, false); state.Progress += 0.45f / resFiles.Count; yield return(null); // Perform rename and save it without making it globally available res.Save(null, false); state.Progress += 0.45f / resFiles.Count; yield return(null); } } }
public static void Main(string[] args) { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; isDebugging = System.Diagnostics.Debugger.IsAttached || args.Contains(DualityApp.CmdArgDebug); isRunFromEditor = args.Contains(DualityApp.CmdArgEditor); isProfiling = args.Contains(DualityApp.CmdArgProfiling); if (isDebugging || isRunFromEditor) { ShowConsole(); } DualityApp.Init(DualityApp.ExecutionEnvironment.Launcher, DualityApp.ExecutionContext.Game, args); using (DualityLauncher launcherWindow = new DualityLauncher( DualityApp.UserData.GfxWidth, DualityApp.UserData.GfxHeight, DualityApp.DefaultMode, DualityApp.AppData.AppName, (DualityApp.UserData.GfxMode == ScreenMode.Fullscreen && !isDebugging) ? GameWindowFlags.Fullscreen : GameWindowFlags.Default)) { DualityApp.UserDataChanged += launcherWindow.OnUserDataChanged; // Retrieve icon from executable file and set it as window icon string executablePath = System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase); launcherWindow.Icon = System.Drawing.Icon.ExtractAssociatedIcon(executablePath); // Go into native fullscreen mode if (DualityApp.UserData.GfxMode == ScreenMode.Native && !isDebugging) { launcherWindow.WindowState = WindowState.Fullscreen; } if (DualityApp.UserData.GfxMode == ScreenMode.FixedWindow) { launcherWindow.WindowBorder = WindowBorder.Fixed; } else if (DualityApp.UserData.GfxMode == ScreenMode.Window) { launcherWindow.WindowBorder = WindowBorder.Resizable; } // Initialize default content launcherWindow.MakeCurrent(); Log.Core.Write("OpenGL initialized"); Log.Core.PushIndent(); Log.Editor.Write("Vendor: {0}", GL.GetString(StringName.Vendor)); Log.Editor.Write("Version: {0}", GL.GetString(StringName.Version)); Log.Editor.Write("Renderer: {0}", GL.GetString(StringName.Renderer)); Log.Editor.Write("Shading language version: {0}", GL.GetString(StringName.ShadingLanguageVersion)); Log.Core.PopIndent(); if (ValidateMinimumGPUSpec() == false) { DualityApp.Terminate(); DisplayDevice.Default.RestoreResolution(); return; } DualityApp.TargetResolution = new Vector2(launcherWindow.ClientSize.Width, launcherWindow.ClientSize.Height); DualityApp.TargetMode = launcherWindow.Context.GraphicsMode; ContentProvider.InitDefaultContent(); // Input setup DualityApp.Mouse.Source = new GameWindowMouseInputSource(launcherWindow.Mouse, launcherWindow.SetMouseDeviceX, launcherWindow.SetMouseDeviceY); DualityApp.Keyboard.Source = new GameWindowKeyboardInputSource(launcherWindow.Keyboard); // Load the starting Scene Scene.SwitchTo(DualityApp.AppData.StartScene); // Run the DualityApp launcherWindow.CursorVisible = isDebugging || DualityApp.UserData.SystemCursorVisible; SetVSyncMode(launcherWindow); launcherWindow.Run(); // Shut down the DualityApp DualityApp.Terminate(); DisplayDevice.Default.RestoreResolution(); } }
/// <summary> /// Updates the Scene /// </summary> internal void Update() { if (!this.IsCurrent) { throw new InvalidOperationException("Can't update non-current Scene!"); } switchLock++; // Update physics bool physUpdate = false; double physBegin = Time.MainTimer.TotalMilliseconds; if (Scene.PhysicsFixedTime) { physicsAcc += Time.MsPFMult * Time.TimeMult; int iterations = 0; if (physicsAcc >= Time.MsPFMult) { Profile.TimeUpdatePhysics.BeginMeasure(); DualityApp.EditorGuard(() => { double timeUpdateBegin = Time.MainTimer.TotalMilliseconds; while (physicsAcc >= Time.MsPFMult) { // Catch up on updating progress FarseerPhysics.Settings.VelocityThreshold = PhysicsUnit.VelocityToPhysical * DualityApp.AppData.PhysicsVelocityThreshold; physicsWorld.Step(Time.SPFMult); physicsAcc -= Time.MsPFMult; iterations++; double timeSpent = Time.MainTimer.TotalMilliseconds - timeUpdateBegin; if (timeSpent >= Time.MsPFMult * 10.0f) { break; // Emergency exit } } }); physUpdate = true; Profile.TimeUpdatePhysics.EndMeasure(); } } else { Profile.TimeUpdatePhysics.BeginMeasure(); DualityApp.EditorGuard(() => { FarseerPhysics.Settings.VelocityThreshold = PhysicsUnit.VelocityToPhysical * Time.TimeMult * DualityApp.AppData.PhysicsVelocityThreshold; physicsWorld.Step(Time.TimeMult * Time.SPFMult); if (Time.TimeMult == 0.0f) { physicsWorld.ClearForces(); // Complete freeze? Clear forces, so they don't accumulate. } physicsAcc = PhysicsAccStart; }); physUpdate = true; Profile.TimeUpdatePhysics.EndMeasure(); } double physTime = Time.MainTimer.TotalMilliseconds - physBegin; // Apply Farseers internal measurements to Duality if (physUpdate) { Profile.TimeUpdatePhysicsAddRemove.Set(1000.0f * physicsWorld.AddRemoveTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsContacts.Set(1000.0f * physicsWorld.ContactsUpdateTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsContinous.Set(1000.0f * physicsWorld.ContinuousPhysicsTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsController.Set(1000.0f * physicsWorld.ControllersUpdateTime / System.Diagnostics.Stopwatch.Frequency); Profile.TimeUpdatePhysicsSolve.Set(1000.0f * physicsWorld.SolveUpdateTime / System.Diagnostics.Stopwatch.Frequency); } // Update low fps physics state if (!physicsLowFps) { physicsLowFps = Time.LastDelta > Time.MsPFMult && physTime > Time.LastDelta * 0.85f; } else { physicsLowFps = !(Time.LastDelta < Time.MsPFMult * 0.9f || physTime < Time.LastDelta * 0.6f); } // Update all GameObjects Profile.TimeUpdateScene.BeginMeasure(); DualityApp.EditorGuard(() => { this.UpdateComponents <ICmpUpdatable>(cmp => cmp.OnUpdate()); this.visibilityStrategy.Update(); }); Profile.TimeUpdateScene.EndMeasure(); // Perform a cleanup step to catch all DisposeLater calls from within the Scene update DualityApp.RunCleanup(); // Perform a scheduled Scene switch PerformScheduledSwitch(); switchLock--; }
public static void Main(string[] args) { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; isDebugging = System.Diagnostics.Debugger.IsAttached || args.Contains(DualityApp.CmdArgDebug); isRunFromEditor = args.Contains(DualityApp.CmdArgEditor); isProfiling = args.Contains(DualityApp.CmdArgProfiling); if (isDebugging || isRunFromEditor) { ShowConsole(); } DualityApp.Init(DualityApp.ExecutionEnvironment.Launcher, DualityApp.ExecutionContext.Game, args); using (DualityLauncher launcherWindow = new DualityLauncher( DualityApp.UserData.GfxWidth, DualityApp.UserData.GfxHeight, DualityApp.DefaultMode, DualityApp.AppData.AppName, (DualityApp.UserData.GfxMode == ScreenMode.Fullscreen && !isDebugging) ? GameWindowFlags.Fullscreen : GameWindowFlags.Default)) { // Retrieve icon from executable file and set it as window icon string executablePath = System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase); launcherWindow.Icon = System.Drawing.Icon.ExtractAssociatedIcon(executablePath); // Go into native fullscreen mode if (DualityApp.UserData.GfxMode == ScreenMode.Native && !isDebugging) { launcherWindow.WindowState = WindowState.Fullscreen; } if (DualityApp.UserData.GfxMode == ScreenMode.FixedWindow) { launcherWindow.WindowBorder = WindowBorder.Fixed; } else if (DualityApp.UserData.GfxMode == ScreenMode.Window) { launcherWindow.WindowBorder = WindowBorder.Resizable; } // Initialize default content launcherWindow.MakeCurrent(); DualityApp.TargetResolution = new Vector2(launcherWindow.Width, launcherWindow.Height); DualityApp.TargetMode = launcherWindow.Context.GraphicsMode; ContentProvider.InitDefaultContent(); // Input setup DualityApp.Mouse.Source = new OpenTKMouseInputSource(launcherWindow.Mouse, launcherWindow.SetMouseDeviceX, launcherWindow.SetMouseDeviceY); DualityApp.Keyboard.Source = new OpenTKKeyboardInputSource(launcherWindow.Keyboard); { // Initialize Joystick manually, since launcherWindow.Joysticks doesn't work for some reason launcherWindow.mainJoystickDriver = new OpenTK.Platform.Windows.WinMMJoystick(); if (launcherWindow.mainJoystickDriver != null && launcherWindow.mainJoystickDriver.Joysticks != null) { DualityApp.Joysticks.AddSource(launcherWindow.mainJoystickDriver.Joysticks.Select(j => new OpenTKJoystickInputSource(j))); } //DualityApp.Joysticks.AddSource(launcherWindow.Joysticks.Select(j => new OpenTKJoystickInputSource(j))); } // Load the starting Scene Scene.Current = DualityApp.AppData.StartScene.Res; // Run the DualityApp launcherWindow.CursorVisible = isDebugging || DualityApp.UserData.SystemCursorVisible; launcherWindow.VSync = (isProfiling || isDebugging) ? VSyncMode.Off : VSyncMode.On; // Don't limit frame rate when debugging. launcherWindow.Run(); // Shut down the DualityApp DualityApp.Terminate(); } }