} // Show() #endregion #region Unit Testing #if DEBUG /// <summary> /// Test post screen glow /// </summary> public static void TestPostScreenGlow() { Model testModel = null; PostScreenGlow glowShader = null; TestGame.Start("TestPostScreenGlow", delegate { testModel = new Model("Asteroid2"); glowShader = new PostScreenGlow(); }, delegate { //Thread.Sleep(10); glowShader.Start(); BaseGame.skyCube.RenderSky(); testModel.Render(Vector3.Zero); BaseGame.MeshRenderManager.Render(); if (Input.Keyboard.IsKeyDown(Keys.LeftAlt) == false && Input.GamePadAPressed == false) { glowShader.Show(); } else { // Resolve first glowShader.sceneMapTexture.Resolve(false); started = false; // Reset background buffer RenderToTexture.ResetRenderTarget(true); // Just show scene map glowShader.sceneMapTexture.RenderOnScreen(BaseGame.ResolutionRect); } // else TextureFont.WriteText(2, 30, "Press left alt or A to just show the unchanged screen."); TextureFont.WriteText(2, 60, "Press space or B to see all menu post screen render passes."); //*TODO if (Input.Keyboard.IsKeyDown(Keys.Space) || // == false) Input.GamePadBPressed) { glowShader.sceneMapTexture.RenderOnScreen( new Rectangle(10, 10, 256, 256)); glowShader.downsampleMapTexture.RenderOnScreen( new Rectangle(10 + 256 + 10, 10, 256, 256)); glowShader.blurMap1Texture.RenderOnScreen( new Rectangle(10 + 256 + 10 + 256 + 10, 10, 256, 256)); glowShader.blurMap2Texture.RenderOnScreen( new Rectangle(10, 10 + 256 + 10, 256, 256)); } // if (Input.Keyboard.IsKeyDown) }); } // TestPostScreenGlow()
} // GetParameters() #endregion #region Start /// <summary> /// Start this post screen shader, will just call SetRenderTarget. /// All render calls will now be drawn on the sceneMapTexture. /// Make sure you don't reset the RenderTarget until you call Show()! /// </summary> public void Start() { // Only apply post screen shader if texture is valid and effect is valid if (sceneMapTexture == null || effect == null || started == true || // Also skip if we don't use post screen shaders at all! BaseGame.UsePostScreenShaders == false) { return; } RenderToTexture.SetRenderTarget(sceneMapTexture.RenderTarget, true); started = true; } // Start()
//*/ /// <summary> /// Test create render to texture /// </summary> public static void TestCreateRenderToTexture() { Model testModel = null; RenderToTexture renderToTexture = null; TestGame.Start( "TestCreateRenderToTexture", delegate { testModel = new Model("asteroid1"); renderToTexture = new RenderToTexture( //SizeType.QuarterScreen); SizeType.HalfScreen); //SizeType.HalfScreenWithZBuffer); //SizeType.FullScreen); //SizeType.ShadowMap); }, delegate { bool renderToTextureWay = Input.Keyboard.IsKeyUp(Keys.Space) && Input.GamePadAPressed == false; BaseGame.Device.RenderState.DepthBufferEnable = true; if (renderToTextureWay) { // Set render target to our texture renderToTexture.SetRenderTarget(); // Clear background renderToTexture.Clear(Color.Blue); // Draw background lines //Line.DrawGrid(); //Ui.LineManager.RenderAll3DLines(); // And draw object testModel.Render(Matrix.CreateScale(7.5f)); //BaseGame.RenderManager.RenderAllMeshes(); // Do we need to resolve? renderToTexture.Resolve(true); //BaseGame.Device.ResolveRenderTarget(0); // Reset background buffer //not longer required, done in Resolve now: //RenderToTexture.ResetRenderTarget(true); } // if (renderToTextureWay) else { // Copy backbuffer way, render stuff normally first // Clear background BaseGame.Device.Clear(Color.Blue); // Draw background lines //Line.DrawGrid(); //Ui.LineManager.RenderAll3DLines(); // And draw object testModel.Render(Matrix.CreateScale(7.5f)); //BaseGame.RenderManager.RenderAllMeshes(); } // else // Show render target in a rectangle on our screen renderToTexture.RenderOnScreen( //tst: new Rectangle(100, 100, 256, 256)); //BaseGame.ScreenRectangle); //no need: BaseGame.UI.FlushUI(); TextureFont.WriteText(2, 0, " Press Space to toogle full screen rendering"); TextureFont.WriteText(2, 30, "renderToTexture.Width=" + renderToTexture.Width); TextureFont.WriteText(2, 60, "renderToTexture.Height=" + renderToTexture.Height); TextureFont.WriteText(2, 90, "renderToTexture.Valid=" + renderToTexture.IsValid); TextureFont.WriteText(2, 120, "renderToTexture.XnaTexture=" + renderToTexture.XnaTexture); TextureFont.WriteText(2, 150, "renderToTexture.ZBufferSurface=" + renderToTexture.ZBufferSurface); TextureFont.WriteText(2, 180, "renderToTexture.Filename=" + renderToTexture.Filename); }); }
/// <summary> /// Add render to texture instance to allow recreating them all /// when DeviceReset is called with help of the remRenderToTextures list. /// </summary> public static void AddRemRenderToTexture(RenderToTexture renderToTexture) { remRenderToTextures.Add(renderToTexture); }
/// <summary> /// Dispose /// </summary> /// <param name="someObject">Some object</param> public static void Dispose(ref RenderToTexture someObject) { if (someObject != null) someObject.Dispose(); someObject = null; }
} // Start() #endregion #region Show /// <summary> /// Execute shaders and show result on screen, Start(..) must have been /// called before and the scene should be rendered to sceneMapTexture. /// </summary> public void Show() { // Only apply post screen glow if texture is valid and effect is valid if (sceneMapTexture == null || Valid == false || started == false) { return; } started = false; // Resolve sceneMapTexture render target for Xbox360 support sceneMapTexture.Resolve(true); try { // Don't use or write to the z buffer BaseGame.Device.RenderState.DepthBufferEnable = false; BaseGame.Device.RenderState.DepthBufferWriteEnable = false; // Also don't use any kind of blending. BaseGame.Device.RenderState.AlphaBlendEnable = false; //unused: BaseGame.Device.RenderState.Lighting = false; if (windowSize != null) { windowSize.SetValue(new float[] { sceneMapTexture.Width, sceneMapTexture.Height }); } if (sceneMap != null) { sceneMap.SetValue(sceneMapTexture.XnaTexture); } if (downsampleMap != null) { downsampleMap.SetValue(downsampleMapTexture.XnaTexture); } if (blurMap1 != null) { blurMap1.SetValue(blurMap1Texture.XnaTexture); } if (blurMap2 != null) { blurMap2.SetValue(blurMap2Texture.XnaTexture); } if (radialSceneMap != null) { radialSceneMap.SetValue(radialSceneMapTexture.XnaTexture); } RadialBlurScaleFactor = //-0.0125f; // Warning: To big values will make the motion blur look to // stepy (we see each step and thats not good). -0.02 should be max. -(0.005f + Player.Speed * 0.015f); if (BaseGame.UsePS20) { effect.CurrentTechnique = effect.Techniques["ScreenGlow20"]; } else { effect.CurrentTechnique = effect.Techniques["ScreenGlow"]; } // We must have exactly 5 passes! if (effect.CurrentTechnique.Passes.Count != 5) { throw new Exception("This shader should have exactly 5 passes!"); } effect.Begin(); //SaveStateMode.None); for (int pass = 0; pass < effect.CurrentTechnique.Passes.Count; pass++) { if (pass == 0) { radialSceneMapTexture.SetRenderTarget(); } else if (pass == 1) { downsampleMapTexture.SetRenderTarget(); } else if (pass == 2) { blurMap1Texture.SetRenderTarget(); } else if (pass == 3) { blurMap2Texture.SetRenderTarget(); } else { // Do a full reset back to the back buffer RenderToTexture.ResetRenderTarget(true); } EffectPass effectPass = effect.CurrentTechnique.Passes[pass]; effectPass.Begin(); // For first effect we use radial blur, draw it with a grid // to get cooler results (more blur at borders than in middle). if (pass == 0) { VBScreenHelper.Render10x10Grid(); } else { VBScreenHelper.Render(); } effectPass.End(); if (pass == 0) { radialSceneMapTexture.Resolve(false); if (radialSceneMap != null) { radialSceneMap.SetValue(radialSceneMapTexture.XnaTexture); } effect.CommitChanges(); } // if else if (pass == 1) { downsampleMapTexture.Resolve(false); if (downsampleMap != null) { downsampleMap.SetValue(downsampleMapTexture.XnaTexture); } effect.CommitChanges(); } // if else if (pass == 2) { blurMap1Texture.Resolve(false); if (blurMap1 != null) { blurMap1.SetValue(blurMap1Texture.XnaTexture); } effect.CommitChanges(); } // else if else if (pass == 3) { blurMap2Texture.Resolve(false); if (blurMap2 != null) { blurMap2.SetValue(blurMap2Texture.XnaTexture); } effect.CommitChanges(); } // else if } // for (pass, <, ++) } // try catch (Exception ex) { // Make effect invalid, continue rendering without this // post screen shader. effect = null; RenderToTexture.ResetRenderTarget(true); #if DEBUG throw ex; #else Log.Write("Failed to render post screen shader " + Filename + ": " + ex.ToString()); #endif } // catch finally { if (effect != null) { effect.End(); } // Restore z buffer state BaseGame.Device.RenderState.DepthBufferEnable = true; BaseGame.Device.RenderState.DepthBufferWriteEnable = true; } // finally } // Show()
} // Dispose() #endregion #region Reload /// <summary> /// Reload /// </summary> public void Load() { if (effect != null) { return; } // Dispose old shader //Dispose(); // Scene map texture sceneMapTexture = new RenderToTexture( RenderToTexture.SizeType.FullScreen); // Downsample map texture (to 1/4 of the screen) downsampleMapTexture = new RenderToTexture( RenderToTexture.SizeType.QuarterScreen); // Blur map texture blurMap1Texture = new RenderToTexture( RenderToTexture.SizeType.QuarterScreen); // Blur map texture blurMap2Texture = new RenderToTexture( RenderToTexture.SizeType.QuarterScreen); // Final map for glow, used to perform radial blur next step radialSceneMapTexture = new RenderToTexture( RenderToTexture.SizeType.FullScreen); string shaderContentName = Filename; // Load shader try { // We have to try, there is no "Exists" method. // We could try to check the xnb filename, but why bother? ^^ effect = BaseGame.Content.Load <Effect>( Path.Combine(Directories.ContentDirectory, shaderContentName)); } // try #if XBOX360 catch (Exception ex) { Log.Write("Failed to load shader " + shaderContentName + ". " + "Error: " + ex.ToString()); // Rethrow error, app can't continue! throw ex; } #else catch { // Try again by loading by filename (only allowed for windows!) // Content file was most likely removed for easier testing :) try { CompiledEffect compiledEffect = Effect.CompileEffectFromFile( Path.Combine("Shaders", shaderContentName + ".fx"), null, null, CompilerOptions.None, TargetPlatform.Windows); effect = new Effect(BaseGame.Device, compiledEffect.GetEffectCode(), CompilerOptions.None, null); } // try catch (Exception ex) { /*obs * Log.Write("Failed to compile shader, this happend most likely " + * "because the shader has some syntax error, please check it. " + * "Error: " + ex.ToString()); */ Log.Write("Failed to load shader " + shaderContentName + ". " + "Error: " + ex.ToString()); // Rethrow error, app can't continue! throw ex; } // catch } // catch #endif // Reset and get all avialable parameters. // This is especially important for derived classes. ResetParameters(); GetParameters(); } // Load()
} // ResetRenderTarget(fullResetToBackBuffer) #endregion #region Unit Testing #if DEBUG /// <summary> /// Test create render to texture /// </summary> static public void TestCreateRenderToTexture() { Model testModel = null; RenderToTexture renderToTexture = null; TestGame.Start( "TestCreateRenderToTexture", delegate { testModel = new Model("asteroid1"); renderToTexture = new RenderToTexture( //SizeType.QuarterScreen); SizeType.HalfScreen); //SizeType.HalfScreenWithZBuffer); //SizeType.FullScreen); //SizeType.ShadowMap); }, delegate { bool renderToTextureWay = Input.Keyboard.IsKeyUp(Keys.Space) && Input.GamePadAPressed == false; BaseGame.Device.RenderState.DepthBufferEnable = true; if (renderToTextureWay) { // Set render target to our texture renderToTexture.SetRenderTarget(); // Clear background renderToTexture.Clear(Color.Blue); // Draw background lines //Line.DrawGrid(); //Ui.LineManager.RenderAll3DLines(); // And draw object testModel.Render(Matrix.CreateScale(7.5f)); //BaseGame.RenderManager.RenderAllMeshes(); // Do we need to resolve? renderToTexture.Resolve(true); //BaseGame.Device.ResolveRenderTarget(0); // Reset background buffer //not longer required, done in Resolve now: //RenderToTexture.ResetRenderTarget(true); } // if (renderToTextureWay) else { // Copy backbuffer way, render stuff normally first // Clear background BaseGame.Device.Clear(Color.Blue); // Draw background lines //Line.DrawGrid(); //Ui.LineManager.RenderAll3DLines(); // And draw object testModel.Render(Matrix.CreateScale(7.5f)); //BaseGame.RenderManager.RenderAllMeshes(); } // else // Show render target in a rectangle on our screen renderToTexture.RenderOnScreen( //tst: new Rectangle(100, 100, 256, 256)); //BaseGame.ScreenRectangle); //no need: BaseGame.UI.FlushUI(); TextureFont.WriteText(2, 0, " Press Space to toogle full screen rendering"); TextureFont.WriteText(2, 30, "renderToTexture.Width=" + renderToTexture.Width); TextureFont.WriteText(2, 60, "renderToTexture.Height=" + renderToTexture.Height); TextureFont.WriteText(2, 90, "renderToTexture.Valid=" + renderToTexture.IsValid); TextureFont.WriteText(2, 120, "renderToTexture.XnaTexture=" + renderToTexture.XnaTexture); TextureFont.WriteText(2, 150, "renderToTexture.ZBufferSurface=" + renderToTexture.ZBufferSurface); TextureFont.WriteText(2, 180, "renderToTexture.Filename=" + renderToTexture.Filename); }); } // TestCreateRenderToTexture()
/// <summary> /// Add render to texture instance to allow recreating them all /// when DeviceReset is called with help of the remRenderToTextures list. /// </summary> public static void AddRemRenderToTexture(RenderToTexture renderToTexture) { remRenderToTextures.Add(renderToTexture); } // AddRemRenderToTexture(renderToTexture)
/// <summary> /// Reload /// </summary> public void Load() { if (effect != null) return; // Dispose old shader //Dispose(); // Scene map texture sceneMapTexture = new RenderToTexture( RenderToTexture.SizeType.FullScreen); // Downsample map texture (to 1/4 of the screen) downsampleMapTexture = new RenderToTexture( RenderToTexture.SizeType.QuarterScreen); // Blur map texture blurMap1Texture = new RenderToTexture( RenderToTexture.SizeType.QuarterScreen); // Blur map texture blurMap2Texture = new RenderToTexture( RenderToTexture.SizeType.QuarterScreen); // Final map for glow, used to perform radial blur next step radialSceneMapTexture = new RenderToTexture( RenderToTexture.SizeType.FullScreen); string shaderContentName = Filename; // Load shader try { // We have to try, there is no "Exists" method. // We could try to check the xnb filename, but why bother? ^^ effect = BaseGame.Content.Load<Effect>( Path.Combine(Directories.ContentDirectory, shaderContentName)); } // try #if XBOX360 catch (Exception ex) { Log.Write("Failed to load shader "+shaderContentName+". " + "Error: " + ex.ToString()); // Rethrow error, app can't continue! throw ex; } #else catch { // Try again by loading by filename (only allowed for windows!) // Content file was most likely removed for easier testing :) try { CompiledEffect compiledEffect = Effect.CompileEffectFromFile( Path.Combine("Shaders", shaderContentName + ".fx"), null, null, CompilerOptions.None, TargetPlatform.Windows); effect = new Effect(BaseGame.Device, compiledEffect.GetEffectCode(), CompilerOptions.None, null); } // try catch (Exception ex) { /*obs Log.Write("Failed to compile shader, this happend most likely " + "because the shader has some syntax error, please check it. " + "Error: " + ex.ToString()); */ Log.Write("Failed to load shader " + shaderContentName + ". " + "Error: " + ex.ToString()); // Rethrow error, app can't continue! throw ex; } // catch } // catch #endif // Reset and get all avialable parameters. // This is especially important for derived classes. ResetParameters(); GetParameters(); }