Jump to content

  • Log In with Google      Sign In   
  • Create Account


Using XNA RenderTargets


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Subliminalman   Members   -  Reputation: 109

Like
0Likes
Like

Posted 15 October 2011 - 11:00 PM

Hi everyone! I'm working on what I call a ViewFinder for my game which acts much like the little "viewers" in Super Smash Bros. when your character goes off screen so you can still see them.




I am having a few problems though

  • My background stops being drawn.
  • My Character does not animate within the ViewFinder.
  • Only one ViewFinder will be drawn at a time.
I think it's with how I use RenderTargets within the ViewFinder class and not anywhere else in the Drawing Code. Since I'm still fairly new to RenderTargets and not drawing to the BackBuffer I'm a little at a loss.

Any help would be appreciated thanks :D



Sponsor:

#2 laztrezort   Members   -  Reputation: 954

Like
1Likes
Like

Posted 15 October 2011 - 11:42 PM

Rendertarget usage can get a bit tricky, if you haven't already you should probably read this and this. If you were more specific (e.g. show some code) you may get some more specific help.

#3 Subliminalman   Members   -  Reputation: 109

Like
0Likes
Like

Posted 16 October 2011 - 12:06 AM

Here's my ViewFinder Class, I tried to make it as self contained as possible but that may be the problem. I will also post up my draw code in the main game loop.

ViewFinder


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

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

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


        public ViewFinder(Game game, FallingMan cat, GraphicsDevice graphicsDevice)
        {
            mask = game.Content.Load<Effect>(@"Shaders\viewMask");
            pointer = game.Content.Load<Texture2D>(@"Sprite\ViewFinder\pointer");
            lens = game.Content.Load<Texture2D>(@"Sprite\ViewFinder\lens");
            maskTexture = game.Content.Load<Texture2D>(@"Sprite\ViewFinder\mask");
            cam = new Camera2d();
            cam.Zoom = 3;
            position = cat.position;
            viewFinderColor = cat.color;
            texture = cat.texture;
            seeRadius = cat.frameSize.X;
            this.graphicsDevice = graphicsDevice;
            playerIndex = cat.p;
            this.cat = cat;
            PresentationParameters pp = graphicsDevice.PresentationParameters;
            renderTarget = new RenderTarget2D(graphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, true, graphicsDevice.DisplayMode.Format, DepthFormat.Depth24);

            Console.WriteLine();
            for(int i = 0; i < 4; i++)
            Console.Write(playerView[i]);

        }
 		
        #endregion 

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

            cam.position.X = position.X - (frameSize.X / 2);
            cam.position.Y = position.Y - (frameSize.Y / 2);
            
            
            this.camera = camera;
            
        }
        #endregion

        #region Draw
        public void Draw(GameTime gameTime, SpriteBatch spriteBatch, params Object[] objects)
        {

   		//Draw either on top or on bottom of the screen


            if (position.Y < camera.Translation.Y)
            {
                yPosition = 10;
                spriteEffect = SpriteEffects.FlipVertically;
            }
            else if (position.Y > camera.Translation.Y + graphicsDevice.Viewport.Height)
            {
                yPosition = graphicsDevice.Viewport.Height - pointer.Height;
            }
   		//Draw the off screen action


            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));
            
            if (cat == null)
            {
                spriteBatch.Draw(texture, new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height), Color.White);
            }
            else
            {
                spriteBatch.Draw(texture, cat.position, new Rectangle(cat.currentFrame.X * frameSize.X, cat.currentFrame.Y * frameSize.Y, cat.frameSize.X, cat.frameSize.Y),
                            Color.White, cat.rotation, Vector2.Zero, cat.scale, cat.flip, 0);
                //Console.WriteLine(cat.currentFrame);
            }

            foreach (Object obj in objects)
            {

                if (obj is List<Platform>)
                {
                    foreach (Platform platform in ((List<Platform>)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<PowerUp>)
                {
                    foreach (PowerUp powerUp in ((List<PowerUp>)obj))
                    {
                        if (Math.Abs(powerUp.position.X - position.X) < seeRadius && Math.Abs(powerUp.position.Y - position.Y) < seeRadius)
                        {
                            powerUp.Draw(gameTime, spriteBatch);
                        }
                    }
                }
                else if (obj is List<Airplane>)
                {
                    foreach (Airplane airPlane in ((List<Airplane>)obj))
                    {
                        if (Math.Abs(airPlane.position.X - position.X) < seeRadius && Math.Abs(airPlane.position.Y - position.Y) < seeRadius)
                        {
                            airPlane.Draw(gameTime, spriteBatch);
                        }
                    }
                }
                else if (obj is List<Bird>)
                {
                    foreach (Bird bird in ((List<Bird>)obj))
                    {
                        if (Math.Abs(bird.position.X - position.X) < seeRadius && Math.Abs(bird.position.Y - position.Y) < seeRadius)
                        {
                            bird.Draw(gameTime, spriteBatch);
                        }
                    }
                }
                else if (obj is List<Fan>)
                {
                    foreach (Fan fan in ((List<Fan>)obj))
                    {
                        if (Math.Abs(fan.position.X - position.X) < seeRadius && Math.Abs(fan.position.Y - position.Y) < seeRadius)
                        {
                            fan.Draw(gameTime, spriteBatch);
                        }
                    }
                }
                else if (obj is List<Cloud>)
                {
                    foreach (Cloud cloud in ((List<Cloud>)obj))
                    {
                        if (Math.Abs(cloud.position.X - position.X) < seeRadius && Math.Abs(cloud.position.Y - position.Y) < seeRadius)
                        {
                            cloud.Draw(gameTime, spriteBatch);
                        }
                    }
                }

                else if (obj is List<FallingMan>)
                {
                    foreach (FallingMan kitty in ((List<FallingMan>)obj))
                    {
                        if (Math.Abs(kitty.position.X - position.X) < seeRadius && Math.Abs(kitty.position.Y - position.Y) < seeRadius && kitty.p != playerIndex)
                        {
                            kitty.Draw(gameTime, spriteBatch);
                        }
                    }
                }
            }   

        
            spriteBatch.End();

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

            //Draw the scene to the screen and apply the mask to make it circular 




            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((int)position.X, (int)yPosition - (int)camera.Translation.Y, 100, 100), Color.White);
            spriteBatch.End();
            
            
            //Draw the actual ViewFinder
          
            spriteBatch.Begin();
            spriteBatch.Draw(pointer, new Vector2(position.X, yPosition), null, viewFinderColor, 0.0f, Vector2.Zero, 1.0f, spriteEffect, 0.1f);
            //spriteBatch.Draw(lens, new Vector2(position.X, yPosition), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f); 
            spriteBatch.Draw(lens, new Rectangle((int)position.X, (int)yPosition, lens.Width, lens.Height), Color.White);
            spriteBatch.End();
        }
        #endregion
    }
}




Main Game Draw Method

//Draw the Background

protected override void Draw(GameTime gameTime)
        {

 spriteBatch.Begin();
                    myBackground.Draw(spriteBatch, Color.White); //color.blendedColor);
                    spriteBatch.End();

 cameraPosition += cameraSpeed;
                            
                            cameraMatrix = Matrix.CreateTranslation(0.0f, -cameraPosition + GraphicsDevice.Viewport.Height / 3 - 50, 0.0f);
                            
                            

                            cloudExplosion.Draw(gameTime, spriteBatch, cameraMatrix);
                            foreach (FallingMan cat in cats)
                            {

                                if (cat.velocity.Y >= 10)
                                {
                                    UpdateCatFur(elapsed, cat);
                                    catFur.Draw(gameTime, spriteBatch);

                                }
                            }
           				
                            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, cameraMatrix);


//Draw the cats
                            
                            foreach (FallingMan cat in cats)
                            {
                                if (cat.backGlow)
                                {
                                    invulnExplosion.AddParticles(new Vector2(cat.collision.Center.X, cat.collision.Y));
                                    if (cat.pulse <= 0)
                                        cat.count = true;
                                    if (cat.pulse >= 40)
                                        cat.count = false;

                                    if (cat.count)
                                    {
                                        if (cat.elapsedTimePulse >= timePulse)
                                        {
                                            cat.pulse++;
                                            elapsedTimePulse = 0;
                                        }
                                    }
                                    else
                                    {
                                        if (cat.elapsedTimePulse >= timePulse)
                                        {
                                            cat.pulse--;
                                            cat.elapsedTimePulse = 0;
                                        }
                                    }

                                    if (cat.flip == SpriteEffects.None)
                                    {

                                        cat.backPos.X = cat.collision.Center.X - ((pulse + cat.backGlowTexture.Width) / 2);
                                        cat.backPos.Y = cat.collision.Center.Y - (cat.backGlowTexture.Height / 2);
                                    }
                                    else
                                    {
                                        cat.backPos.X = (int)cat.position.X;
                                    }
                                    
                                    spriteBatch.Draw(cat.backGlowTexture, new Rectangle(cat.backPos.X, cat.backPos.Y, cat.frameSize.X + pulse, cat.frameSize.Y + pulse), Color.LightYellow);
                                }
                            }
                            foreach (FallingMan cat in cats)
                            {


                                cat.Draw(gameTime, spriteBatch);

                            }
                            
                 			
           				
                            
           				
                          
                              
           				
   	//Draw all the objects other then the player to the screen
                            
                            GraphicsDevice.BlendState = BlendState.AlphaBlend;


                            foreach (Platform p in platforms)
                            {
                                p.Draw(gameTime, spriteBatch);
                            }
                            
                            foreach (PowerUp pow in powerUps)
                            {
                                pow.Draw(gameTime, spriteBatch);
                            }
                            
                            foreach (Airplane air in airPlanes)
                            {
                                air.Draw(gameTime, spriteBatch);
                            }
                            foreach (Bird bird in birds)
                            {
                                bird.Draw(gameTime, spriteBatch);
                            }
                            foreach (Fan fan in fans)
                            {
                                fan.Draw(gameTime, spriteBatch);
                            }
                            
                            spriteBatch.End();
                            
                          

//Draw the ViewFinders


                            foreach (ViewFinder view in viewFinders)
                            {

                                view.Draw(gameTime, spriteBatch, platforms, clouds, powerUps, birds, airPlanes);


                            }
         				

                

 	

}





I'm experimenting with RenderTargets throughout the draw code also but I keep getting a purple screen when I do. Could that be because I might be doing a RenderTarget within a RenderTarget because of how the code is structured?

Like


Graphics.SetRenderTarget2D(example1);

Graphics.SetRenderTarget2D(example2);

//Drawing stuff here

Graphics.SetRenderTarget2D(null);



#4 laztrezort   Members   -  Reputation: 954

Like
0Likes
Like

Posted 16 October 2011 - 01:31 AM

I'm not really an expert on this stuff, but have you tried setting RenderTargetUsage to PreserveContents (or whatever it's called)? The framework may be discarding the rendertarget buffer before it gets drawn, and would explain the purple screen.

#5 Subliminalman   Members   -  Reputation: 109

Like
0Likes
Like

Posted 16 October 2011 - 01:36 AM

No I haven't but doesnt that cause issues with the Xbox 360?

#6 laztrezort   Members   -  Reputation: 954

Like
0Likes
Like

Posted 16 October 2011 - 01:45 PM

No I haven't but doesnt that cause issues with the Xbox 360?


As far as I know, there are just some performance considerations with the Xbox and rendertargets. In XNA 4 they apparently changed the interface so that behavior (but not performance!) is the same across platforms. The usual advice is to get something working first, then make a determination if optimization is needed.

Of course, as I said, I'm not really the expert here, so maybe someone else can give a more detailed or accurate answer.

#7 Subliminalman   Members   -  Reputation: 109

Like
0Likes
Like

Posted 22 October 2011 - 09:20 PM

As far as I know, there are just some performance considerations with the Xbox and rendertargets. In XNA 4 they apparently changed the interface so that behavior (but not performance!) is the same across platforms. The usual advice is to get something working first, then make a determination if optimization is needed.

Of course, as I said, I'm not really the expert here, so maybe someone else can give a more detailed or accurate answer.


So I figured it out!





Here's the code so if anyone is doing something like this they can use it! 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<Effect>(@"Shaders\viewMask");
            pointer = game.Content.Load<Texture2D>(@"Sprite\ViewFinder\pointer");
            lens = game.Content.Load<Texture2D>(@"Sprite\ViewFinder\lens");
            maskTexture = game.Content.Load<Texture2D>(@"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<Platform>)
                {
                    foreach (Platform platform in ((List<Platform>)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<PowerUp>)
                {
                    foreach (PowerUp powerUp in ((List<PowerUp>)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 = <spherePort>;
};

sampler TextureSamplerMask = sampler_state
{
	Texture = <mask>;
};

// 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();
    }
}






Thanks for the Help :D




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS