XNA's ToggleFullScreen causes a lost device, such as errors

I am trying to write my first XNA game, and I would like to enable ALT + ENTER functionality to switch between full-screen and windowed modes. My game is extremely simple right now, nothing out of the ordinary. I can make it work in both windowed (default) and full-screen mode (by calling ToggleFullScreen) in my LoadContent function, and everything works fine.

However, when I call ToggleFullScreen in my update function using the same code, my game fails. If I run the window and switch to full screen mode, it seems to freeze, displaying only one frame and not accepting keyboard input (I need CTRL + ALT + DEL). If I started full-screen mode and switched to windowed mode, these are errors in DrawIndexedPrimitive with the message "The current vertex declaration does not include all the elements necessary for the current vertex shader. Normal0 is missing." (which is wrong, my vertex buffer is VertexPositionNormalTexture and contains data, and the status of GraphicsDevice is Normal).

Both of these problems seem to indicate a loss of connection with the device, but I cannot understand why. Every resource I found on the Internet says that turning on full-screen mode is as easy as calling the ToggleFullScreen function without mentioning rebooting devices or buffers. Any ideas?

Edit: here is some code with extraneous left:

    protected override void LoadContent()
    {
        graphics.PreferredBackBufferWidth = 800; 
        graphics.PreferredBackBufferHeight = 600;
        graphics.ToggleFullScreen();

        basicEffect = new BasicEffect(graphics.GraphicsDevice);
        // etc.
    }

    protected override void Update(GameTime gameTime)
    {
        if (k.IsKeyDown(Keys.Enter) && (k.IsKeyDown(Keys.LeftAlt) || k.IsKeyDown(Keys.RightAlt)) && !oldKeys.Contains(Keys.Enter)) {
            graphics.ToggleFullScreen();
            gameWorld.Refresh();
        }
         // update the world graphics; this fills my buffers
        GraphicsBuffers gb = gameWorld.Render(graphics.GraphicsDevice);
        graphics.GraphicsDevice.SetVertexBuffer(gb.vb, 0);
        graphics.GraphicsDevice.Indices = gb.ib;
   }

    protected override void Draw(GameTime gameTime)
    {
        // buffer reference again; these are persistent once filled in Update, they don't get created anew
        GraphicsBuffers gb = gameWorld.Render(graphics.GraphicsDevice);

        foreach (EffectPass effectPass in basicEffect.CurrentTechnique.Passes)
        {
            effectPass.Apply();

            basicEffect.Texture = textures;
            graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, gb.vb.VertexCount, 0, gb.ib.IndexCount / 3);
        }
    }
+3
source share
4 answers

The XNA Game class and its associated GraphicsDeviceManager are built around the concept that the update function is designed to update the state of your game, and the Draw function is intended to render this state. When you set the state of the graphics device during the Update function, you are violating this assumption.

. , Framework, . , , .. , Draw, , .

... . .

, . . Game.Draw :

, , . .

:

, . , . .

+4

App Hub , .

http://forums.create.msdn.com/forums/p/31773/182231.aspx

....

, . 3D, . 2D, , , SpriteBatch.Begin. 2D.

, , ( , , , Ziggyware, , 2D, , , - , WaybackMachine, , , 3D, , ).

+3

/ , :

/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    private Model grid;
    Model tank;
    int zoom = 1;

    Texture2D thumb;
    Vector2 position = new Vector2( 400, 240 );
    Vector2 velocity = new Vector2( -1, -1 );
    Matrix projection, view;
    public Game1()
    {
        graphics = new GraphicsDeviceManager( this );
        Content.RootDirectory = "Content";
    }

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here

        base.Initialize();

        projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4,
                                                                GraphicsDevice.Viewport.AspectRatio,
                                                                10,
                                                                20000 );

        view = Matrix.CreateLookAt( new Vector3( 1500, 550, 0 ) * zoom + new Vector3( 0, 150, 0 ),
                                          new Vector3( 0, 150, 0 ),
                                          Vector3.Up );

    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch( GraphicsDevice );

        // TODO: use this.Content to load your game content here
        thumb = Content.Load<Texture2D>( "GameThumbnail" );
        grid = Content.Load<Model>( "grid" );
        tank = Content.Load<Model>( "tank" );

    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// all content.
    /// </summary>
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    int ToggleDelay = 0;
    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update( GameTime gameTime )
    {
        // Allows the game to exit
        if ( GamePad.GetState( PlayerIndex.One ).Buttons.Back == ButtonState.Pressed )
            this.Exit();

        var kbState = Keyboard.GetState();
        if ( ( kbState.IsKeyDown( Keys.LeftAlt ) || kbState.IsKeyDown( Keys.RightAlt ) ) &&
             kbState.IsKeyDown( Keys.Enter ) && ToggleDelay <= 0 )
        {
            graphics.ToggleFullScreen();
            ToggleDelay = 1000;
        }

        if ( ToggleDelay >= 0 )
        {
            ToggleDelay -= gameTime.ElapsedGameTime.Milliseconds;
        }
        // TODO: Add your update logic here

        int x, y;
        x = (int)position.X;
        y = (int)position.Y;

        x += (int)velocity.X;
        y += (int)velocity.Y;
        if ( x > 480 - 64 )
            velocity.X = +1;
        if ( x < 0 )
            velocity.X = -1;
        if ( y < 0 )
            velocity.Y = +1;
        if ( y > 800 - 64 )
            velocity.Y = -1;

        position.X = x;
        position.Y = y;

        base.Update( gameTime );
    }

    /// <summary>
    /// This is called when the game should draw itself.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw( GameTime gameTime )
    {
        GraphicsDevice.Clear( Color.CornflowerBlue );

        Matrix rotation = Matrix.CreateRotationY( gameTime.TotalGameTime.Seconds * 0.1f );

        // Set render states.
        GraphicsDevice.BlendState = BlendState.Opaque;
        GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        GraphicsDevice.SamplerStates[ 0 ] = SamplerState.LinearWrap;

        grid.Draw( rotation, view, projection );

        DrawModel( tank, rotation, view, projection );

        // TODO: Add your drawing code here
        spriteBatch.Begin();
        spriteBatch.Draw( thumb, new Rectangle( (int)position.X, (int)position.Y, 64, 64 ), Color.White );
        spriteBatch.End();

        base.Draw( gameTime );
    }

    public void DrawModel( Model model, Matrix world, Matrix view, Matrix projection )
    {
        // Set the world matrix as the root transform of the model.
        model.Root.Transform = world;

        // Allocate the transform matrix array.
        Matrix[] boneTransforms = new Matrix[ model.Bones.Count ];

        // Look up combined bone matrices for the entire model.
        model.CopyAbsoluteBoneTransformsTo( boneTransforms );

        // Draw the model.
        foreach ( ModelMesh mesh in model.Meshes )
        {
            foreach ( BasicEffect effect in mesh.Effects )
            {
                effect.World = boneTransforms[ mesh.ParentBone.Index ];
                effect.View = view;
                effect.Projection = projection;

                //switch (lightMode)
                //{
                //    case LightingMode.NoLighting:
                //        effect.LightingEnabled = false;
                //        break;

                //    case LightingMode.OneVertexLight:
                //        effect.EnableDefaultLighting();
                //        effect.PreferPerPixelLighting = false;
                //        effect.DirectionalLight1.Enabled = false;
                //        effect.DirectionalLight2.Enabled = false;
                //        break;

                //    case LightingMode.ThreeVertexLights:
                //effect.EnableDefaultLighting();
                //effect.PreferPerPixelLighting = false;
                //        break;

                //    case LightingMode.ThreePixelLights:
                //        effect.EnableDefaultLighting();
                //        effect.PreferPerPixelLighting = true;
                //        break;
                //}

                effect.SpecularColor = new Vector3( 0.8f, 0.8f, 0.6f );
                effect.SpecularPower = 16;
                effect.TextureEnabled = true;
            }

            mesh.Draw();
        }
    }
}
+2

, , , . , . Draw, :

    graphics.GraphicsDevice.SetVertexBuffer(gb.vb, 0);

, , , .

, , , . , - . - , .

0

Source: https://habr.com/ru/post/1785849/


All Articles