簡體   English   中英

XNA 4.0 SpriteBatch.Draw發生內存不足異常

[英]XNA 4.0 SpriteBatch.Draw Out Of Memory Exception Thrown

好吧,首先,我的猜測是我要多次調用spritebatch.draw()方法,但是我需要(或者,這是我唯一能弄清楚方法的方法)繪制游戲窗口。 我將繼續轉儲我的代碼。

我的窗戶課;

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace System.Window
{
class Window
{
    #region Variables

    public Texture2D importedTexture;
    public Texture2D WindowSkin;
    public RenderTarget2D currentWindow;
    public RenderTarget2D windowTexture;

    public Vector2 pos;

    public int prevWindowWidth;
    public int prevWindowHeight;
    public int windowWidth;
    public int windowHeight;

    public bool visible;
    public bool active;
    public bool drawNew;

    #region Rectangles

    public Rectangle clickRect;
    public Rectangle topLeftRect;
    public Rectangle topRightRect;
    public Rectangle buttonRect;
    public Rectangle botLeftRect;
    public Rectangle botRightRect;


    #endregion

    #endregion

    public Window()
    {

    }

    public void Initialize(GraphicsDevice g, Texture2D ws, Texture2D it, int w, int h, bool v, bool a)
    {
        WindowSkin = ws;
        importedTexture = it;

        windowWidth = w;
        prevWindowWidth = w;

        windowHeight = h;
        prevWindowHeight = h;

        windowTexture = new RenderTarget2D(g, windowWidth, windowHeight);
        currentWindow = windowTexture;

        visible = v;
        active = a;

        drawNew = true;

        topLeftRect = new Rectangle(0, 0, 32, 32);
        topRightRect = new Rectangle(32, 0, 32, 32);
        buttonRect = new Rectangle(64, 0, 32, 32);
        botLeftRect = new Rectangle(0, 64, 32, 32);
        botRightRect = new Rectangle(64, 64, 32, 32);

    }

    public void Update(GraphicsDevice g, Vector2 p, int width, int height)
    {
        prevWindowWidth = windowWidth;
        prevWindowHeight = windowHeight;

        pos = p;
        windowWidth = width;
        windowHeight = height;
        windowTexture = new RenderTarget2D(g, windowWidth+2, windowHeight+2);

    }

    public void Draw(SpriteBatch s, GraphicsDevice g)
    {


        s.Draw(currentWindow, pos, new Rectangle(0, 0, windowWidth, windowHeight), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);

    }

    public void DrawNewWindow(SpriteBatch s, GraphicsDevice g)
    {

            g.SetRenderTarget(windowTexture);
            g.Clear(Color.Transparent);

            s.Begin();

            #region Draw Background

            for (int w = 3; w < (windowWidth); w += 32)
            {
                for (int h = 32; h < (windowHeight); h += 32)
                {
                    s.Draw(WindowSkin, new Vector2(w, h), new Rectangle(32, 32, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
                }
            }

            #endregion

            s.Draw(importedTexture, new Vector2(3, 32), new Rectangle(0, 0, importedTexture.Width, importedTexture.Height), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);


            #region Draw resizables

            for (int i = 32; i < (windowWidth - 64); i += 32)
            {
                s.Draw(WindowSkin, new Vector2(i, 0), new Rectangle(16, 0, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            }
            for (int i = 32; i < (windowWidth - 32); i += 32)
            {
                s.Draw(WindowSkin, new Vector2(i, windowHeight - 32), new Rectangle(32, 64, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            }
            for (int i = 64; i < (windowHeight - 32); i += 32)
            {
                s.Draw(WindowSkin, new Vector2(0, i), new Rectangle(0, 48, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            }
            for (int i = 64; i < (windowHeight - 32); i += 32)
            {
                s.Draw(WindowSkin, new Vector2(windowWidth - 32, i), new Rectangle(64, 48, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            }

            #endregion

            #region Draw Corners

            s.Draw(WindowSkin, new Vector2(0, 0), topLeftRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            s.Draw(WindowSkin, new Vector2(0, 32), new Rectangle(0, 32, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);

            s.Draw(WindowSkin, new Vector2(windowWidth - 64, 0), topRightRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            s.Draw(WindowSkin, new Vector2(windowWidth - 32, 32), new Rectangle(64, 32, 32, 32), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);

            s.Draw(WindowSkin, new Vector2(windowWidth - 32, 0), buttonRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            s.Draw(WindowSkin, new Vector2(0, windowHeight - 32), botLeftRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            s.Draw(WindowSkin, new Vector2(windowWidth - 32, windowHeight - 32), botRightRect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);

            #endregion

            s.End();

            currentWindow = windowTexture;

    }
}
}

我的Draw()方法;

        protected override void Draw(GameTime gameTime)
    {

            window1.DrawNewWindow(spriteBatch, GraphicsDevice);
            window1.drawNew = false;


        GraphicsDevice.SetRenderTarget(null);
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin(SpriteSortMode.Deferred,
                    BlendState.AlphaBlend,
                    SamplerState.PointClamp,
                    null,
                    null,
                    null);

        window1.Draw(spriteBatch, GraphicsDevice);

        spriteBatch.End();

        base.Draw(gameTime);
    }

一切都很好,並針對我的小窗戶皮膚紋理進行了配置。 唯一的問題是它會有點滯后,然后在運行它大約一分鍾后完全崩潰。 它拋出Out Of Memory Exception ,但是我不知道,也找不到任何其他與spritebatch相關的主題或帖子。 有人對我如何使它工作而不占用太多內存有任何建議嗎? 我認為這是繪制窗口的簡便,經濟高效的方法。 我只是不確定如何減少抽獎,還是要收回任何記憶。

windowTexture =新的RenderTarget2D(g,windowWidth + 2,windowHeight + 2);

可能是罪魁禍首的一部分。 盡量不要在每次更新時實例化新內容。 它大約每秒發生60次,並可能導致嚴重的開銷。 而是使用Initialize方法初始化渲染目標。

RenderTarget2D實現了IDisposable:使用完IDisposable:您應該始終在其上調用Dispose(),因為它可能容納不受管理的資源(如Direct3D表面)。 這是您看到的內存泄漏的根本原因。

當然,正如已經提到的那樣,在每個Draw()上實例化一個新的RenderTarget2D並不是一個好主意,因為這是一個昂貴的調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM