XNA Creators Club Online
Page 1 of 1 (3 items)
Sort Posts: Previous Next

Post Processing

Last post 4/14/2007 3:56 PM by John Sedlak. 2 replies.
  • 4/14/2007 10:44 AM

    Post Processing

    My game currently uses multiple screens to represent different things to be rendered to the game screen.  For instance I have a screen that renders the 3D scene and another screen that renders the GUI ontop of the 3D scene.  The screens are stack based and drawn from bottom to top.

     I'm trying to apply different post processing effects to each screen.  I'm having trouble because I can't get the transparency to work right for screens that require transparent values.  The GUI won't allow the 3D scene to be shown because when I draw the GUI I must clear the render target used by the post processing effect.

     Heres my code for drawing a screen.  Each frame of my game I iterate through every screen and draw them.  The ScreenManager calls the screen's BeginDraw(), Draw(GameTime gameTime), then EndDraw() methods.

     internal void BeginDraw()

    {

        // Change to the off screen render target.

        this.previousTarge t= this.Graphics.GraphicsDevice.GetRenderTarget(0) as RenderTarget2D;

        this.Graphics.GraphicsDevice.SetRenderTarget(0, this.renderTarget);

        this.Graphics.GraphicsDevice.Clear(Color.TransparentWhite);

    }

     

    internal void EndDraw()

    {

        // Change back to the back buffer and get the scene as a texture.

        this.Graphics.GraphicsDevice.ResolveRenderTarget(0);

        this.shaderTexture = this.renderTarget.GetTexture();

        this.Graphics.GraphicsDevice.SetRenderTarget(0, this.previousTarget);

        // Draw the screen.

        this.spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);

        if (this.effects.Count == 0)

        {

            this.spriteBatch.Draw(this.shaderTexture, Vector2.Zero, Color.White);

        }

        else

        {

            foreach (Effect effect in this.effects)

            {

                effect.Begin();

                // Activate each pass in the effect.

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)

                {

                    pass.Begin();

                    this.spriteBatch.Draw(this.shaderTexture, Vector2.Zero, Color.White);

                    pass.End();

                }

            }

            this.spriteBatch.End();

    }

  • 4/14/2007 11:41 AM In reply to

    Re: Post Processing

    Full screen quad is the good solution. SpriteBatch were designed for 2d games. Not as part of gui systems inside of 3d apps. As you already see it's a bit complicated to use spritebatches together with 3d.
     
  • 4/14/2007 3:56 PM In reply to

    Re: Post Processing

    Answer
    Reply Quote

    You SceneManager should work in a Tree Based fashion. It should contain rendering groups that each render to the backbuffer or their own render target. The important thing is that after each group is rendered, the original state has to be returned to. So the order of things should be something as follows...

    1. Clear screen

    2. Put in a global render target

    3. Render Group 1 through N

    3a. Put in local render target.

    3b. Render

    3c. Restore old render target

    3d. Render local target to now restored render target, with post process

    4. Post process global render target to back buffer

     

    After that, it is just a matter of getting the device states correctly. You have to make sure you have alpha blending correctly or else when you render a local render target, it will overlay what was there. You also have to watch where you clear, Xna5D's post processing framework only clears once or twice, as high up in the rendering tree as possible.

    John Sedlak Xna/DirectX MVP
    XNA Articles, Tutorials and Videos | My Blog
Page 1 of 1 (3 items) Previous Next