XNA Dispose 功能在切换渲染目标时导致视觉错误

问题描述 投票:0回答:1

目前正在使用 XNA 和 MonoGame 开发一款游戏,但在尝试渲染背景时遇到了视觉错误,背景应该始终出现在精灵后面。

背景渲染目标偶尔会在精灵顶部闪烁,而它应该始终出现在后面。

当我使用 RenderTarget2D.Dispose() 函数时,我已经将其范围缩小到了一些破坏的范围,因为当我不处理渲染目标时,它工作得很好。


/*  <DRAW ENTITIES>  */

spriteBatch.GraphicsDevice.SetRenderTarget(entityRt);
spriteBatch.GraphicsDevice.Clear(Color.Transparent);
spriteBatch.Begin(SpriteSortMode.BackToFront, samplerState: SamplerState.PointClamp);
for (int i = 0; i < entities.Count; i++)
    entities[i].Draw();
spriteBatch.End();
spriteBatch.GraphicsDevice.SetRenderTarget(null);

/*  </DRAW ENTITIES>  */


/*  <HANDLE BACKGROUND EFFECT>  */
MouseState mouseState = Mouse.GetState();
Point mousePos = mouseState.Position;
            
RenderTarget2D newPrev = new RenderTarget2D(spriteBatch.GraphicsDevice, BackgroundBuffer1.Width, BackgroundBuffer1.Height);
spriteBatch.GraphicsDevice.SetRenderTarget(newPrev);
spriteBatch.GraphicsDevice.Clear(Color.Transparent);
spriteBatch.Begin();
            
spriteBatch.Draw(BackgroundBuffer1,
    new Rectangle(0, 0, BackgroundBuffer1.Width, BackgroundBuffer1.Height),
    Color.White);

spriteBatch.Draw(DrawUtils.createTexture(spriteBatch.GraphicsDevice),
    new Vector2((int)(mousePos.X * PixelateMultiplier), (int)(mousePos.Y * PixelateMultiplier)),
    Color.White);
            
spriteBatch.End();
spriteBatch.GraphicsDevice.SetRenderTarget(null);

(BackgroundBuffer1, newPrev) = (newPrev, BackgroundBuffer1);
newPrev.Dispose(); //<<==== PROBLEM LINE

/*  </HANDLE BACKGROUND EFFECT>  */


/*  <DRAW TO SCREEN>  */
spriteBatch.GraphicsDevice.SetRenderTarget(null);
spriteBatch.GraphicsDevice.Clear(Color.Transparent);
spriteBatch.Begin(samplerState: SamplerState.PointClamp, effect: CRTShader, sortMode: SpriteSortMode.Immediate);

spriteBatch.Draw(BackgroundBuffer1, //<<== Can be deleted and will still have a problem
    new Rectangle(0, 0, Globals.Camera.Width, Globals.Camera.Height),
    Color.White);

spriteBatch.Draw(entityRt, 
    new Rectangle(0, 0, Globals.Camera.Width, Globals.Camera.Height), 
    Color.White);

spriteBatch.End();

/*  <DRAW TO SCREEN>  */

在代码片段中,行

newPrev.Dispose();
可以移动到任何地方,代码仍然会有问题。只有当我完全忽略它时,代码才不会出现闪烁问题。

它似乎在

newPrev
之上渲染
entityRt
中的内容,因为即使不将BackgroundBuffer1渲染到屏幕上,视觉闪烁的故障仍然会弹出。我通过删除线
spriteBatch.Draw(BackgroundBuffer1...

来测试这一点
c# xna game-development monogame
1个回答
0
投票

通常,对于这样的效果,您会在程序(或场景)开始时(例如在

Initialize()
中)创建一个 RenderTarget(或一些 RenderTarget 的池)并在每一帧重用它(它们) - 从而避免创建(并处置)每帧一个新的 RenderTarget。

仅当您的分辨率发生变化或 RT 变得不可用时,您才重新创建 RT,并且仅当程序停止或不再需要效果时才将其丢弃。

那么,交换引用也是没有必要的:

(BackgroundBuffer1, newPrev) = (newPrev, BackgroundBuffer1);
© www.soinside.com 2019 - 2024. All rights reserved.