Meh i was just about to give up i was wrong about what i said.
Well at least if you just use a pixel shader.
To make a long story short here we go.

The pixel shader.
// FxClipText
//
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif
//matrix WorldViewProjection;
float4 visibleBounds;
Texture2D TextureA;
sampler2D TextureSamplerA = sampler_state
{
Texture = <TextureA>;
};
// pixel shader
float4 MyPixelShader(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
float4 col = tex2D(TextureSamplerA, texCoord) *color;
float2 pos = position.xy;
// i could probably mathematically boolean this down get rid of the ifs in a few ways but im tired.
float dx = (pos.x - visibleBounds.x) * (visibleBounds.z - pos.x);
float dy = (pos.y - visibleBounds.y) * (visibleBounds.w - pos.y);
if (dx < 0.0f)
clip(-1);
if (dy < 0.0f)
clip(-1);
return col;
}
technique BasicColorDrawing
{
pass P0
{
PixelShader = compile PS_SHADERMODEL MyPixelShader();
}
}
Implementation Game1
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace GLClipTextShader
{
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Effect effect;
SpriteFont font;
string message = "";
Rectangle boundryRectangle = new Rectangle(100, 0, 200, 400);
public static Texture2D dotTexture;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.ApplyChanges();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
// load up your stuff
font = Content.Load<SpriteFont>("MgFont");
// load up your effect;
effect = Content.Load<Effect>("FxClipText");
effect.CurrentTechnique = effect.Techniques["BasicColorDrawing"];
// make a message
message =
" Ok so i had a bit of trouble figuring this out it turns out that it was working after all. " +
"\n I was wrong when spritebatch passes the pos to the pixel shader. " +
"\n It passes the untransformed coordinates so it does a bit of magic under the hood. " +
"\n However its own vertex shader is still lining them up properly even if i pass matrix identity." +
"\n So there we go if you intend however to pass a projection matrix ill bet youll need to do the transform on the boundry" +
"\n +\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+"
;
dotTexture = TextureDotCreate(GraphicsDevice);
}
public Texture2D TextureDotCreate(GraphicsDevice device)
{
Color[] data = new Color[1];
data[0] = new Color(255, 255, 255, 255);
Texture2D tex = new Texture2D(device, 1, 1);
tex.SetData<Color>(data);
return tex;
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Moccasin);
Matrix m = Matrix.Identity;
effect.CurrentTechnique = effect.Techniques["BasicColorDrawing"];
effect.Parameters["visibleBounds"].SetValue(GetVector4Rectangle(boundryRectangle));
// Im cheating here cause i dont know the samplers name or if it can be used in the function.
// So im re-splicing the same texture thats will be sent in a second time.
// Maybe someone else can chime in on what the name of the texture sampler is, that basic effects, vertex shader uses.
effect.Parameters["TextureA"].SetValue(font.Texture);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, effect, m);
spriteBatch.Draw(dotTexture, boundryRectangle, Color.White);
spriteBatch.Draw(font.Texture, new Vector2(200,320), Color.LightGray);
spriteBatch.DrawString(font, message, new Vector2(100f, 100f), Color.MonoGameOrange);
spriteBatch.End();
base.Draw(gameTime);
}
public Vector4 GetVector4Rectangle(Rectangle r)
{
// woops you gotta flip the y should do this with the matrixes later on i think.
// return new Vector4(r.Left, r.Top, r.Right, r.Bottom);
int h = graphics.GraphicsDevice.Viewport.Height;
return new Vector4(r.Left, (h - r.Top), r.Right, (h - r.Bottom));
}
public Vector4 GetVector4GpuRectangle(Rectangle r, Matrix vp)
{
var lt = Vector2.Transform(new Vector2(r.Left, r.Top), vp);
var rb = Vector2.Transform(new Vector2(r.Right, r.Bottom), vp);
return new Vector4(lt.X, lt.Y, rb.X, rb.Y);
}
}
}