Получение Texture2D из объекта RenderTarget2D в XNA 4.0

Я просто экспериментирую с пиксельным шейдером. Я нашел хороший эффект размытия, и теперь я пытаюсь создать эффект размытия изображения снова и снова.

КАК я хочу это сделать: я хочу визуализировать свое изображение hellokittyTexture в RenderTarget, применяя эффект размытия, затем заменить hellokittyTexture на результат этого рендеринга и сделать это снова и снова. снова каждую итерацию Draw:

protected override void Draw(GameTime gameTime)
    {

        GraphicsDevice.Clear(Color.CornflowerBlue);


        GraphicsDevice.SetRenderTarget(buffer1);

        // Begin the sprite batch, using our custom effect.
        spriteBatch.Begin(0, null, null, null, null, blur);
        spriteBatch.Draw(hellokittyTexture , Vector2.Zero, Color.White);
        spriteBatch.End();
        GraphicsDevice.SetRenderTarget(null);

        hellokittyTexture = (Texture2D) buffer1;

        // Draw the texture in the screen
        spriteBatch.Begin(0, null, null, null, null, null);
        spriteBatch.Draw(hellokittyTexture , Vector2.Zero, Color.White);
        spriteBatch.End();

        base.Draw(gameTime);
    }

Но я получаю эту ошибку "Цель рендеринга не должна быть установлена ​​на устройстве, когда оно используется в качестве текстуры". Потому что hellokittyTexture = (Texture2D) buffer1; копирует не текстуру, а ссылку на RenderTarget (по сути, это тот же объект после присваивания)

Вы знаете хороший способ получить текстуру внутри RenderTarget? или более элегантный способ сделать то, что я пытаюсь?


person Chemari    schedule 11.07.2013    source источник
comment
renderTarget должен иметь какое-то поле, свойство или метод, который позволяет устанавливать данные текстуры, либо использовать их, либо просто рисовать на них свою текстуру.   -  person user1306322    schedule 12.07.2013


Ответы (2)


    spriteBatch.Draw(hellokittyTexture , Vector2.Zero, Color.White);

В этой строке вы рисуете текстуру... самой себе... Этого не может быть.

Предполагая, что buffer1 и hellokittyTexture были правильно инициализированы, замените эту строку:

    hellokittyTexture = (Texture2D) buffer1;

с этим:

        Color[] texdata = new Color[hellokittyTexture.Width * hellokittyTexture.Height];
        buffer1.GetData(texdata);
        hellokittyTexture.SetData(texdata);

Таким образом, hellokittyTexture будет установлен как копия buffer1, а не как указатель на него.

person mcmonkey4eva    schedule 12.07.2013
comment
Спасибо mcmonkey! это было то, что я искал. - person Chemari; 12.07.2013

Просто небольшое дополнение к ответу McMonkey:

Я получаю следующую ошибку: "Вы не можете вызывать SetData для ресурса, пока он активно установлен на GraphicsDevice. Снимите его с устройства перед вызовом SetData." Я решил эту проблему, создав новую текстуру. Не знаю, может ли это быть проблемой производительности, но теперь это работает:

        Color[] texdata = new Color[buffer1.Width * buffer1.Height];
        buffer1.GetData(texdata);
        hellokittyTexture= new Texture2D(GraphicsDevice, buffer1.Width, buffer1.Height);
        hellokittyTexture.SetData(texdata);
person Chemari    schedule 12.07.2013
comment
Если вы собираетесь это сделать, вызовите hellokittyTexture.Dispose(); перед этим, чтобы убедиться, что он будет удален из памяти. - person mcmonkey4eva; 13.07.2013