【问题标题】:Rendering to texture fills texture with color in XNA渲染到纹理用 XNA 中的颜色填充纹理
【发布时间】:2012-09-11 02:34:56
【问题描述】:

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

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

一切都是二维的,这是我的代码:

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);

【问题讨论】:

    标签: c# xna


    【解决方案1】:

    您遇到的问题是设置渲染目标 - 并且后台缓冲区算作渲染目标 - 将清除该渲染目标。

    至少如果设置了RenderTargetUsage.DiscardContents (MSDN)。这是默认设置,因为它是唯一在 Xbox 360 上表现良好的设备,在 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 时,您才应使用第二种方法。

    【讨论】:

    • 谢谢,这是一个仅限Windows的游戏,我会试试这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多