From: Using XNA RenderTargets

Published October 23, 2011
Advertisement
So here's my first Entry on this journal! My name is Ryan and I make games. Nothing too big at the moment but I will someday. Instead of doing a huge intro about me I thought I could just post some code that I did for my game Sky Cat that you can use for your XNA title (or if you port it to some other API). This code creates a "ViewFinder" for when a character goes off screen and you still want to see them. This code can be modified for whatever you are doing (in game map etc.).

Here's the code! Please though just site me in the credits as a Special Thanks and let me know :D






using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;




class ViewFinder
{
#region Variables
public bool isAlive = true;
private float yPosition;
private float seeRadius;
private Point frameSize;
private SpriteEffects spriteEffect = SpriteEffects.None;
public Vector2 position;
public Color viewFinderColor;
private Matrix camera;
private Camera2d cam, cam2;
private Effect mask;
private Texture2D pointer;
private Texture2D lens;
private Texture2D pointRender;
private Texture2D maskTexture, finalMask, flippedFinalMask;
private Texture2D texture;
private RenderTarget2D renderTarget;
private GraphicsDevice graphicsDevice;
public PlayerIndex playerIndex;
private FallingMan cat;
static public bool[] playerView = new bool[4];
public RenderTarget2D finalTarget;
public Texture2D finalTexture;

#endregion

#region Constructors
public ViewFinder(Game game,Vector2 position, Texture2D texture, Point frameSize, Color viewFinderColor, GraphicsDevice graphicsDevice, PlayerIndex playerIndex)
{
mask = game.Content.Load(@"Shaders\viewMask");
pointer = game.Content.Load(@"Sprite\ViewFinder\pointer");
lens = game.Content.Load(@"Sprite\ViewFinder\lens");
maskTexture = game.Content.Load(@"Sprite\ViewFinder\mask");
cam = new Camera2d();
cam.Zoom = 3.5f;
cam2 = new Camera2d();
cam2.Zoom = 6;
this.position = position;
this.viewFinderColor = viewFinderColor;
this.texture = texture;
this.frameSize = frameSize;
seeRadius = this.frameSize.X;
this.graphicsDevice = graphicsDevice;
this.playerIndex = playerIndex;
PresentationParameters pp = graphicsDevice.PresentationParameters;
renderTarget = new RenderTarget2D(graphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, true, graphicsDevice.DisplayMode.Format, DepthFormat.Depth24);
finalTarget = new RenderTarget2D(graphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, true, graphicsDevice.DisplayMode.Format, DepthFormat.Depth24);
}
#endregion

#region Update
public void Update(GameTime gameTime, Vector2 position, Matrix camera)
{
//Update Postion
this.position = position;

//Update Cam1 Position
cam.position.X = position.X + (frameSize.X / 4);
cam.position.Y = position.Y + (frameSize.Y / 2);
if (position.Y < -camera.Translation.Y)
{
yPosition = 10;
spriteEffect = SpriteEffects.FlipVertically;

}

else if (position.Y > -camera.Translation.Y)
{
yPosition = graphicsDevice.Viewport.Height - pointer.Height;

}

//Update Cam2 Position
cam2.position.X = pointer.Width / 2;
cam2.position.Y = pointer.Width / 2;
this.camera = camera;

}
#endregion

#region Draw
//Call this first to draw the ViewFinder to a RenderTarget
public void PreDraw(GameTime gameTime, SpriteBatch spriteBatch, params Object[] objects)
{


mask.CurrentTechnique = mask.Techniques["Technique1"];
graphicsDevice.SetRenderTarget(renderTarget);

graphicsDevice.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true };

// Draw the scene
graphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, cam.get_transformation(graphicsDevice));


spriteBatch.Draw(texture, new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height), Color.White);


foreach (Object obj in objects)
{

if (obj is List)
{
foreach (Platform platform in ((List)obj))
{
if (Math.Abs(platform.position.X - position.X) < seeRadius && Math.Abs(platform.position.Y - position.Y) < seeRadius)
{
platform.Draw(gameTime, spriteBatch);
}
}
}

else if (obj is List)
{
foreach (PowerUp powerUp in ((List)obj))
{
if (Math.Abs(powerUp.position.X - position.X) < seeRadius && Math.Abs(powerUp.position.Y - position.Y) < seeRadius)
{
powerUp.Draw(gameTime, spriteBatch);
}
}
}
}
spriteBatch.End();



graphicsDevice.SetRenderTarget(finalTarget);
pointRender = (Texture2D)renderTarget;
graphicsDevice.Clear(Color.CornflowerBlue);



spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone, mask, camera);
mask.Parameters["spherePort"].SetValue(pointRender);
mask.Parameters["mask"].SetValue(maskTexture);
spriteBatch.Draw(pointRender, new Rectangle(-50, -(int)camera.Translation.Y, pointRender.Width, pointRender.Height), Color.White);
spriteBatch.End();



spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, cam2.get_transformation(graphicsDevice));
spriteBatch.Draw(pointer, new Rectangle(-19, 0, pointer.Width +39, pointer.Height), null, viewFinderColor, 0.0f, Vector2.Zero, spriteEffect, 0.1f);
spriteBatch.Draw(lens, new Rectangle(-19,0, lens.Width + 39, lens.Height), Color.White);
spriteBatch.End();
graphicsDevice.SetRenderTarget(null);

finalTexture = (Texture2D)finalTarget;



}

//Call this second to Mask the ViewFinder to have multiple on screen
public void DrawViewFinder(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone, mask);
mask.Parameters["spherePort"].SetValue(finalTexture);
if (spriteEffect == SpriteEffects.None)
{
mask.Parameters["mask"].SetValue(finalMask);
}
else
{
mask.Parameters["mask"].SetValue(flippedFinalMask);
}
spriteBatch.Draw(finalTexture, new Rectangle((int)position.X, (int)yPosition, 100, 100), Color.White);
spriteBatch.End();
}
#endregion
}









And then here's the Mask HLSL Code






texture spherePort;
texture mask;

sampler TextureSamplerSphere = sampler_state
{
Texture = ;
};

sampler TextureSamplerMask = sampler_state
{
Texture = ;
};

// TODO: add effect parameters here.


float4 PixelShaderFunction(float2 TextureCoordinateSphere : TEXCOORD0, float2 TextureCoordinateMask :TEXCOORD0 ) : COLOR0
{
// TODO: add your pixel shader code here.


return tex2D(TextureSamplerSphere, TextureCoordinateSphere) * tex2D(TextureSamplerMask, TextureCoordinateMask);
}

technique Technique1
{
pass Pass1
{
// TODO: set renderstates here.


PixelShader = compile ps_2_0 PixelShaderFunction();
}
}





I hope you all enjoy! Also check out Sky Cat on XBox Live Indie Games and PC when we release our 1.1 Update! Coming soon to Mac, iOS, and Android!

Source: Using XNA RenderTargets
0 likes 1 comments

Comments

JosephCollard
This is nice. However, a novice is going to get very lost in this. I think it would be beneficial if you were to analyze the problem and show a step by step process of the solution explaining why you are doing different things. Also, as a software developer you may wish to re-factor your code to be easier to manage in the future. The code here could easily put into a nice pattern that you could use and re-use.
October 23, 2011 01:34 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement

Latest Entries

Advertisement