渲染到纹理填充纹理与XNA中的颜色

时间:2012-09-11 02:34:57

标签: c# xna

我在XNA工作,遇到了以下问题:我的目标是将一些不同的纹理绘制到纹理,然后使用给定的alpha值将最终纹理绘制到屏幕上。

问题在于我绘制的纹理是全屏并且填充了颜色而不是透明度,因此它会阻挡其背后的所有内容。

一切都是2d,这是我的代码:

public void Draw(SpriteBatch sb)
            {
            if (opacity > 0)
                {
                gd.SetRenderTarget(formTexture);
                gd.Clear(Color.Transparent);
                for (int i=0; i<formItems.Count; i++)
                    {
                    ((FormItem)formItems[i]).draw(sb);
                    }
                sb.Begin(SpriteSortMode.Immediate, BlendState.Additive);
                    for (int i=0; i<formItems.Count; i++)
                        {
                        FormItem fi = (formItems[i] as FormItem);
                        if (fi.glow != null)
                            {
                            sb.Draw(fi.glow, new Rectangle((int) fi.location.X + fi.width/2 - fi.glow.Width/2, (int) fi.location.Y + fi.height/2 - fi.glow.Height/2, fi.glow.Width, fi.glow.Height), Color.White);
                            }
                        }
                sb.End();
                gd.SetRenderTarget(null);
                sb.Begin();
                sb.Draw(formTexture, new Rectangle(0, 0, gd.Viewport.Width, gd.Viewport.Height), Color.White*opacity);
                sb.End();
                }
            }

formTexture是一个RenderTarget2D对象,gd是图形设备。这就是formTexture的初始化方式:

formTexture = new RenderTarget2D(this.gd, this.windowWidth, this.windowHeight);

1 个答案:

答案 0 :(得分:1)

您遇到的问题是设置渲染目标 - 并且后备缓冲区计为渲染目标 - 将清除渲染目标

至少设置RenderTargetUsage.DiscardContentsMSDN)。这是默认设置,因为它是唯一一个在Xbox 360上运行良好的设备,其中保留内容需要昂贵的副本。 (并且它是Windows上的默认设置,只是为了保持行为相同的跨平台)。

你的后备缓冲区被清除到这条线上的“呐喊这是一个新的缓冲区”颜色(通常是紫色):

gd.SetRenderTarget(null);

有两种解决方法:

首选方式是对所有渲染进行排序,以便在帧的开头设置渲染目标,然后将场景绘制到后备缓冲区。永远不要多次触摸渲染目标。


另一种方法是将事件附加到GraphicsDeviceManager.PreparingDeviceSettings,设置后备缓冲区使用RenderTargetUsage.PreserveContents

void SetBackbufferPreserveContents(object sender,
                                   PreparingDeviceSettingsEventArgs e)
{
    e.GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage
            = RenderTargetUsage.PreserveContents;
}

// in your game constructor:
graphics.PreparingDeviceSettings += SetBackbufferPreserveContents;

如果您的游戏专门针对Windows,则应该只使用第二种方法。