Weiner Lemes
Weiner Lemes

Reputation: 113

MonoGame Problem with renderize Texture2D on camera movement

First, sorry for my bad English, English is not my native language.

I have a problem when I draw a Texture2D in screen. When I move a Texture in screen, colors in border of the texture flickers. This is my code:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SharpDX.Direct2D1.Effects;
using System;
using System.Collections.Generic;

namespace PixelTest
{
    public class Drawable
    {
        public Texture2D Image;
        public Point Position;
        public Point Size;
        public Rectangle Source;
    }

    public class MainGame : Game
    {
        //PRIVATE READ-ONLY VARIABLES
        private readonly GraphicsDeviceManager _graphics;
        private readonly List<Drawable> _sprites;

        //VARIABLES
        private Texture2D _screen;
        private Texture2D _tiles;
        private SpriteBatch _spriteBatch;
        private Point _camera;
        private Point _scale;
        private bool _byRect;
        private KeyboardState _previousKeyState;
        private BlendState _state;
        private RasterizerState _rState;

        //CONSTRUCTOR
        public MainGame()
        {
            _graphics = new GraphicsDeviceManager(this);
            _sprites = new List<Drawable>();

            _tiles = null;
            _spriteBatch = null;
            _camera = Point.Zero;
            _scale = new Point(1, 1);

            Content.RootDirectory = "Content";
            IsMouseVisible = true;
            IsFixedTimeStep = true;
            //_graphics.PreferHalfPixelOffset = true;
            _graphics.PreferMultiSampling= true;
            //_graphics.SynchronizeWithVerticalRetrace = false;
            _state = new BlendState()
            {
                AlphaBlendFunction = BlendFunction.Add,
                AlphaSourceBlend = Microsoft.Xna.Framework.Graphics.Blend.Zero,
                AlphaDestinationBlend = Microsoft.Xna.Framework.Graphics.Blend.Zero,

                ColorBlendFunction= BlendFunction.Add,
                ColorDestinationBlend = Microsoft.Xna.Framework.Graphics.Blend.Zero,
                ColorSourceBlend = Microsoft.Xna.Framework.Graphics.Blend.One,
                
            };
            _rState = new RasterizerState()
            {
                MultiSampleAntiAlias = false
            };
        }

        protected override void Initialize()
        {
            base.Initialize();

            _sprites.Add(new Drawable
            {
                Image = _tiles,
                Position = new Point(32, 64),
                Size = new Point(8, 8),
                Source = new Rectangle(0, 0, 8, 8)
            });
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);

            _tiles = Content.Load<Texture2D>("i001_tiles");
            _screen = new Texture2D(GraphicsDevice, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight);

            var colors = new Color[_graphics.PreferredBackBufferWidth * _graphics.PreferredBackBufferHeight];

            for (var i = 0; i < _graphics.PreferredBackBufferWidth * _graphics.PreferredBackBufferHeight; i++)
                colors[i] = Color.Black;

            _screen.SetData(colors);
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();

            _tiles.Dispose();
            _screen.Dispose();
        }

        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            var sKey = Keyboard.GetState();
            var translateUnit = Point.Zero;
            var scaleUnit = 0;

            if (sKey.IsKeyDown(Keys.A))
                translateUnit.X = -1;
            else if (sKey.IsKeyDown(Keys.D))
                translateUnit.X = 1;
            else
                translateUnit.X = 0;

            if (sKey.IsKeyDown(Keys.W))
                translateUnit.Y = -1;
            else if (sKey.IsKeyDown(Keys.S))
                translateUnit.Y = 1;
            else
                translateUnit.Y = 0;

            if (sKey.IsKeyDown(Keys.F))
                scaleUnit = -1;
            else if (sKey.IsKeyDown(Keys.G))
                scaleUnit = 1;
            else
                scaleUnit = 0;

            if (sKey.IsKeyDown(Keys.U) && _previousKeyState.IsKeyUp(Keys.U))
                _byRect = !_byRect;

            var speed = translateUnit;// * 1;

            _camera += speed;// RoundVec(speed);
            _scale = new Point(4, 4);
            _previousKeyState = sKey;
        }

        protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            GraphicsDevice.Clear(Color.Blue);

            _spriteBatch.Begin(SpriteSortMode.Deferred, _state, SamplerState.PointClamp, null, _rState, null, null);
            //_spriteBatch.Draw(_screen, Vector2.Zero, Color.White);

            foreach (var item in _sprites)
            {
                if (true)
                {
                    var pos = item.Position;
                    var size = item.Size;

                    pos += _camera;
                    pos *= _scale;
                    size *= _scale;

                    var rect = new Rectangle(
                        (int)pos.X,
                        (int)pos.Y,
                        (int)size.X,
                        (int)size.Y);

                    _spriteBatch.Draw(
                        item.Image,
                        rect,
                        item.Source,
                        Color.White,
                        0F,
                        Vector2.Zero,
                        SpriteEffects.None,
                        0F);
                }
                else
                {
                    var pos = item.Position;

                    //pos = RoundVec(pos * _scale) / _scale;
                    pos += _camera;
                    pos *= _scale;

                    _spriteBatch.Draw(
                        item.Image,
                        pos.ToVector2(),
                        item.Source,
                        Color.White,
                        0F,
                        Vector2.Zero,
                        _scale.ToVector2(),
                        SpriteEffects.None,
                        0F);
                }
            }
            
            _spriteBatch.End();
        }

    }
}

I dont use floats values for camera position in this test and the flickers continue to happens. I dont know what is happen.

I tried various things, but nothing work.

Resources: i001_tiles.png (no alpha values)

i001_tiles

PrintScreens:

print

Maybe is just a ottical illusion, or a monitor problem, but the green part of texture merge with the blue background on camera movement, i dont know why.

In Movement Up:

Movement Camera UP

This only occour with the colors different of white, when i movement camera to right, only the one pixel in green in the right merge with blue background.

Upvotes: 0

Views: 157

Answers (1)

LeDreamer
LeDreamer

Reputation: 58

I compiled your code on my machine and everything behaved like you wanted - no black line. I think the code should be fine.

My thoughts are that maybe it's some kind of flickering or something that messes up the colors when moving. Maybe there's some weird tearing on your screen that causes the black line. In this case try _graphics.SynchronizeWithVerticalRetrace = true; in your Initialize method.

It's hard to help you if your code runs fine on my PC but if nothing of this helps it might be a hardware problem.

Upvotes: 1

Related Questions