Texture Dynamic

A forum dedicated to WPF version of LightningChart Ultimate.

Moderator: Arction_LasseP

juergen
Posts: 27
Joined: Tue Feb 04, 2014 8:11 am

Texture Dynamic

Post by juergen » Fri Nov 25, 2016 7:00 pm

Hi,
I'm working on a new version of our software for data visualization. In one mode is a CCD camera the source for images.
I want to display the images as fast as possible. I saw some Direct3D examples where images coming from a web-cam were displayed in realtime using a dynamic TextureBuffer.
For normal sized images it's not a problem, I got a solution in the past and it worked. (http://forum.arction.com/viewtopic.php? ... xture#p695)
Now many customers buy 5MP cameras for microscopy solutions. For this it's too slow (sometimes 1-3 frames/second).
So my question:
Is it possible or maybe possible to add a function to use a TextureBuffer directly which I can update by code?
I think that would be the fastest solution for images and also interesting for others.

Thanks and best regards,
Jürgen

User avatar
ArctionPasi
Posts: 1365
Joined: Tue Mar 26, 2013 10:57 pm
Location: Finland

Re: Texture Dynamic

Post by ArctionPasi » Sat Nov 26, 2016 12:27 pm

Hi Jürgen,

Currently we have almost direct approach available: Using IntensityGridSeries with PixelRendering = true, and using SetColorsData + InvalidateColorsOnly approach

I'm creating a image data on the fly here. Using 2500 x 2000 resolution (5 MP), it runs approx 20 FPS with NVidia GTX 960.

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading.Tasks;
using System.Windows.Threading; 


using Arction.Wpf.Charting;
using Arction.Wpf.Charting.Views;
using Arction.Wpf.Charting.Views.ViewXY;
using Arction.Wpf.Charting.SeriesXY;
using Arction.Wpf.Charting.Axes; 

namespace WpfApplicationFastVideoUpdaterIntensitySeries
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        LightningChartUltimate _chart;
        
        System.Threading.CancellationTokenSource _cancelImageUpdater = new System.Threading.CancellationTokenSource();
        
        int _round = 0;
        int[][] _pixelData;
        const int ImageWidth = 2500;
        const int ImageHeight = 2000; 


        public MainWindow()
        {
            InitializeComponent();

            CreateChart();

            Task taskImageUpdater = new Task(() => { UpdateNextImageLoop(); }, _cancelImageUpdater.Token);
            taskImageUpdater.Start();
        }


        void CreateChart()
        {
            _chart = new LightningChartUltimate();
            gridMain.Children.Add(_chart);

            _chart.BeginUpdate();
            
            ViewXY v = _chart.ViewXY;

            IntensityGridSeries grid = new IntensityGridSeries(v, v.XAxes[0], v.YAxes[0]);
            grid.PixelRendering = true;
            grid.SetRangesXY(0, ImageWidth, 0, ImageHeight);
            grid.Fill = IntensityFillStyle.FromSurfacePoints;

            CreatePixelData();

            grid.SetColorsData(_pixelData, IntensityGridValuesDataOrder.RowsColumns); 
            v.IntensityGridSeries.Add(grid);

            v.XAxes[0].ValueType = AxisValueType.Number;
            v.XAxes[0].SetRange(0, ImageWidth);
            v.YAxes[0].SetRange(0, ImageHeight);
            
            v.LegendBox.Visible = false;

            _chart.EndUpdate(); 
        }


        void UpdateNextImageLoop()
        {
            while (!_cancelImageUpdater.IsCancellationRequested)
            {
                Dispatcher.Invoke((Action)delegate { UpdateNextImage(); });

                System.Threading.Thread.Sleep(1);

            }
        }

        void UpdateNextImage()
        {
            _chart.BeginUpdate();

            //Update image data 
            CreatePixelData();
            
            //Set it to series 
            _chart.ViewXY.IntensityGridSeries[0].InvalidateColorsOnly();

            
            //Update chart title
            _chart.Title.Text = (_round++).ToString("0");

            _chart.EndUpdate();
        }

        void CreatePixelData()
        {
            if (_pixelData == null)
            {
                _pixelData = new int[ImageHeight][];
            }
            
            Parallel.For(0, ImageHeight, (row) =>
            {
                if(_pixelData[row] == null)
                    _pixelData[row] = new int[ImageWidth];

                byte A, R, G, B; 
                for (int col = 0; col < ImageWidth; col++)
                {
                    
                    B = (byte)(col % 255);
                    G = (byte)(row % 255);
                    R = (byte)(_round * 4 % 255);
                    A = 255;

                    _pixelData[row][col] = (int)(A << 24 | R << 16 | G << 8 | B);
                }
            });
        } 
       

    }


}
How does this fullfill your requirements?

Making it yet faster... might be difficult and require excessive changes in our API.
LightningChart Support Team, PT