xna – HLSL Deferred Rendering PointLight problem

Hello everyone, I am currently following this tutorial at http://www.catalinzima.com/xna/tutorials/deferred-rendering-in-xna/point-lights/ on point lights in delayed rendering. I am trying to implement a point light, but it is only correct if the camera is on (0, 0, 0). What should be changed?

Here is the shader

float4x4 World;
float4x4 View;
float4x4 Projection;

//color of the light 
float3 Color; 

//position of the camera, for specular light
float3 cameraPosition; 

 //this is used to compute the world-position
float4x4 InvertViewProjection; 

//this is the position of the light
float3 lightPosition;

//how far does this light reach
float lightRadius;

//control the brightness of the light
float lightIntensity = 1.0f;

// diffuse color, and specularIntensity in the alpha channel
texture colorMap; 
// normals, and specularPower in the alpha channel
texture normalMap;
//depth
texture depthMap;

sampler colorSampler = sampler_state
{
Texture = (colorMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = LINEAR;
MinFilter = LINEAR;
Mipfilter = LINEAR;
};
sampler depthSampler = sampler_state
{
Texture = (depthMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
Mipfilter = POINT;
};
sampler normalSampler = sampler_state
{
Texture = (normalMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
Mipfilter = POINT;
};


struct VertexShaderInput
{
float3 Position : POSITION0;
};

struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 ScreenPosition : TEXCOORD0;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
//processing geometry coordinates
float4 worldPosition = mul(float4(input.Position,1), World);
float4 viewPosition = mul(worldPosition,  View);
output.Position = mul(viewPosition, Projection);
output.ScreenPosition = output.Position;
return output;
}

float2 halfPixel;
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
//obtain screen position
input.ScreenPosition.xy /= input.ScreenPosition.w;
//obtain textureCoordinates corresponding to the current pixel
//the screen coordinates are in (-1,1)*(1,-1)
//the texture coordinates need to be in (0,1)*(0,1)
float2 texCoord = 0.5f * (float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 1);
//allign texels to pixels
texCoord -=halfPixel;

//get normal data from the normalMap
float4 normalData = tex2D(normalSampler,texCoord);
//tranform normal back into (-1,1) range
float3 normal = 2.0f * normalData.xyz - 1.0f;
//get specular power
float specularPower = normalData.a * 255;
//get specular intensity from the colorMap
float specularIntensity = tex2D(colorSampler, texCoord).a;

//read depth
float depthVal = tex2D(depthSampler,texCoord).r;

//compute screen-space position
float4 position;
position.xy = input.ScreenPosition.xy;
position.z = depthVal;
position.w = 1.0f;
//transform to world space
position = mul(position, InvertViewProjection);
position /= position.w;

//surface-to-light vector
float3 lightVector = lightPosition - position;

//compute attenuation based on distance - linear attenuation
float attenuation = saturate(1.0f - length(lightVector)/lightRadius); 

//normalize light vector
lightVector = normalize(lightVector); 

float NdL = max(0, dot(normal, lightVector));
float3 diffuseLight = NdL * Color.rgb;

//reflection vector
float3 reflectionVector = normalize(reflect(-lightVector, normal));
//camera-to-surface vector
float3 directionToCamera = normalize(cameraPosition - position);
//compute specular light
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);

//take into account attenuation and lightIntensity.
return attenuation * lightIntensity * float4(diffuseLight.rgb, specularLight);
}

technique Technique1
{
pass Pass1
{
    VertexShader = compile vs_2_0 VertexShaderFunction();
    PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

MeshBatcher for XNA always materials wrong

I'm trying to write a mesh batch for XNA.

In the test scenario, I use 3 network entries and 2 materials. However, only the last material is drawn.

sealed class MeshBatch
{
    private readonly List> items;
    GraphicsDevice GraphicsDevice { get; }
    private VertexPositionNormalTexture() vertexArray = { };

    private int() triangles = { };

    public MeshBatch(GraphicsDevice device)
    {
        items = new List>();
        GraphicsDevice = device;
    }

    private void EnsureCapacity(int vertexCount, int triangleCount)
    {
        vertexArray = 
            new VertexPositionNormalTexture(vertexCount);
        triangles = new int(triangleCount);
    }

    public void Draw(Mesh.MeshEntry entry, Material mat)
    {
        items.Add(new KeyValuePair(entry, mat));
    }

    public void Draw(GraphicsDevice device)
    {
        if (items.Count == 0)
            return;

        int itemCount = items.Count;
        int vertexCount = 0, triangleCount = 0;

        for (int i = 0; i < itemCount; i++)
        {
            Mesh.MeshEntry item = items(i).Key;
            vertexCount += item.renderBuffer.Length;
            triangleCount += item.indices.Length;
        }

        EnsureCapacity(vertexCount, triangleCount);

        vertexCount = 0;
        triangleCount = 0;
        Material lastMat = null;
        bool flushed = false;
        for (int i = 0; i < itemCount; i++)
        {
            Mesh.MeshEntry item = items(i).Key;
            Material mat = items(i).Value;
            int itemBufferCount = item.renderBuffer.Length;

            if (lastMat != mat ||
                vertexCount + itemBufferCount > short.MaxValue)
            {
                flushed = true;
                Flush(lastMat);
                vertexCount = 0;
                triangleCount = 0;
                lastMat = mat;
                Array.Clear(vertexArray, 0, vertexArray.Length);
                Array.Clear(triangles, 0, triangles.Length);
            }

            for (int ii = 0, t = triangleCount;
                ii < item.indices.Length;
                ii++, t++)
                triangles(t) = (item.indices(ii) + vertexCount);
            triangleCount += item.indices.Length;

            for (int ii = 0, t = vertexCount;
                ii < itemBufferCount;
                ii++, t++)
                vertexArray(t) = (item.renderBuffer(ii));
            vertexCount += itemBufferCount;
            if (!flushed && i == items.Count - 1)
                Flush(mat);
            flushed = false;
        }

        items.Clear();
    }

    private void Flush(Material mat)
    {

        if (vertexArray.Length == 0 || mat == null) 
            return;

        foreach (EffectPass pass in mat.Effect.CurrentTechnique.Passes)
        {
            pass.Apply();
            GraphicsDevice.DrawUserIndexedPrimitives(
                PrimitiveType.TriangleList,
                vertexArray, 0, vertexArray.Length,
                triangles, 0, triangles.Length / 3,
                VertexPositionNormalTexture.VertexDeclaration);
        }
    }
}

Any help is appreciated.

XNA MAtrix Object rotates, scales, but does not move

I have the following transformation method to transform all vértices in the buffer:

        public void Transform(ITransform transform)
        {
            for (int i = 0; i < renderBuffer.Length; i++)
                renderBuffer(i).Position = Vector4.Transform(
                    transform.TransformationMatrix,
                    new Vector4(buffer(i).Position, 1)).Xyz;
        }

The transformation matrix is ​​composed as follows:

    void ITransform.Update()
    {
        TransformationMatrix = 
            Matrix4.CreateScale(Scale);
        TransformationMatrix *= 
            Matrix4.CreateFromQuaternion(Rotation);
        TransformationMatrix *= 
            Matrix4.CreateTranslation(Position);
    }

The object rotates and scales well, but is not translated. I'm not sure why ...

Supplementary Code:

    public static implicit operator Microsoft.Xna.Framework.Vector3(Vector3 a) =>
        new Microsoft.Xna.Framework.Vector3(a.X, a.Y, a.Z);

    public static implicit operator Vector3(Microsoft.Xna.Framework.Vector3 a) =>
       new Vector3(a.X, a.Y, a.Z);


    public static void Transform(ref Matrix4 mat, ref Vector4 vec, out Vector4 result)
    {
        result = new Vector4(
            (mat.Row0.X * vec.X) + (mat.Row0.Y * vec.Y) + (mat.Row0.Z * vec.Z) + (mat.Row0.W * vec.W),
            (mat.Row1.X * vec.X) + (mat.Row1.Y * vec.Y) + (mat.Row1.Z * vec.Z) + (mat.Row1.W * vec.W),
            (mat.Row2.X * vec.X) + (mat.Row2.Y * vec.Y) + (mat.Row2.Z * vec.Z) + (mat.Row2.W * vec.W),
            (mat.Row3.X * vec.X) + (mat.Row3.Y * vec.Y) + (mat.Row3.Z * vec.Z) + (mat.Row3.W * vec.W));
    }


    public static void CreateTranslation(float x, float y, float z, out Matrix4 result)
    {
        result = Identity;
        result.Row3.X = x;
        result.Row3.Y = y;
        result.Row3.Z = z;
    }

Any help is appreciated ...

EDIT:

It works with the following code:

    public void Transform(ITransform transform)
        {
            for (int i = 0; i < renderBuffer.Length; i++)
                renderBuffer(i).Position = Vector4.Transform(
                    transform.TransformationMatrix,
                    new Vector4(buffer(i).Position, 1)).Xyz +
                    transform.TransformationMatrix.ExtractTranslation();
        }

But shouldn't the Vector4.Transform take care of it ????

XNA Weird Mesh result

Hello everyone and a happy new year!

I'm having trouble displaying a network on the screen loaded by assimp.

This is how it looks

Enter image description here

Here is my code to load …

interface IMesh
{
    Mesh.MeshEntry() SubMeshes { get; }

    void Render(
        GameWindow gameWindow,
        ITransform transform,
        ICamera camera);
}

public class Mesh : IMesh
{
    internal struct MeshEntry
    {
        internal int materialIndex;
        public VertexPositionNormalTexture() buffer;
        public int() indices;

        public MeshEntry(Assimp.Mesh mesh)
        {
            float() vertices = new float(0);
            float() normals = new float(0);
            float() uvs = new float(0);
            indices = new int(0);

            if (mesh.HasVertices)
            {
                vertices = new float(mesh.VertexCount * 3);
                int i = 0;
                foreach (var vertex in mesh.Vertices)
                {
                    vertices(i) = vertex.X;
                    vertices(i + 1) = vertex.Y;
                    vertices(i + 2) = vertex.Z;
                    i += 3;
                }
            }

            if (mesh.HasTextureCoords(0))
            {
                uvs = new float(mesh.VertexCount * 2);

                int i = 0;
                foreach (Vector3D vertex in mesh.TextureCoordinateChannels(0))
                {
                    uvs(i) = vertex.X;
                    uvs(i + 1) = vertex.Y;
                    i += 2;
                }
            }

            if (mesh.HasNormals)
            {
                normals = new float(mesh.Normals.Count * 3);
                int i = 0;
                foreach (var vertex in mesh.Normals)
                {
                    normals(i) = vertex.X;
                    normals(i + 1) = vertex.Y;
                    normals(i + 2) = vertex.Z;
                    i+= 3;
                }
            }

            if (mesh.HasFaces)
            {
                indices = new int(mesh.FaceCount * 3);
                int i = 0;
                foreach (Face face in mesh.Faces)
                {
                    indices(i) = face.Indices(0);
                    indices(i + 1) = face.Indices(1);
                    indices(i + 2) = face.Indices(2);
                    i += 3;
                }
            }

            materialIndex = mesh.MaterialIndex;
            buffer = new VertexPositionNormalTexture(mesh.VertexCount);

            for (int i = 0, j = 0; i < vertices.Length; i += 3, j++)
                buffer(j).Position = 
                    new Microsoft.Xna.Framework.Vector3(
                        vertices(i),
                        vertices(i + 1), 
                        vertices(i + 2));

            for (int i = 0, j = 0; i < normals.Length; i += 3, j++)
                buffer(j).Normal =
                    new Microsoft.Xna.Framework.Vector3(
                        normals(i), normals(i + 1), normals(i + 2));

            for (int i = 0, j = 0; i < uvs.Length; i += 2, j++)
                buffer(j).TextureCoordinate =
                    new Microsoft.Xna.Framework.Vector2(
                        uvs(i), uvs(i + 1));
        }

        public void Draw(GameWindow gameWindow)
        {
            gameWindow.MeshBatch.Draw(this);
        }
    }

    private MeshEntry() SubMeshes { get; set; }

    Mesh.MeshEntry() IMesh.SubMeshes => SubMeshes;

    Mesh()
    {

    }

    void IMesh.Render(
        GameWindow gameWindow,
        ITransform transform,
        ICamera camera)
    {
        foreach (MeshEntry entry in SubMeshes)
            entry.Draw(gameWindow);
    }

    internal static Mesh FromFile(string filename)
    {
        Mesh mesh = new Mesh();

        Assimp.AssimpContext importer = new AssimpContext();

        Assimp.Scene scene = importer.ImportFile(
            filename,
            PostProcessSteps.Triangulate |
            PostProcessSteps.GenerateNormals |
            PostProcessSteps.CalculateTangentSpace |
            PostProcessSteps.SortByPrimitiveType |
            PostProcessSteps.GenerateUVCoords | 
            PostProcessSteps.OptimizeMeshes |
            PostProcessSteps.OptimizeGraph);

        mesh.SubMeshes = new MeshEntry(scene.MeshCount);
        int i = 0;
        foreach (Assimp.Mesh entry in scene.Meshes)
        {
            mesh.SubMeshes(i) = new MeshEntry(entry);
            i++;
        }

        importer.Dispose();

        return mesh;
    }
}

I am trying to change my code from OpenGL to MonoGame and, oddly enough, it works on OpenGL. I'm not sure what's going on.

I draw the net like this

GraphicsDevice.DrawUserIndexedPrimitives(
            PrimitiveType.TriangleList,
            vertexArray, 0, vertexArray.Length,
            triangles, 0, triangles.Length / 3,
            VertexPositionNormalTexture.VertexDeclaration);

xna – Prevents a movement from moving multiple spaces when a direction key is pressed

I am doing a 15 piece puzzle and have difficulty getting my sprite to move one tile at a time when I initially press the left button the sprite will move once but after that the sprite will move several tiles after doing the Press buttons again instead of moving a tile as it should. Ultimately, this also confuses the sprites and some of them disappear. The code I use to determine the movement is:

if (positionx16 - positionx1 == 200 && positiony16 == positiony1)
{
    canswapleft1 = true;
}

if (oldState.IsKeyUp(Keys.Left) && newState.IsKeyDown(Keys.Left))
{
    if (positionx16 > 0 && canswapleft1 == true)
    {
        positionx16 += -widthoftile;
        positionx1 += widthoftile;
        canswapleft1 = false;
    }
}

Position x16 is the X position of the tile controlled by the player, and position x1 refers to the X position of the 1st tile. This was repeated for each tile.

xna – How do I change a specific set of rendered buttons from gray to green?

I am a self-taught programmer.

I ran a Button class like this:

Texture texture;
Color color;
Color differentColor;

SpriteFont font;
...
button1 = new Button(texture, font, ... , color);
button2 = new Button(texture, font, ... , color);
...
button20 = new Button(texture, font, ... , color);

This button appears 20 times at a number of specific locations on the screen.

I want a set of 10 buttons in each level not to light up in a random green.

Level 1: Button 1,3,6,7,10,12,13,14,15,16 lights green (must be in this sequence)

Level 2: Button 2,5,6,7,9,11,13,14,19,20 lights green (must be in this sequence)

Level 3: etc …

There are 15 levels in total.

How do I do that in an intelligent way?

What I think might work:

Color() color1;
Color() color2;
...
Color() color20;

Repeat the spawn button 20 times and assign each level:

color1 = {Color.Green, Color.Gray, Color.Green... }
color2 = {Color.Gray, Color.Green, Color.Gray... }

I will add more functions to the button over time.
Will I benefit from using the command design pattern here?

xna – MonoGame model antialiasing does not work

I've followed the tutorial at https://docs.microsoft.com/en-us/xamarin/graphics-games/monogame/3d/part1 to render a model in a MonoGame bare-bone project. It works, but I want to use anti-aliasing to make it look better.

I made the following changes to achieve this:

public Game1()
{
    graphics = new GraphicsDeviceManager(this);

    // this part is added
    graphics.PreferMultiSampling = true;
    graphics.GraphicsProfile = GraphicsProfile.HiDef;
    graphics.ApplyChanges();

    Content.RootDirectory = "Content";
}

and

protected override void Initialize()
{
    graphics.GraphicsDevice.PresentationParameters.MultiSampleCount = 8;
    graphics.ApplyChanges();
    // TODO: Add your initialization logic here

    base.Initialize();
}

However, the model still has aliasing.

xna – MonoGame game is slow

During development, I ran my 2D game (Monogame 3.6) on my Windows laptop, which has a poorly integrated graphics card and an i5. Now I'm trying out my game on my gaming PC, which has a GTX 970 and an i5 (a slightly better one), and the game is running hellishly slow.

I'm completely at a loss here. Here's what I tried to do to speed up the game, and it still floats around maybe 15 FPS:

  • Reduce the gameplay from 3 or 4 spritebatch blocks to a single one
  • Remove ALL changes to shader uniforms so that the shader uniforms are set up only once and never changed
  • Comment out 100% of the particle rendering code.
  • Remove my extra render target that I used for the post-process FX.

After all, it's about as simple as a Hello World renderer, and it's still dog-weak. I am amazed. According to Codetrack Profiler, 80% of my CPU time is in a function called "DoDraw," which seems to be XNA framework code. So I'm sure it's not about the update logic or the number of rendering operations, and so on. The stack looks like this:

  • Tick
  • DoDraw
  • Available
  • Platform Present

But I do not really understand what it does and why it takes so long. Any tips, knowledge about the rendering of quirks, profile tips, etc., everything is appreciated.

xna – Monogame – Collision does not work and invisible walls

I recently experimented with Monogame and XNA (by Gamemaker) and decided to work on a simple collision system. Problem is displayed in the GIF.
Preview of the error

main collision

Each entity (short name for everything with properties) has some parameters. These are:

                public vector2 position;
public Vector2 Origin;
public Vector2 Velocity;
public vector2 speed;
public Color Color = Color.White;
public rectangle rectangle
{
receive
{
return new rectangle ((int) position.X, (int) position.Y, _texture.Width, _texture.Height);
}

}

I've used blocks to check how the collision works on multiple objects side by side. Right now, it's not about optimization.
As you can see, to the right of each vertical block is an invisible wall. I can add multiples just to demonstrate:

Enter image description here

Let's get to the collision code. I wanted to do something similar to GMS2 and check if the box with the sprite at the specified position overlapped another entity in the game.
Since I need to know which page to touch in the future, I wrote my code in the entity class as follows:

                Protected Bool IsTouchingLeft (Vector2 pos, Entity entity)
{
return pos.X + _texture.Width> = entity.Rectangle.Left &&
pos.X <= entity.Rectangle.Left &&
               pos.Y + _texture.Height >= entity.Rectangle.Top &&
posy <= entity.Rectangle.Bottom;
    }
    protected bool IsTouchingRight(Vector2 pos, Entity entity)
    {
        return pos.X >= entity.Rectangle.Right &&
pos.X + _texture.Width> = entity.Rectangle.Right &&
pos.Y + _texture.Height> = entity.Rectangle.Top &&
pos.Y <= entity.Rectangle.Bottom;
}
Protected Bool IsTouchingTop (Vector2 pos, Entity entity)
{
Return Pos.X <= entity.Rectangle.Right &&
               pos.X + _texture.Width >= entity.Rectangle.Left &&
pos.Y + _texture.Height> = entity.Rectangle.Top &&
pos.Y <= entity.Rectangle.Top;
}
Protected Bool IsTouchingBottom (Vector2 pos, Entity entity)
{
Return Pos.X <= entity.Rectangle.Right &&
               pos.X + _texture.Width >= entity.Rectangle.Left &&
posy <= entity.Rectangle.Bottom &&
               pos.Y + _texture.Height >= entity.Rectangle.Bottom;
}

For these functions I use two variables, the position where a collision should take place and the entity with which it should collide.

And to simplify matters, if I just need to know if it's going to collide at all, I've added a PlaceMeeting feature.

                protected bool PlaceMeeting (Vector2 pos, Entity entity)
{
return IsTouchingLeft (pos, entity) ||
IsTouchingRight (pos, entity) ||
IsTouchingTop (pos, entity) ||
IsTouchingBottom (pos, entity);
}

It only checks if a collision with a specified object occurs at a specified point. (If you used GMS, you know what I want to do.)

Let's go to the movement script.
Player is a child of the Entity Class and has some new variables.

                private Vector2 move;
private float grav = 0.3f;
private Int32 input_left;
private Int32 input_right;
private bool input_up;

The entry is made as follows:

                                input_left = Convert.ToInt32 (Keyboard.GetState (). IsKeyDown (Keys.A));
input_right = Convert.ToInt32 (Keyboard.GetState (). IsKeyDown (Keys.D));
input_up = Keyboard.GetState (). IsKeyDown (Keys.Space);

The horizontal input is adjusted as a result of the easier movement. Here is the Move () function.

                private void move ()
{
move.X = (input_right - input_left);
Speed.X = movement.X * speed.X;
Speed.Y + = grav;
if (input_up)
Speed.Y = speed.Y;
}

And the Code Player Collision Code:

                                foreach (var entity in entity) // Displays all created entities
{
if (entity == this) // If it is a player, do not check the collision
continue;

// Horizontal collision
if (PlaceMeeting (new vector2 (position.X + velocity.X, position.Y), entity))
{
while (! PlaceMeeting (new Vector2 (Position.X + Math.Sign (Velocity.X), Position.Y), entity))
{
Position.X + = Math.Sign (Velocity.X);
}
Speed.X = 0;
}
// vertical collision
if (PlaceMeeting (new vector2 (Position.X, Position.Y + Speed.Y), Entity)) // Check if it will collide in one step
{
while (! PlaceMeeting (new Vector2 (Position.X, Position.Y + Math.Sign (Velocity.Y)), entity)) // checks if it will not collide in 1 pixel
{
Position.Y + = Math.Sign (Velocity.Y); // Increment pixel by pixel until it collides into 1 pixel
}
Speed. Y = 0; // stop the player
}
}

And then I increase the position with speed.

Position + = speed;

I've tried different collision methods and they work and look like this:

Other collision One

In the player class, I used this collision code instead:

                                                if (this.Velocity.X> 0 && IsTouchingLeft (Position + Velocity, Entity))
this.Velocity.X = 0;
if (this.Velocity.X < 0 && IsTouchingRight(Position + Velocity, entity))
                this.Velocity.X = 0;
            //Vertical Collision
            if (this.Velocity.Y > 0 && IsTouchingTop (position + speed, entity)
this.Velocity.Y = 0;
if (this.Velocity.Y <0 && IsTouchingBottom (position + velocity, unit))
this.Velocity.Y = 0; 

Basically, I could not move to the left when I was to the right of vertical blocks.

Other collision 2

I also tried using this strange code with Rectangle.Intersects ().

                                                // Horizontal collision
var xRect = new rectangle ((int) position.X + (int) velocity.X, (int) position.Y, _texture.Width, _texture.Height);
if (xRect.Intersects (entity.Rectangle))
{
xRect = new rectangle ((int) Position.X + Math.Sign (Velocity.X), (int) Position.Y, _texture.Width, _texture.Height);
while (! xRect.Intersects (entity.Rectangle))
{
Position.X + = Math.Sign (Velocity.X);
}
this.Velocity.X = 0;


}
// vertical collision
var yRect = new rectangle ((int) position.X, (int) position.Y + (int) velocity.Y, _texture.Width, _texture.Height);
if (yRect.Intersects (entity.Rectangle))
{
yRect = new rectangle ((int) position.X, (int) position.Y + Math.Sign (Velocity.Y), _texture.Width, _texture.Height);
while (! yRect.Intersects (entity.Rectangle))
{
Position.Y + = Math.Sign (Velocity.Y);
}
this.Velocity.Y = 0;

}

This has made my program not to react.
Anyway, do you have any idea why that is?
I will post the full code of each class:
Spiel1.cs
Entity.cs
Player.cs
Block.cs

Implement a scrollable panel in XNA / MonoGame

I'm trying to create a scroll box for my game. The code I showed below is working but there is a problem.

I read Andrew's answer here and decided to implement the scrolling effect using a translation matrix. However, my controls (buttons, combo boxes, and so on) have a solid rectangle on the screen (the rectangle I use to check if the cursor is over the control). As I found out, the matrix translation only moves the texture of the control, not the rectangle.

The problem:

So, when I scroll down and click where the button was originally in the panel, the Click event fires even though the button's texture is "out of the box." scissorRectangle,

What I have considered:

  1. I thought I should disable the interaction with controls outside of scissorRectangleBut what about controls that are still partially visible?

  2. If the matrix translation does not work, I thought about going through the panels _controls List the offset and send it to each control (ugh) where it adjusts its rectangle position. : /

I have the following code for my panel:

// ...
private RasterizerState _rasterizerState = new RasterizerState () {ScissorTestEnable = true};
private Vector2 _scrollOffset = Vector2.Zero;
private matrix _matrix = Matrix.Identity;
// ...

in the To update():

_matrix = Matrix.CreateTranslation (new Vector3 (_scrollOffset, 0));
if (Enables && BorderBox.Intersects (inputManager.MouseRect))
{
if (inputManager.ScrolledDown ())
{
if (_combinedRowHeight - (ContentBox.Height -scrollOffset.Y)> -combinedTextHeight)
{
_scrollOffset.Y - = 14;
}
}
otherwise if (inputManager.ScrolledUp ())
{
if (_scrollOffset.Y <0)
{
_scrollOffset.Y + = 14;
}
}
}

And then in To draw():

// Save the previous RasterizerState
RasterizerState oldState = spriteBatch.GraphicsDevice.RasterizerState;
// Save the original scissors rectangle
Rectangle currentScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;

spriteBatch.End ();

spriteBatch.Begin ();
// Draw the control panel
spriteBatch.End ();

spriteBatch.Begin (SpriteSortMode.Immediate, BlendState.AlphaBlend, rasterizerState: _rasterizerState, transformMatrix: _matrix);

spriteBatch.GraphicsDevice.ScissorRectangle = ContentBox;

if (_drawControls)
{
for (int i = 0; i <_rows.Count; i ++)
{
_Reihen[i].Draw (SpriteBatch);
}
}

spriteBatch.End ();

// Restore the scissors rectangle
spriteBatch.GraphicsDevice.ScissorRectangle = currentScissorRect;

// Restore the RasterizerState
spriteBatch.Begin (rasterizerState: oldState);

Is there no other way? Should I simply send the offset to controls and change their position? Can not the matrix approach be used for interactive controls?