Reputation: 55
I am using OpenGL to render a static picture in WPF, on a .NET Core 3.1 platform. The context is initially displayed in a hidden GLFW window. Then I am using glReadPixels
to read the context and display it on an Image control on the UI, using the code shown below. The code works fine when not using threading. However, when calling the rendering code through a different thread the image is not displayed. As an intermediate check, I created the using (FileStream...
code, which reads the WriteableBitmap and saves it locally and appears to be working correctly; this means that the WriteableBitmap is created correctly. So, I guess the problem is how to transmit a WriteableBitmap to the Image control, both of which were created on different threads. Dispatcher.BeginInvoke
does not work for some strange reason.
byte[] imageBuffer = new byte[imageWidth * imageHeight * 4];
glReadPixels(0, 0, imageWidth, imageHeight, GL_BGRA, GL_UNSIGNED_BYTE, imageBuffer);
imageBuffer = ImageReverse(imageBuffer, imageWidth);
PixelFormat pixelFormat = PixelFormats.Pbgra32;
int rawStride = (imageWidth * pixelFormat.BitsPerPixel) / 8;
BitmapSource bitmapSource = BitmapSource.Create(imageWidth, imageHeight, 96, 96, pixelFormat, null, imageBuffer, rawStride);
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapSource);
//This is a check whether the writeableBitmap has been created correctly
using (FileStream fileStream = new FileStream(@"C:\Temp\Image1.bmp", FileMode.Create))
{
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(writeableBitmap));
encoder.Save(fileStream);
}
Action action = new Action(() => {
_imgSoilProfile.Source = writeableBitmap;
});
_imgSoilProfile.Dispatcher.BeginInvoke(action, DispatcherPriority.Send);
Upvotes: 1
Views: 228
Reputation: 169200
Try to call w.Freeze()
on the background thread before you set the Source
of the Image
:
using (FileStream fileStream = new FileStream(@"C:\Temp\Image1.bmp", FileMode.Create))
{
...
}
w.Freeze();
Action action = new Action(() => {
_imgSoilProfile.Source = writeableBitmap;
});
From the docs:
A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.
Upvotes: 1