/// <summary> /// This creates and passes an array to webgl for rendering to the canvas using "2D" webgl interface /// /// There are two possibilities for showing our result: /// /// First is the "direct" draw approach where we pass a color map and create an ImageData object /// in JavaScript, copying each pixels color to the image data object. /// /// Second is we generate a compressed PNG image in memory and tell the webgl context /// to download the compressed PNG image as a file like any other web page process. /// /// While not implemented this approach would reduce the server bandwidth consumed /// per render by 80% or more as the resulting color map is large when uncompressed. /// </summary> /// <param name="basicCanvas"></param> /// <param name="data"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="iterations"></param> /// <param name="color"></param> /// <returns></returns> public static async Task Draw(BasicCanvas basicCanvas, int[] data, int width, int height, int iterations, Color color) { byte[] result = new byte[width * height * 4]; for (int i = 0; i < width * height; i++) { Color fillColor = color; if (data[i] >= iterations) { fillColor = color; } else { int red = data[i] * 30 % 256; int green = data[i] * 20 % 256; int blue = data[i] * 50 % 256; fillColor = Color.FromArgb(255, red, green, blue); } result[i * 4] = fillColor.R; result[i * 4 + 1] = fillColor.G; result[i * 4 + 2] = fillColor.B; result[i * 4 + 3] = fillColor.A; } await basicCanvas.CreateImageDataCopyByteArray("Mandelbrot", width, height, result); await basicCanvas.PutImageData("Mandelbrot", 0, 0); }
private async void CanvasInitComplete(BasicCanvas basicCanvas) { // we could start the rendering process here rather than having a button click to start rendering. DisabledButtons = false; GetAvailableDevices(); displayPort[0] = Canvas2D.Width; displayPort[1] = Canvas2D.Height; areaView[0] = -2.0f; areaView[1] = 1.0f; areaView[2] = -1.0f; areaView[3] = 1.0f; maxIterations = 1000; int[] data = Crunch(DeviceName); await MandelbrotExtensions.Draw(Canvas2D, data, displayPort[0], displayPort[1], maxIterations, Color.Blue); StateHasChanged(); }
private async void CanvasInitComplete(BasicCanvas basicCanvas) { DeviceName = MandelbrotInstance.AcceleratorName(); displayPort[0] = Canvas2D.Width; displayPort[1] = Canvas2D.Height; areaView[0] = -2.0f; areaView[1] = 1.0f; areaView[2] = -1.0f; areaView[3] = 1.0f; maxIterations = 1000; if (_disposing || !MandelbrotInstance.IsActive) { return; } RestartWatch(); MandelbrotInstance.SetDisplay(Canvas2D.Width, Canvas2D.Height); ExecutionsDetails1 = ElapsedTime($"IL Compile - {DeviceName}"); if (_disposing || !MandelbrotInstance.IsActive) { return; } RestartWatch(); int[] data = await MandelbrotInstance.CalculateMandelbrot(areaView[0], areaView[1], areaView[2], areaView[3]); // ILGPU-CPU-Mode ExecutionsDetails2 = ElapsedTime($"IL Run - {DeviceName}"); if (data == null || _disposing) { return; } await MandelbrotExtensions.Draw(Canvas2D, data, displayPort[0], displayPort[1], maxIterations, Color.Blue); DisabledButtons = false; StateHasChanged(); // note StateHasChanged will force an update of controls on our razor page. }