2012-12-11 8 views
3

Reach 그래픽 설정을 사용하여 C# XNA 4.0으로 코딩 된 Windows 플랫폼 게임이 있습니다. 내 프로젝트는 GameStateManagement 샘플을 기반으로하지만 나중에 Bloom과 spriteSheet/spriteBatch 기능을 추가했습니다.XNA 스크린 샷은 블룸 이전, 최종 렌더링이 표시되지 않습니다.

마지막 스크린 출력을 저장 한 스크린 샷을 원합니다. 그러나 스크린 샷을 저장하면 Bloom이 적용되기 전과 HUD 텍스트가 표시되기 전에 렌더링 만 표시됩니다 (Bloom 이후에 그립니다). 이 두 프로세스 후에 내 Draw 메서드의 끝에 저장된 스크린 샷이 있습니다.

나는 모든 종류의 것을 시도했다. 앤드류의 대답은 여기 Take screen shot in XNA이 도움이되었으며 이미지를 저장하지 않았습니다. 그러나 최종 렌더링을 저장하지는 않습니다.

필자는 블룸 프로세스 또는 스프라이트 배치와 관련이 있다고 생각합니다.

example { 
    public override void Draw(GameTime gameTime) 
    { 
     ScreenManager.GraphicsDevice.SetRenderTarget(sceneRenderTarget); 
     // Clear the screen to black 
     ScreenManager.GraphicsDevice.Clear(ClearOptions.Target, 
              Color.Black, 0, 0); 
     SpriteBatch spriteBatch = ScreenManager.SpriteBatch; 
     spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend); 

    // then i draw all my game stuff 

     spriteBatch.End(); 

     #region Post-Processing & Bloom 
     ScreenManager.GraphicsDevice.SamplerStates[1] = SamplerState.LinearClamp; 

     // Pass 1: draw the scene into rendertarget 1, using a 
     // shader that extracts only the brightest parts of the image. 
     bloomExtractEffect.Parameters["BloomThreshold"].SetValue(
      Settings.BloomThreshold); 

     DrawFullscreenQuad(sceneRenderTarget, renderTarget1, 
          bloomExtractEffect, 
          IntermediateBuffer.PreBloom); 

     // Pass 2: draw from rendertarget 1 into rendertarget 2, 
     // using a shader to apply a horizontal gaussian blur filter. 
     SetBlurEffectParameters(1.0f/(float)renderTarget1.Width, 0); 

     DrawFullscreenQuad(renderTarget1, renderTarget2, 
          gaussianBlurEffect, 
          IntermediateBuffer.BlurredHorizontally); 

     // Pass 3: draw from rendertarget 2 back into rendertarget 1, 
     // using a shader to apply a vertical gaussian blur filter. 
     SetBlurEffectParameters(0, 1.0f/(float)renderTarget1.Height); 

     DrawFullscreenQuad(renderTarget2, renderTarget1, 
          gaussianBlurEffect, 
          IntermediateBuffer.BlurredBothWays); 

     // Pass 4: draw both rendertarget 1 and the original scene 
     // image back into the main backbuffer, using a shader that 
     // combines them to produce the final bloomed result. 
     ScreenManager.GraphicsDevice.SetRenderTarget(null); 

     EffectParameterCollection parameters = bloomCombineEffect.Parameters; 

     parameters["BloomIntensity"].SetValue(Settings.BloomIntensity); 
     parameters["BaseIntensity"].SetValue(Settings.BaseIntensity); 
     parameters["BloomSaturation"].SetValue(Settings.BloomSaturation); 
     parameters["BaseSaturation"].SetValue(Settings.BaseSaturation); 

     ScreenManager.GraphicsDevice.Textures[1] = sceneRenderTarget; 

     Viewport viewport = ScreenManager.GraphicsDevice.Viewport; 

     DrawFullscreenQuad(renderTarget1, 
          viewport.Width, viewport.Height, 
          bloomCombineEffect, 
          IntermediateBuffer.FinalResult); 

     #endregion 

     spriteBatch.Begin(); 
     // Draw HUD 
     spriteBatch.End(); 


     if (screenShotTake) 
     { 
      using (FileStream fs = File.Open(@"screenshot" + (screenshotNumber) + @".png", FileMode.OpenOrCreate)) 
      { 
       // Right here I try to save out the screen shot Texture2D 
       sceneRenderTarget.SaveAsPng(fs, (int)viewportSize.X, (int)viewportSize.Y); // save render target to disk 
      } 
     } 
    } 




    #region PostProcess & Bloom 
    void DrawFullscreenQuad(Texture2D texture, RenderTarget2D renderTarget, 
          Effect effect, IntermediateBuffer currentBuffer) 
    { 
     ScreenManager.GraphicsDevice.SetRenderTarget(renderTarget); 

     DrawFullscreenQuad(texture, 
          renderTarget.Width, renderTarget.Height, 
          effect, currentBuffer); 


    } 

    void DrawFullscreenQuad(Texture2D texture, int width, int height, 
          Effect effect, IntermediateBuffer currentBuffer) 
    { 
     if (showBuffer < currentBuffer) 
     { 
      effect = null; 
     } 

     spriteBatch.Begin(0, BlendState.Opaque, null, null, null, effect); 
     spriteBatch.Draw(texture, new Rectangle(0, 0, width, height), Color.White); 
     spriteBatch.End(); 
    } 

}

+0

spriteBatch.Begin() 호출에서 SpriteSortMode.Deferred를 사용하고 있습니까? – itsme86

+0

예, 저는 : spriteBatch.Begin (SpriteSortMode.Deferred, BlendState.AlphaBlend); –

+1

왜 스크린 샷을'spritebatch.End()'전에 저장합니까? 나중에 그 일을한다면 어떻게 될지 시험해 보셨습니까? –

답변

5

문제는 여기에 있습니다 : :

이 때문에 라인의
ScreenManager.GraphicsDevice.SetRenderTarget(null); 

, 당신은 백 버퍼에 영향을 그릴 수 있지만, 렌더링 여기

내 코드입니다 당신이 저축하는 표적은 홀로 남았습니다. 효과가 직접 그려지기 때문에 효과의 결과를 볼 수 있지만, 저장하는 것은 백 버퍼에 그려진 결과가 아닙니다. 이 문제를 해결하려면 다른 RenderTarget에 효과를 그린 다음 단일 버퍼로 그 효과를 백 버퍼에 그립니다. 분명히 이것은 처리해야하는 또 다른 문제이며, 최소한의 비용입니다. 그렇게하면 새로운 RenderTarget에서 텍스처를 가져 와서 원하는대로 저장할 수 있습니다.

+0

아, 고마워. 네가 한 말은 일했다. renderTargetFinal을 작성하여 대상으로 설정 한 다음 나중에 null을 설정하고 final을 null로 그립니다. 스크린 샷이 완벽하게 작동합니다. –