简体   繁体   English

WriteableBitmap Backbuffer不适用于图像

[英]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. 我正在使用writeablebitmap的backuffer,并将其应用于图像,但图像由于某种原因没有更新。

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. 我已经检查了内存并且后备缓冲区值已更改,但将图像源设置为writeablebitmap不会改变任何内容。 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: BackBuffer MSDN页面上的备注:

Update the back buffer only between calls to the Lock and Unlock methods. 仅在调用Lock和Unlock方法之间更新后台缓冲区。 If you do not follow the Lock/Unlock workflow described in the WriteableBitmap class remarks, undefined behaviors, such as tearing, can occur. 如果您不遵循WriteableBitmap类备注中描述的锁定/解锁工作流程,则可能会发生未定义的行为,例如撕裂。

So your Tick handler should look like this: 所以你的Tick处理程序应如下所示:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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