Hallo,
ich möchte gern mein Programm-Code vorstellen zum sehr schnellen Zeichen eines Grid in einem eigenen Control, für Koordinaten-Systeme oder ähnliches.
Verbesserungen sind immer gewünscht ;D
Spoiler anzeigen
ich möchte gern mein Programm-Code vorstellen zum sehr schnellen Zeichen eines Grid in einem eigenen Control, für Koordinaten-Systeme oder ähnliches.
Verbesserungen sind immer gewünscht ;D
C#-Quellcode
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
- using System.Runtime.CompilerServices;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- //public unsafe class GridBlock : Control { //old
- public unsafe class GridBlock : Panel {
- private Graphics _graphics;
- //private int _halfWidth; //Vertikale mitte //old
- //private int _halfHeight; //horizontale mitte //old
- private int _offsetX; //verschiebung der Maus vom _mouseDownPosition aus in x-Achse
- private int _offsetY; //verschiebung der Maus vom _mouseDownPosition aus in Y-Achse
- private bool _leftMouseButtonHold; //linke Maustaste zum verschieben des Grid
- private Point _mouseDownPosition; //allgemeine klick Position der Maustasten
- private Point _mouseLeftDownPosition; //click position der linken Maustaste
- #region LoopSetting
- private ParallelOptions _parallelOptions;
- #endregion
- #region Grid
- ///Settings
- #region Settings
- private int _gridIndex = 0; //Index vom zu zeichnenden Bitmap
- private Bitmap[] _grid; //Bitmaps auf den gezeichnet wird
- private int*[] _gridPtrs; //Pointer zu den Bitmap-Array
- private int _gridPixelCount; //Anzahl der gesamt Pixel vom Bitmap
- //private Rectangle _gridRectangle; //
- private Color _gridColor; //Farbe der Grid-Linen
- private int _gridIntColor; //
- private Color _gridBackground; //Hintergrund Farbe es Grid
- private int _gridIntBackground; //
- private Pen _gridPen;
- private int _gridStroke; //Breite der Grid-Linien
- private int _gridWidth; //Breite eines Kästchens im Grid
- private int _gridHeight; //Höheeines Kästchens im Grid
- private bool _gridShow; //Sollte logisch sein vom Namen her
- private int _gridOffsetX; //verschiebung des Grid in x-achse
- private int _gridOffsetY; //verschiebung des Grid in y-achse
- #endregion
- ///Properties
- #region Properties
- /// <summary>
- /// Grid-Line color
- /// </summary>
- public Color GridColor {
- get => _gridColor;
- set {
- if (_gridColor != value) {
- _gridColor = value;
- _gridIntColor = value.ToArgb();
- UpdateGridPen();
- UpdateGrid();
- }
- }
- }
- /// <summary>
- /// Grid background color
- /// </summary>
- public Color GridBackground {
- get => _gridBackground;
- set {
- if (_gridBackground != value) {
- _gridBackground = value;
- _gridIntBackground = value.ToArgb();
- UpdateGrid();
- }
- }
- }
- /// <summary>
- /// Grid-Line stroke
- /// </summary>
- public int GridStroke {
- get => _gridStroke;
- set {
- if (_gridStroke != value) {
- _gridStroke = value;
- UpdateGridPen();
- UpdateGrid();
- }
- }
- }
- /// <summary>
- /// Grid-Rectangle width
- /// </summary>
- public int GridWidth {
- get => _gridWidth;
- set {
- if (_gridWidth != value) {
- _gridWidth = value;
- UpdateGrid();
- }
- }
- }
- /// <summary>
- /// Grid-Rectangle height
- /// </summary>
- public int GridHeight {
- get => _gridHeight;
- set {
- if (_gridHeight != value) {
- _gridHeight = value;
- UpdateGrid();
- }
- }
- }
- /// <summary>
- /// True, the grid-lines are shown. False, the grid-lines aren't shown
- /// </summary>
- public bool GridShow {
- get => _gridShow;
- set {
- if (_gridShow != value) {
- _gridShow = value;
- UpdateGrid();
- }
- }
- }
- #endregion
- ///Methoden
- #region Methoden zu den Properties
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void UpdateGridPen() {
- _gridPen = new Pen(_gridColor, _gridStroke);
- }
- /// <summary>
- /// redraw the invisibil Bitmap and send them do show
- /// </summary>
- private unsafe void UpdateGrid() {
- int bufferIndex = (_gridIndex + 1) % 2;
- if (_grid[bufferIndex] != null) {
- int* vptr = _gridPtrs[bufferIndex];
- //Parallel.For für maximale zeichen geschwindigkeit (bei mir waren es ~1.7e6 Pixel/ms und das entsprichte bei mir halbe CPU geschwindigkeit)
- //3,4 GHZ
- Parallel.For(0, _gridPixelCount, _parallelOptions, pos => {
- int x = pos % Width;
- int y = pos / Width;
- ///n - _gridOffsetn := verschiebung determinieren
- *(vptr + pos) = ((x - _gridOffsetX) % _gridWidth == 0 || (y - _gridOffsetY) % _gridHeight == 0)
- ? _gridIntColor
- : _gridIntBackground;
- });
- Interlocked.Exchange(ref _gridIndex, (_gridIndex + 1) % 2);
- Invalidate();
- }
- }
- #endregion
- #endregion
- public GridBlock() {
- ControlStyles styles = ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint;
- SetStyle(styles, true);
- _parallelOptions = new ParallelOptions() {
- MaxDegreeOfParallelism = Environment.ProcessorCount //zum zeichnen genutze Prozessoren
- };
- _grid = new Bitmap[2]; //Warum zwei bitmaps? wärend das eine gezeichnet wird, wird das andere dargestellt
- _gridPtrs = new int*[2]; //zwei pointer jeweils auf die Bitmaps
- _gridBackground = Color.FromArgb(64, 64, 64);
- _gridColor = Color.FromArgb(60, 60, 60);
- _gridIntBackground = _gridBackground.ToArgb();
- _gridIntColor = _gridColor.ToArgb();
- _gridHeight = 30;
- _gridWidth = 30;
- _gridStroke = 1;
- _gridShow = true;
- _gridPen = new Pen(_gridColor, _gridStroke);
- _offsetX = 0; //Bewegung des Grids
- _offsetY = 0;
- }
- #region Events
- protected override void OnPaint(PaintEventArgs e) {
- base.OnPaint(e);
- if (_graphics != e.Graphics) {
- _graphics = e.Graphics;
- _graphics.CompositingQuality = CompositingQuality.HighQuality;
- _graphics.SmoothingMode = SmoothingMode.HighQuality;
- _graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- _graphics.InterpolationMode = InterpolationMode.High;
- }
- if (_grid[_gridIndex] != null) {
- _graphics.DrawImage(_grid[_gridIndex], Point.Empty); //Zeichen des BitMaps
- }
- }
- protected override void OnSizeChanged(EventArgs e) {
- base.OnSizeChanged(e);
- if (Width != 0 && Height != 0) {
- //_halfHeight = (int)(Height * 0.5); //old
- //_halfWidth = (int)(Width * 0.5); //old
- // Erstellet neue Bitmaps mit der Größe dieses Controls
- Interlocked.Exchange(ref _grid[0], new Bitmap(Width, Height))?.Dispose();
- Interlocked.Exchange(ref _grid[1], new Bitmap(Width, Height))?.Dispose();
- //create
- //_gridRectangle = new Rectangle(0, 0, Width, Height); //old
- Rectangle gridRect = ClientRectangle;
- _gridPixelCount = Width * Height;
- _gridPtrs[0] = GetBitmapPointer(_grid[0], ref gridRect);
- _gridPtrs[1] = GetBitmapPointer(_grid[1], ref gridRect);
- UpdateGrid();
- } else {
- Interlocked.Exchange(ref _grid[0], null)?.Dispose();
- Interlocked.Exchange(ref _grid[0], null)?.Dispose();
- }
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- //private unsafe int* GetBitmapPointer(Bitmap bmp) { //old
- private unsafe int* GetBitmapPointer(Bitmap bmp, ref Rectangle gridRect) {
- BitmapData bitmapData = bmp.LockBits(gridRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
- IntPtr intPtr = bitmapData.Scan0;
- bmp.UnlockBits(bitmapData);
- return (int*)intPtr.ToPointer();
- }
- protected override void OnMouseDown(MouseEventArgs e) {
- base.OnMouseDown(e);
- _mouseDownPosition = e.Location;
- if (e.Button == MouseButtons.Left) {
- _leftMouseButtonHold = true;
- _mouseLeftDownPosition = _mouseDownPosition;
- }
- }
- protected override void OnMouseUp(MouseEventArgs e) {
- base.OnMouseUp(e);
- _leftMouseButtonHold = !(e.Button == MouseButtons.Left);
- }
- protected override void OnMouseMove(MouseEventArgs e) {
- base.OnMouseMove(e);
- if (_leftMouseButtonHold) {
- _offsetX = e.X - _mouseLeftDownPosition.X;
- _offsetY = e.Y - _mouseLeftDownPosition.Y;
- _gridOffsetX = _offsetX % _gridWidth;
- _gridOffsetY = _offsetY % _gridHeight;
- UpdateGrid();
- }
- }
- #endregion
- }
Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Facebamm“ ()