Game Development Community

Tiles disappearing after minimizing and restoring game window

by Diego Santos Leao - GameBlox Studio · in Torque X 2D · 02/24/2010 (2:00 pm) · 6 replies

If you pick a Torque X game and minimize and restore it, any tiles that were on the screen will disappear (like they were never there). If you unload and reload another level (in my case, that is) you will get an exception in this method of TorqueCoreMaterialsEffectManager.cs:

static public void SetParameter(EffectParameter param, Texture value)
{
if (param != null)
param.SetValue(value); <----------- right here
}

Exception description: "Cannot access a disposed object.rnObject name: 'Texture2D'."

Is this bug known? Is it being fixed?

It was an old bug that a purple screen (or other color) would appear if you minimize and restore a window in Torque X (2D). I thought that problem had been fixed when I tried minimizing a game and it worked. Unfortunately I was wrong, the problem is only a little different and more restricted (to tilemaps) now.

It is utterly frustrating that bugs like this are being neglected for over two years.

===============================
Stack Trace:
===============================
at Microsoft.Xna.Framework.Helpers.CheckDisposed(Object obj, IntPtr pComPtr)
   at Microsoft.Xna.Framework.Graphics.EffectParameter.SetValue(Texture value)
   at GarageGames.Torque.Materials.EffectManager.SetParameter(EffectParameter param, Texture value) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreMaterialsEffectManager.cs:line 238
   at GarageGames.Torque.Materials.SimpleMaterial._SetupGlobalParameters(SceneRenderState srs, MaterialInstanceData materialData) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreMaterialsSimpleMaterial.cs:line 163
   at GarageGames.Torque.Materials.RenderMaterial.SetupEffect(SceneRenderState srs, MaterialInstanceData materialData) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreMaterialsRenderMaterial.cs:line 267
   at GarageGames.Torque.Materials.MaterialManager.PreloadMaterials(SceneRenderState srs) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreMaterialsMaterialManager.cs:line 260
   at GarageGames.Torque.Core.Xml.TorqueSceneData.Load(String filename, List`1 extraAssemblies) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreCoreXmlTorqueSceneData.cs:line 324
   at GarageGames.Torque.Core.Xml.TorqueSceneData.Load(String filename) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreCoreXmlTorqueSceneData.cs:line 250
   at GarageGames.Torque.GameUtil.SceneLoader.Load(String sceneFileName) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreGameUtilSceneLoader.cs:line 119
   at GarageGames.Torque.PlatformerDemo.Game.LoadLevel(Int32 levelNumber) in E:PlatformerKitGameGame.cs:line 399
   at GarageGames.Torque.PlatformerDemo.Game.LoadNextLevel() in E:PlatformerKitGameGame.cs:line 425
   at GarageGames.Torque.PlatformerDemo.Components.KillerComponents.NextLevelTriggerComponent.OnEnter(T2DSceneObject ourObject, T2DSceneObject theirObject) in E:PlatformerKitGameComponentsKillerComponentsNextLevelTriggerComponent.cs:line 29
   at GarageGames.Torque.T2D.T2DTriggerComponent.ProcessTick(Move move, Single elapsed) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0Torque2DT2DComponentsT2DTriggerComponent.cs:line 249
   at GarageGames.Torque.Sim.ProcessList._TickObjects(Single tickSec) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreSimProcessList.cs:line 715
   at GarageGames.Torque.Sim.ProcessList.AdvanceTick(Single floatMS) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreSimProcessList.cs:line 505
   at GarageGames.Torque.XNA.TorqueEngineComponent._UpdateSim(String eventName, Single elapsed) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreXNATorqueEngineComponent.cs:line 877
   at GarageGames.Torque.Core.TorqueEvent`1._Trigger(Delegate d) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreCoreTorqueEvent.cs:line 85
   at GarageGames.Torque.Core.TorqueEventManager._TriggerEvent(TorqueEventBase ev) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreCoreTorqueEvent.cs:line 636
   at GarageGames.Torque.Core.TorqueEventManager.MgrProcessEvents() in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreCoreTorqueEvent.cs:line 477
   at GarageGames.Torque.Core.TorqueEventManager.ProcessEvents() in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreCoreTorqueEvent.cs:line 315
   at GarageGames.Torque.XNA.TorqueEngineComponent.Update(GameTime gameTime) in C:GGTorque X 2D Pro 3.1.4v3.1.4.0TorqueCoreXNATorqueEngineComponent.cs:line 483
   at Microsoft.Xna.Framework.Game.Update(GameTime gameTime)
   at GarageGames.Torque.PlatformerDemo.Game.Update(GameTime gameTime) in E:PlatformerKitGameGame.cs:line 388
   at Microsoft.Xna.Framework.Game.Tick()
   at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
   at Microsoft.Xna.Framework.GameHost.OnIdle()
   at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
   at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Microsoft.Xna.Framework.WindowsGameHost.Run()
   at Microsoft.Xna.Framework.Game.Run()
   at GarageGames.Torque.PlatformerDemo.GameStarter.Main(String[] args) in E:PlatformerKitGameMain.cs:line 11

#2
02/24/2010 (5:12 pm)
It doesn't work... Thanks Duncan, but although this fix does make the tilemap reappear, when I try to unload the current level and load the next one, I get an exception "Object reference not set to an instance of an object" at TorqueCoreCoreTorqueEvent.cs, in the following method:

/// <summary>
        /// Stop callbacks to passed delegate and given key.
        /// </summary>
        /// <typeparam name="T">Type of data payload.</typeparam>
        /// <param name="silenceThese">Event to stop listening to.</param>
        /// <param name="forThisDelegate">Delegate to unregister.</param>
        /// <param name="key">Key to match.</param>
        public void MgrSilenceEvents<T>(TorqueEvent<T> silenceThese, TorqueEventDelegate<T> forThisDelegate, object key)
        {
            ConsumerNode exists;

            if (_eventConsumers.TryGetValue(silenceThese.Name, out exists))
            {
                ConsumerNode toss = null;

                if (exists._consumer == (Delegate)forThisDelegate) //<--- exception occurs here!
                {
                    _eventConsumers[silenceThese.Name] = exists._next;
                    toss = exists;
                }
                else
                {
                    while (exists._next != null)
                    {
                        if (exists._next._consumer == (Delegate)forThisDelegate && exists._next._key == key)
                        {
                            toss = exists._next;
                            exists._next = toss._next;
                            break;
                        }

                 ...

To make things worse, it happens even if I don't minimize the screen. It only happens when there is a tilemap on the screen. I have given up solving problems on TX, as there are just too many, and it requires a lot of XNA specific knowledge...

This is the stack trace:

at GarageGames.Torque.Core.TorqueEventManager.MgrSilenceEvents[T](TorqueEvent`1 silenceThese, TorqueEventDelegate`1 forThisDelegate, Object key)
   at GarageGames.Torque.Core.TorqueEventManager.SilenceEvents[T](TorqueEvent`1 silenceThese, TorqueEventDelegate`1 forThisDelegate)
   at GarageGames.Torque.T2D.T2DTileLayer.Dispose()
   at GarageGames.Torque.Core.Xml.TorqueSceneData._UnloadObjects(List`1 list)
   at GarageGames.Torque.Core.Xml.TorqueSceneData.Unload()
   at GarageGames.Torque.GameUtil.SceneLoader.Unload(TorqueSceneData scene)
   at GarageGames.Torque.GameUtil.SceneLoader.UnloadLastScene()
   at GarageGames.Torque.PlatformerDemo.Game.LoadInterLevel() in E:PlatformerDemoGameGame.cs:line 357
   at GarageGames.Torque.PlatformerDemo.Components.Callers.InterLevelCallerComponent.ProcessTick(Move move, Single dt) in E:PlatformerDemoGameComponentsCallersInterLevelCallerComponent.cs:line 23
   at GarageGames.Torque.Sim.ProcessList._TickObjects(Single tickSec)
   at GarageGames.Torque.Sim.ProcessList.AdvanceTick(Single floatMS)
   at GarageGames.Torque.XNA.TorqueEngineComponent._UpdateSim(String eventName, Single elapsed)
   at GarageGames.Torque.Core.TorqueEvent`1._Trigger(Delegate d)
   at GarageGames.Torque.Core.TorqueEventManager._TriggerEvent(TorqueEventBase ev)
   at GarageGames.Torque.Core.TorqueEventManager.MgrProcessEvents()
   at GarageGames.Torque.Core.TorqueEventManager.ProcessEvents()
   at GarageGames.Torque.XNA.TorqueEngineComponent.Update(GameTime gameTime)
   at Microsoft.Xna.Framework.Game.Update(GameTime gameTime)
   at GarageGames.Torque.PlatformerDemo.Game.Update(GameTime gameTime) in E:PlatformerDemoGameGame.cs:line 388
   at Microsoft.Xna.Framework.Game.Tick()
   at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
   at Microsoft.Xna.Framework.GameHost.OnIdle()
   at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
   at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Microsoft.Xna.Framework.WindowsGameHost.Run()
   at Microsoft.Xna.Framework.Game.Run()
   at GarageGames.Torque.PlatformerDemo.GameStarter.Main(String[] args) in E:PlatformerDemoGameMain.cs:line 11
#3
02/24/2010 (5:39 pm)
In T2DTileLayer try overriding the OnRegister() method and silencing the event from there instead of in Dispose().
#4
02/24/2010 (6:31 pm)
When I do that (removing that line from Dispose and pasting it into OnRegister), the tilemap starts to disappear again when I minimize.

Am I suposed to add it in the first line of the method, after a specific line or anywhere?
#5
02/25/2010 (9:30 am)
Ah sorry, typo... I meant OnUnregister()
#6
02/25/2010 (10:15 am)
Working perfectly now :)
Thanks _a lot_!

This is the way it ended up:
public T2DTileLayer()
        {
            TorqueEventManager.ListenEvents<bool>(GFXDevice.Instance.DeviceReset, OnDeviceReset); 
            Components.AddComponent(new T2DCollisionComponent());
            Collision.InstallImage(new TileLayerCollisionImage());
        }



        public override void OnUnregister()
        {
            base.OnUnregister();
            TorqueEventManager.SilenceEvents<bool>(GFXDevice.Instance.DeviceReset, OnDeviceReset);

        }