简体   繁体   中英

WriteableBitmap Backbuffer not applying to image

I'm drawing on the backuffer of a writeablebitmap, and the applying it to the image but the image is not updating for some reason.

I've checked in the memory and the backbuffer values are changed, but setting the source of the image to the writeablebitmap doesn't change anything. The screen stays black.

Here is my program:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace RayTracer
{
  class Main : Application
  {

    Window mainWindow;
    protected override void OnStartup(StartupEventArgs e)
    {
      base.OnStartup(e);
      CreateAndShowMainWindow();
    }

    public void CreateAndShowMainWindow()
    {
      mainWindow = new Window();
      mainWindow.Title = "Writeable Bitmap";
      mainWindow.Height = 480;
      mainWindow.Width = 640;
      mainWindow.ResizeMode = ResizeMode.NoResize;

      mImage = new Image();
      mWriteableBitmap = new WriteableBitmap(640, 480, 96, 96, PixelFormats.Rgb24, null);

      mImage.Stretch = Stretch.None;
      mImage.Margin = new Thickness(0);

      mBytesPerPixel = (mWriteableBitmap.Format.BitsPerPixel + 7) / 8;
      mStride = mWriteableBitmap.PixelWidth * mBytesPerPixel;

      StackPanel myStackPanel = new StackPanel();
      myStackPanel.Orientation = Orientation.Vertical;
      myStackPanel.Height = 480;
      myStackPanel.VerticalAlignment = VerticalAlignment.Top;
      myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;

      myStackPanel.Children.Add(mImage);

      mainWindow.Content = myStackPanel;
      mainWindow.Show();

      DispatcherTimer dispatcherTimer = new DispatcherTimer();
      dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
      dispatcherTimer.IsEnabled = true;
      dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
      dispatcherTimer.Start();
    }

    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
      for (int i = 0; i < 480; i++)
      {
        for (int j = 0; j < 640; j++)
        {
          setPixel(j, i, Color.FromRgb(255, 255, 255));
        }
      }
      mImage.Source = mWriteableBitmap; // image should be white but stays black
    }

    private Image mImage = null;
    private WriteableBitmap mWriteableBitmap = null;

    private int mBytesPerPixel = 0;
    private int mStride = 0;


    void setPixel(int x, int y, Color c)
    {
      int posX = x * mBytesPerPixel;
      int posY = y * mStride;
      unsafe
      {
        byte* backBuffer = (byte*)mWriteableBitmap.BackBuffer;
        backBuffer[posY + posX] = c.R;
        backBuffer[posY + posX + 1] = c.G;
        backBuffer[posY + posX + 2] = c.B;
      }
    }

    void clearScreen()
    {
      int totalBytes = mStride * 480;

      unsafe
      {
        byte* backBuffer = (byte*)mWriteableBitmap.BackBuffer;
        for (int i = 0; i < totalBytes; i++)
        {
          backBuffer[i] = 255;
        }
      }
    }
  }


  internal static class EntryClass
  {
    [System.STAThread()]
    private static void Main()
    {
      Main app = new Main();
      app.Run();
    }
  }
}

From the Remarks on the BackBuffer MSDN page:

Update the back buffer only between calls to the Lock and Unlock methods. If you do not follow the Lock/Unlock workflow described in the WriteableBitmap class remarks, undefined behaviors, such as tearing, can occur.

So your Tick handler should look like this:

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    mWriteableBitmap.Lock();

    for (int i = 0; i < 480; i++)
    {
        for (int j = 0; j < 640; j++)
        {
            setPixel(j, i, Color.FromRgb(255, 255, 255));
        }
    }

    mWriteableBitmap.AddDirtyRect(new Int32Rect(0, 0,
        mWriteableBitmap.PixelWidth, mWriteableBitmap.PixelHeight));
    mWriteableBitmap.Unlock();

    mImage.Source = mWriteableBitmap; // image is white now
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM