Example #1
0
        public SoftwareBitmap GetBitmap()
        {
            SoftwareBitmap bitmap = null;

            //Needs to run in UI thread
            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                bitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, (int)dim.width, (int)dim.height);
            }).AsTask().Wait();

            using (BitmapBuffer buffer = bitmap.LockBuffer(BitmapBufferAccessMode.Write))
                using (var reference = buffer.CreateReference())
                {
                    unsafe
                    {
                        ((IMemoryBufferByteAccess)reference).GetBuffer(out var tempByteArray, out uint capacity);
                        // Fill-in the BGRA plane
                        BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);
                        for (int i = 0; i < bufferLayout.Width * bufferLayout.Height; i++)
                        {
                            tempByteArray[bufferLayout.StartIndex + (i * 4)]     = data[(i * cpp) + 2];
                            tempByteArray[bufferLayout.StartIndex + (i * 4) + 1] = data[(i * cpp) + 1];
                            tempByteArray[bufferLayout.StartIndex + (i * 4) + 2] = data[(i * cpp)];
                            if (cpp == 4)
                            {
                                tempByteArray[bufferLayout.StartIndex + (i * 4) + 3] = data[(i * 4) + 3];
                            }
                            else
                            {
                                tempByteArray[bufferLayout.StartIndex + (i * 4) + 3] = 255;
                            }
                        }
                    }
                }
            return(bitmap);
        }
        /// <summary>
        /// Draws a polyline anti-aliased. Add the first point also at the end of the array if the line should be closed.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="points">The points of the polyline in x and y pairs, therefore the array is interpreted as (x1, y1, x2, y2, ..., xn, yn).</param>
        /// <param name="color">The color for the line.</param>
        public static void dbugDrawPolylineAa(this BitmapBuffer bmp, int[] points, int color)
        {
            using (BitmapContext context = bmp.GetBitmapContext())
            {
                // Use refs for faster access (really important!) speeds up a lot!
                int w  = context.Width;
                int h  = context.Height;
                int x1 = points[0];
                int y1 = points[1];

                for (int i = 2; i < points.Length; i += 2)
                {
                    //int x2 = points[i];
                    //int y2 = points[i + 1];

                    DrawLineAa(context, w, h,
                               x1, y1,
                               x1 += points[i], y1 += points[i + 1], //also update x1,y1
                               color);
                    //x1 = x2;
                    //y1 = y2;
                }
            }
        }
Example #3
0
        public Texture2d LoadTexture(BitmapBuffer bmp)
        {
            Texture2d ret = null;
            int       id  = GenTexture();

            try
            {
                ret = new Texture2d(this, id, bmp.Width, bmp.Height);
                GL.BindTexture(TextureTarget.Texture2D, id);
                //picking a color order that matches doesnt seem to help, any. maybe my driver is accelerating it, or maybe it isnt a big deal. but its something to study on another day
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
                (this as IGL).LoadTextureData(ret, bmp);
            }
            catch
            {
                GL.DeleteTexture(id);
                throw;
            }

            //set default filtering.. its safest to do this always
            ret.SetFilterNearest();

            return(ret);
        }
        public Win32VtkRenderingSurface(IntPtr windowId, bool offscreen)
        {
            _imageBuffer   = new BitmapBuffer(PixelFormat.Format32bppRgb);
            _overlayBuffer = new BitmapBuffer(PixelFormat.Format32bppArgb);
            _finalBuffer   = new BackBuffer();

            _vtkRenderer = new vtkRenderer();
            _vtkRenderer.SetBackground(0.0f, 0.0f, 0.0f);

            _vtkRenderWindow = new vtkWin32OpenGLRenderWindow();
            _vtkRenderWindow.OffScreenRenderingOn();
            _vtkRenderWindow.DoubleBufferOff();
            _vtkRenderWindow.EraseOn();
            _vtkRenderWindow.SwapBuffersOff();
            _vtkRenderWindow.SetDesiredUpdateRate(_dynamicFrameRate);
            _vtkRenderWindow.AddRenderer(_vtkRenderer);

            var delayTime = Math.Min(10000, Math.Max(100, Settings.Default.RendererRefinementDelayMs));

            _dynamicFrameRate            = Math.Min(1000, Math.Max(1, Settings.Default.RendererDynamicFps));
            _dynamicRenderEventPublisher = !offscreen ? new DelayedEventPublisher((s, e) => Render(true, null), delayTime) : null;

            WindowID = windowId;
        }
Example #5
0
        void UpdateRenderFrame()
        {
            // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block
            // NOTE: This is not strictly necessary for the SL version as this is a WPF feature, however we include it here for completeness and to show
            // a similar API to WPF
            //render!
            using (var bmplock = destBmp.Lock())
            {
                BitmapBuffer wb = bmplock.GetWritableBitmap();
                emitter.TargetBitmap   = wb;
                emitter.ParticleBitmap = particleBmp;

                wb.Clear(Colors.Black);


                double elapsed = (DateTime.Now - lastUpdate).TotalSeconds;
                lastUpdate = DateTime.Now;
                emitter.Update(elapsed);
                //			bmp.Blit(new Point(100, 150), circleBmp, new Rect(0, 0, 200, 200), Colors.Red, BlendMode.Additive);
                //			bmp.Blit(new Point(160, 55), circleBmp, new Rect(0, 0, 200, 200), Color.FromArgb(255, 0, 255, 0), BlendMode.Additive);
                //			bmp.Blit(new Point(220, 150), circleBmp, new Rect(0, 0, 200, 200), Colors.Blue, BlendMode.Additive);

                //double timeNow = _stopwatch.ElapsedMilliseconds;
                //double elapsedMilliseconds = timeNow - _lastTime;
                //_lowestFrameTime = Math.Min(_lowestFrameTime, elapsedMilliseconds);
                //// FpsCounter.Text = string.Format("FPS: {0:0.0} / Max: {1:0.0}", 1000.0 / elapsedMilliseconds, 1000.0 / _lowestFrameTime);
                //_lastTime = timeNow;

                //
                bmplock.WriteAndUnlock();
                //

                g.Clear(System.Drawing.Color.White);
                g.DrawImage(destBmp, 0, 0);
            }
        }
Example #6
0
        public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex)
        {
            //TODO - lazy create and cache resolving target in RT
            var target = new d3d9.Texture(dev, tex.IntWidth, tex.IntHeight, 1, d3d9.Usage.None, d3d9.Format.A8R8G8B8, d3d9.Pool.SystemMemory);
            var tw     = tex.Opaque as TextureWrapper;

            dev.GetRenderTargetData(tw.Texture.GetSurfaceLevel(0), target.GetSurfaceLevel(0));
            var dr = target.LockRectangle(0, LockFlags.ReadOnly);

            if (dr.Pitch != tex.IntWidth * 4)
            {
                throw new InvalidOperationException();
            }
            int[] pixels = new int[tex.IntWidth * tex.IntHeight];
            dr.Data.ReadRange(pixels, 0, tex.IntWidth * tex.IntHeight);
            var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight, pixels);

            target.UnlockRectangle(0);
            target.Dispose();             //buffer churn warning

            //TEMPORARY until flipping is sorted out
            bb.YFlip();
            return(bb);
        }
Example #7
0
 public Texture2d LoadTexture(sd.Bitmap bitmap)
 {
     using var bmp = new BitmapBuffer(bitmap, new BitmapLoadOptions());
     return((this as IGL).LoadTexture(bmp));
 }
Example #8
0
        FilterProgram UpdateSourceInternal(JobInfo job)
        {
            if (job.chain_outsize.Width == 0 || job.chain_outsize.Height == 0)
            {
                //this has to be a NOP, because lots of stuff will malfunction on a 0-sized viewport
                return(null);
            }

            //no drawing actually happens. it's important not to begin drawing on a control
            if (!job.simulate && !job.offscreen)
            {
                GLManager.Activate(CR_GraphicsControl);
            }

            IVideoProvider videoProvider = job.videoProvider;
            bool           simulate      = job.simulate;
            Size           chain_outsize = job.chain_outsize;

            //simulate = true;

            int vw = videoProvider.BufferWidth;
            int vh = videoProvider.BufferHeight;

            if (Global.Config.DispFixAspectRatio)
            {
                if (Global.Config.DispManagerAR == Config.EDispManagerAR.System)
                {
                    vw = videoProvider.VirtualWidth;
                    vh = videoProvider.VirtualHeight;
                }
                if (Global.Config.DispManagerAR == Config.EDispManagerAR.Custom)
                {
                    vw = Global.Config.DispCustomUserARWidth;
                    vh = Global.Config.DispCustomUserARHeight;
                }
                if (Global.Config.DispManagerAR == Config.EDispManagerAR.CustomRatio)
                {
                    FixRatio(Global.Config.DispCustomUserARX, Global.Config.DispCustomUserARY, videoProvider.BufferWidth, videoProvider.BufferHeight, out vw, out vh);
                }
            }

            var padding = CalculateCompleteContentPadding(true, false);

            vw += padding.Horizontal;
            vh += padding.Vertical;

            int[] videoBuffer = videoProvider.GetVideoBuffer();

            int  bufferWidth   = videoProvider.BufferWidth;
            int  bufferHeight  = videoProvider.BufferHeight;
            bool isGlTextureId = videoBuffer.Length == 1;

            BitmapBuffer bb           = null;
            Texture2d    videoTexture = null;

            if (!simulate)
            {
                if (isGlTextureId)
                {
                    //FYI: this is a million years from happening on n64, since it's all geriatric non-FBO code
                    //is it workable for saturn?
                    videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight);
                }
                else
                {
                    //wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders)
                    bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer);
                    bb.DiscardAlpha();

                    //now, acquire the data sent from the videoProvider into a texture
                    videoTexture = VideoTextureFrugalizer.Get(bb);

                    //lets not use this. lets define BizwareGL to make clamp by default (TBD: check opengl)
                    //GL.SetTextureWrapMode(videoTexture, true);
                }
            }

            //record the size of what we received, since lua and stuff is gonna want to draw onto it
            currEmuWidth  = bufferWidth;
            currEmuHeight = bufferHeight;

            //build the default filter chain and set it up with services filters will need
            Size chain_insize = new Size(bufferWidth, bufferHeight);

            var filterProgram = BuildDefaultChain(chain_insize, chain_outsize, job.includeOSD);

            filterProgram.GuiRenderer = Renderer;
            filterProgram.GL          = GL;

            //setup the source image filter
            EmuHawk.Filters.SourceImage fInput = filterProgram["input"] as EmuHawk.Filters.SourceImage;
            fInput.Texture = videoTexture;

            //setup the final presentation filter
            EmuHawk.Filters.FinalPresentation fPresent = filterProgram["presentation"] as EmuHawk.Filters.FinalPresentation;
            fPresent.VirtualTextureSize = new Size(vw, vh);
            fPresent.TextureSize        = new Size(bufferWidth, bufferHeight);
            fPresent.BackgroundColor    = videoProvider.BackgroundColor;
            fPresent.GuiRenderer        = Renderer;
            fPresent.Flip = isGlTextureId;
            fPresent.Config_FixAspectRatio  = Global.Config.DispFixAspectRatio;
            fPresent.Config_FixScaleInteger = Global.Config.DispFixScaleInteger;
            fPresent.Padding      = ClientExtraPadding;
            fPresent.AutoPrescale = Global.Config.DispAutoPrescale;

            fPresent.GL = GL;

            filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen);

            if (simulate)
            {
            }
            else
            {
                CurrentFilterProgram = filterProgram;
                UpdateSourceDrawingWork(job);
            }

            //cleanup:
            if (bb != null)
            {
                bb.Dispose();
            }

            return(filterProgram);
        }
Example #9
0
 public BitmapBufferVideoProvider(BitmapBuffer bb)
 {
     this.bb = bb;
 }
        /// <summary>
        /// Tests the led strip graphics.
        /// </summary>
        public static void TestLedStripGraphics()
        {
            BitmapBuffer pixels = null;

            try
            {
                using (var bitmap =
                           new System.Drawing.Bitmap(Path.Combine(Runtime.EntryAssemblyDirectory, "fractal.jpg")))
                {
                    $"Loaded bitmap with format {bitmap.PixelFormat}".Info();
                    pixels = new BitmapBuffer(bitmap);
                    $"Loaded Pixel Data: {pixels.Data.Length} bytes".Info();
                }
            }
            catch (Exception ex)
            {
                $"Error Loading image: {ex.Message}".Error();
            }

            var exitAnimation        = false;
            var useDynamicBrightness = false;
            var frameRenderTimes     = new Queue <int>();
            var frameTimes           = new Queue <int>();

            var thread = new Thread(() =>
            {
                var strip = new LedStripAPA102C(60 * 4, 1, 1000000); // 1 Mhz is sufficient for such a short strip (only 240 LEDs)
                var millisecondsPerFrame = 1000 / 25;
                var lastRenderTime       = DateTime.UtcNow;
                var currentFrameNumber   = 0;

                var currentBrightness = 0.8f;
                var currentRow        = 0;
                var currentDirection  = 1;

                while (!exitAnimation)
                {
                    // Push pixels into the Frame Buffer
                    strip.SetPixels(pixels, 0, currentRow, currentBrightness);

                    // Move the current row slowly at FPS
                    currentRow += currentDirection;
                    if (currentRow >= pixels.ImageHeight)
                    {
                        currentRow       = pixels.ImageHeight - 2;
                        currentDirection = -1;
                    }
                    else if (currentRow <= 0)
                    {
                        currentRow       = 1;
                        currentDirection = 1;
                    }

                    if (useDynamicBrightness)
                    {
                        currentBrightness = 0.05f + (0.80f * (currentRow / (pixels.ImageHeight - 1f)));
                    }

                    // Stats and sleep time
                    var delayMilliseconds = (int)DateTime.UtcNow.Subtract(lastRenderTime).TotalMilliseconds;
                    frameRenderTimes.Enqueue(delayMilliseconds);
                    delayMilliseconds = millisecondsPerFrame - delayMilliseconds;

                    if (delayMilliseconds > 0 && exitAnimation == false)
                    {
                        Thread.Sleep(delayMilliseconds);
                    }
                    else
                    {
                        $"Lagging framerate: {delayMilliseconds} milliseconds".Info();
                    }

                    frameTimes.Enqueue((int)DateTime.UtcNow.Subtract(lastRenderTime).TotalMilliseconds);
                    lastRenderTime = DateTime.UtcNow;

                    // Push the framebuffer to SPI
                    strip.Render();

                    if (currentFrameNumber == int.MaxValue)
                    {
                        currentFrameNumber = 0;
                    }
                    else
                    {
                        currentFrameNumber++;
                    }
                    if (frameRenderTimes.Count >= 2048)
                    {
                        frameRenderTimes.Dequeue();
                    }
                    if (frameTimes.Count >= 20148)
                    {
                        frameTimes.Dequeue();
                    }
                }

                strip.ClearPixels();
                strip.Render();

                var avg = frameRenderTimes.Average();
                $"Frames: {currentFrameNumber + 1}, FPS: {Math.Round(1000f / frameTimes.Average(), 3)}, Strip Render: {Math.Round(avg, 3)} ms, Max FPS: {Math.Round(1000 / avg, 3)}"
                .Info();
                strip.Render();
            });

            thread.Start();
            Console.Write("Press any key to stop and clear");
            Console.ReadKey(true);
            Console.WriteLine();
            exitAnimation = true;
        }
Example #11
0
        public static double browser_draw(double browserIdDouble, double x, double y)
        {
            int browserId = (int)browserIdDouble; // this is so stupid, GML...

            if (browserId < 0 || browserId >= browsers.Count || browsers[browserId] == null)
            {
                return(0);
            }

            //Debug.WriteLine("Draw");

            Browser browserObj = browsers[browserId];

            if (browserObj.texture == null || browserObj.textureSize.Width != browserObj.browser.Size.Width || browserObj.textureSize.Height != browserObj.browser.Size.Height)
            {
                Debug.WriteLine("Recreate texture " + browserObj.browser.Size.Width + "x" + browserObj.browser.Size.Height);
                browserObj.textureSize = new Size(browserObj.browser.Size.Width, browserObj.browser.Size.Height);
                if (browserObj.texture != null)
                {
                    browserObj.texture.Dispose();
                }
                browserObj.texture = new Texture(device, browserObj.textureSize.Width, browserObj.textureSize.Height, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
            }


            BitmapBuffer buffer = (browserObj.browser.RenderHandler as DefaultRenderHandler).BitmapBuffer;

            lock (buffer.BitmapLock)
            {
                if (buffer.Width == 0 || buffer.Height == 0 || buffer.Buffer.Length == 0)
                {
                    Debug.WriteLine("No buffer!!!");
                    return(0);
                }
                if (browserObj.textureSize.Width != buffer.Width || browserObj.textureSize.Height != buffer.Height)
                {
                    Debug.WriteLine("Invalid buffer size!!!");
                    return(0);
                }
                var rect = browserObj.texture.LockRectangle(0, LockFlags.None);
                unsafe
                {
                    fixed(byte *buf = buffer.Buffer)
                    {
                        for (int yy = 0; yy < buffer.Height; yy++)
                        {
                            Buffer.MemoryCopy(buf + yy * buffer.Width * 4, (byte *)rect.DataPointer.ToPointer() + yy * rect.Pitch, (uint)(buffer.Width * 4), (uint)(buffer.Width * 4));
                        }
                    }
                }
                browserObj.texture.UnlockRectangle(0);
            }

            if (browsers[browserId].sprite == null)
            {
                browsers[browserId].sprite = new Sprite(device);
            }
            browsers[browserId].sprite.Begin();
            browsers[browserId].sprite.Draw(browsers[browserId].texture, new RawColorBGRA(255, 255, 255, 255), null, null, new RawVector3((float)x, (float)y, 0.0f));
            browsers[browserId].sprite.End();

            return(1);
        }
Example #12
0
        /// <summary>
        /// Sets a number of pixels from loaded pixel data directly into the frame buffer
        /// This is the fastest method to set a number of pixels.
        /// Call the Render Method to apply!
        /// </summary>
        /// <param name="pixels">The pixel data of a previously loaded bitmap.</param>
        /// <param name="sourceOffsetX">The x offset in the bitmap to start copying pixels from</param>
        /// <param name="sourceOffsetY">The row index (y) from which to take the pixel data</param>
        /// <param name="brightness">The brightness from 0.0 to 1.0. The underlying precision is from 0 to 31</param>
        /// <param name="targetOffset">The target offset where to start setting the pixels.</param>
        /// <param name="targetLength">The number of pixels to set. 0 or less means the entire LedCount</param>
        /// <exception cref="ArgumentOutOfRangeException">startX
        /// or
        /// y</exception>
        /// <exception cref="ArgumentNullException">bitmap</exception>
        public void SetPixels(BitmapBuffer pixels, int sourceOffsetX, int sourceOffsetY, float brightness = 1f, int targetOffset = 0, int targetLength = 0)
        {
            var brightnessByte = default(byte);

            { // Parameter validation
                if (pixels == null)
                {
                    throw new ArgumentNullException(nameof(pixels));
                }

                if (sourceOffsetX < 0 || sourceOffsetX > (pixels.ImageWidth - targetLength) - 1)
                {
                    throw new ArgumentOutOfRangeException(nameof(sourceOffsetX));
                }

                if (sourceOffsetY < 0 || sourceOffsetY >= pixels.ImageHeight)
                {
                    throw new ArgumentOutOfRangeException(nameof(sourceOffsetY),
                                                          $"{nameof(sourceOffsetY)} was '{sourceOffsetY}' but it must be between '0' and '{pixels.ImageHeight - 1}'");
                }

                if (targetOffset < 0)
                {
                    targetOffset = 0;
                }
                if (targetOffset > LedCount - 1)
                {
                    throw new ArgumentOutOfRangeException(nameof(targetOffset));
                }

                if (targetLength <= 0)
                {
                    targetLength = LedCount;
                }

                if (targetOffset + targetLength > LedCount)
                {
                    throw new ArgumentOutOfRangeException(nameof(targetLength));
                }

                // Brightness Setting
                if (brightness < 0f)
                {
                    brightness = 0f;
                }
                if (brightness > 1f)
                {
                    brightness = 1f;
                }
                brightnessByte = (byte)(brightness * 31);
                brightnessByte = (byte)(brightnessByte | BrightnessSetMask);
            }

            // Offset settings
            var offsetB = ReverseRgb ? 1 : 3; var offsetG = 2; var offsetR = ReverseRgb ? 3 : 1; var offsetT = 0;

            // Pixel copying
            lock (SyncLock)
            {
                var bmpOffsetBase  = pixels.GetPixelOffset(sourceOffsetX, sourceOffsetY);
                var bmpOffsetLimit = bmpOffsetBase + (targetLength * BitmapBuffer.BytesPerPixel);
                var setCount       = 0;

                var frameBufferOffset = StartFrame.Length + (targetOffset * StartFrame.Length);

                for (var bmpOffset = bmpOffsetBase; bmpOffset < bmpOffsetLimit; bmpOffset += BitmapBuffer.BytesPerPixel)
                {
                    FrameBuffer[frameBufferOffset + offsetT] = brightnessByte;
                    FrameBuffer[frameBufferOffset + offsetR] = pixels.Data[bmpOffset + BitmapBuffer.ROffset]; // R
                    FrameBuffer[frameBufferOffset + offsetG] = pixels.Data[bmpOffset + BitmapBuffer.GOffset]; // G
                    FrameBuffer[frameBufferOffset + offsetB] = pixels.Data[bmpOffset + BitmapBuffer.BOffset]; // B
                    frameBufferOffset += StartFrame.Length;
                    setCount          += 1;

                    if (setCount >= targetLength)
                    {
                        break;
                    }
                }
            }
        }
Example #13
0
        public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
        {
            applyRect = IntersectRectangle(applyBitmap.Size, rect);

            if (applyRect.Height <= 0 || applyRect.Width <= 0)
            {
                return;
            }

            int    blurRadius     = GetFieldValueAsInt(FieldType.BLUR_RADIUS);
            double previewQuality = GetFieldValueAsDouble(FieldType.PREVIEW_QUALITY);

            // do nothing when nothing can be done!
            if (blurRadius < 1)
            {
                return;
            }

            using (BitmapBuffer bbbDest = new BitmapBuffer(applyBitmap, applyRect)) {
                bbbDest.Lock();
                using (BitmapBuffer bbbSrc = new BitmapBuffer(applyBitmap, applyRect)) {
                    bbbSrc.Lock();
                    Random rand = new Random();

                    int    r      = blurRadius;
                    int[]  w      = CreateGaussianBlurRow(r);
                    int    wlen   = w.Length;
                    long[] waSums = new long[wlen];
                    long[] wcSums = new long[wlen];
                    long[] aSums  = new long[wlen];
                    long[] bSums  = new long[wlen];
                    long[] gSums  = new long[wlen];
                    long[] rSums  = new long[wlen];
                    for (int y = 0; y < applyRect.Height; ++y)
                    {
                        long waSum = 0;
                        long wcSum = 0;
                        long aSum  = 0;
                        long bSum  = 0;
                        long gSum  = 0;
                        long rSum  = 0;

                        for (int wx = 0; wx < wlen; ++wx)
                        {
                            int srcX = wx - r;
                            waSums[wx] = 0;
                            wcSums[wx] = 0;
                            aSums[wx]  = 0;
                            bSums[wx]  = 0;
                            gSums[wx]  = 0;
                            rSums[wx]  = 0;

                            if (srcX >= 0 && srcX < bbbDest.Width)
                            {
                                for (int wy = 0; wy < wlen; ++wy)
                                {
                                    int srcY = y + wy - r;

                                    if (srcY >= 0 && srcY < bbbDest.Height)
                                    {
                                        int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY);
                                        int   wp     = w[wy];

                                        waSums[wx] += wp;
                                        wp         *= colors[0] + (colors[0] >> 7);
                                        wcSums[wx] += wp;
                                        wp        >>= 8;

                                        aSums[wx] += wp * colors[0];
                                        bSums[wx] += wp * colors[3];
                                        gSums[wx] += wp * colors[2];
                                        rSums[wx] += wp * colors[1];
                                    }
                                }

                                int wwx = w[wx];
                                waSum += wwx * waSums[wx];
                                wcSum += wwx * wcSums[wx];
                                aSum  += wwx * aSums[wx];
                                bSum  += wwx * bSums[wx];
                                gSum  += wwx * gSums[wx];
                                rSum  += wwx * rSums[wx];
                            }
                        }

                        wcSum >>= 8;

                        if (waSum == 0 || wcSum == 0)
                        {
                            SetColorAt(bbbDest, 0, y, new int[] { 0, 0, 0, 0 });
                        }
                        else
                        {
                            int alpha = (int)(aSum / waSum);
                            int blue  = (int)(bSum / wcSum);
                            int green = (int)(gSum / wcSum);
                            int red   = (int)(rSum / wcSum);

                            SetColorAt(bbbDest, 0, y, new int[] { alpha, red, green, blue });
                        }

                        for (int x = 1; x < applyRect.Width; ++x)
                        {
                            for (int i = 0; i < wlen - 1; ++i)
                            {
                                waSums[i] = waSums[i + 1];
                                wcSums[i] = wcSums[i + 1];
                                aSums[i]  = aSums[i + 1];
                                bSums[i]  = bSums[i + 1];
                                gSums[i]  = gSums[i + 1];
                                rSums[i]  = rSums[i + 1];
                            }

                            waSum = 0;
                            wcSum = 0;
                            aSum  = 0;
                            bSum  = 0;
                            gSum  = 0;
                            rSum  = 0;

                            int wx;
                            for (wx = 0; wx < wlen - 1; ++wx)
                            {
                                long wwx = (long)w[wx];
                                waSum += wwx * waSums[wx];
                                wcSum += wwx * wcSums[wx];
                                aSum  += wwx * aSums[wx];
                                bSum  += wwx * bSums[wx];
                                gSum  += wwx * gSums[wx];
                                rSum  += wwx * rSums[wx];
                            }

                            wx = wlen - 1;

                            waSums[wx] = 0;
                            wcSums[wx] = 0;
                            aSums[wx]  = 0;
                            bSums[wx]  = 0;
                            gSums[wx]  = 0;
                            rSums[wx]  = 0;

                            int srcX = x + wx - r;

                            if (srcX >= 0 && srcX < applyRect.Width)
                            {
                                for (int wy = 0; wy < wlen; ++wy)
                                {
                                    int srcY = y + wy - r;
                                    // only when in EDIT mode, ignore some pixels depending on preview quality
                                    if ((renderMode == RenderMode.EXPORT || rand.NextDouble() < previewQuality) && srcY >= 0 && srcY < applyRect.Height)
                                    {
                                        int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY);
                                        int   wp     = w[wy];

                                        waSums[wx] += wp;
                                        wp         *= colors[0] + (colors[0] >> 7);
                                        wcSums[wx] += wp;
                                        wp        >>= 8;

                                        aSums[wx] += wp * (long)colors[0];
                                        bSums[wx] += wp * (long)colors[3];
                                        gSums[wx] += wp * (long)colors[2];
                                        rSums[wx] += wp * (long)colors[1];
                                    }
                                }

                                int wr = w[wx];
                                waSum += (long)wr * waSums[wx];
                                wcSum += (long)wr * wcSums[wx];
                                aSum  += (long)wr * aSums[wx];
                                bSum  += (long)wr * bSums[wx];
                                gSum  += (long)wr * gSums[wx];
                                rSum  += (long)wr * rSums[wx];
                            }

                            wcSum >>= 8;

                            if (waSum == 0 || wcSum == 0)
                            {
                                SetColorAt(bbbDest, x, y, new int[] { 0, 0, 0, 0 });
                            }
                            else
                            {
                                int alpha = (int)(aSum / waSum);
                                int blue  = (int)(bSum / wcSum);
                                int green = (int)(gSum / wcSum);
                                int red   = (int)(rSum / wcSum);

                                SetColorAt(bbbDest, x, y, new int[] { alpha, red, green, blue });
                            }
                        }
                    }
                }
                bbbDest.DrawTo(graphics, applyRect.Location);
            }
        }
Example #14
0
        /// <summary>
        /// A Fast Bresenham Type Algorithm For Drawing Ellipses http://homepage.smc.edu/kennedy_john/belipse.pdf
        /// Uses a different parameter representation than DrawEllipse().
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="xc">The x-coordinate of the ellipses center.</param>
        /// <param name="yc">The y-coordinate of the ellipses center.</param>
        /// <param name="xr">The radius of the ellipse in x-direction.</param>
        /// <param name="yr">The radius of the ellipse in y-direction.</param>
        /// <param name="color">The color for the line.</param>
        public static unsafe void DrawEllipseCentered(this BitmapBuffer bmp, int xc, int yc, int xr, int yr, int color)
        {
            // Use refs for faster access (really important!) speeds up a lot!
            using (BitmapContext context = bmp.GetBitmapContext())
            {
                int *pixels = context.Pixels._inf32Buffer;

                int w = context.Width;
                int h = context.Height;

                // Avoid endless loop
                if (xr < 1 || yr < 1)
                {
                    return;
                }

                // Init vars
                int uh, lh, uy, ly, lx, rx;
                int x         = xr;
                int y         = 0;
                int xrSqTwo   = (xr * xr) << 1;
                int yrSqTwo   = (yr * yr) << 1;
                int xChg      = yr * yr * (1 - (xr << 1));
                int yChg      = xr * xr;
                int err       = 0;
                int xStopping = yrSqTwo * xr;
                int yStopping = 0;

                // Draw first set of points counter clockwise where tangent line slope > -1.
                while (xStopping >= yStopping)
                {
                    // Draw 4 quadrant points at once
                    uy = yc + y;                  // Upper half
                    ly = yc - y;                  // Lower half
                    if (uy < 0)
                    {
                        uy = 0;                  // Clip
                    }
                    if (uy >= h)
                    {
                        uy = h - 1;               // ...
                    }
                    if (ly < 0)
                    {
                        ly = 0;
                    }
                    if (ly >= h)
                    {
                        ly = h - 1;
                    }
                    uh = uy * w;                  // Upper half
                    lh = ly * w;                  // Lower half

                    rx = xc + x;
                    lx = xc - x;
                    if (rx < 0)
                    {
                        rx = 0;                  // Clip
                    }
                    if (rx >= w)
                    {
                        rx = w - 1;               // ...
                    }
                    if (lx < 0)
                    {
                        lx = 0;
                    }
                    if (lx >= w)
                    {
                        lx = w - 1;
                    }
                    pixels[rx + uh] = color;      // Quadrant I (Actually an octant)
                    pixels[lx + uh] = color;      // Quadrant II
                    pixels[lx + lh] = color;      // Quadrant III
                    pixels[rx + lh] = color;      // Quadrant IV

                    y++;
                    yStopping += xrSqTwo;
                    err       += yChg;
                    yChg      += xrSqTwo;
                    if ((xChg + (err << 1)) > 0)
                    {
                        x--;
                        xStopping -= yrSqTwo;
                        err       += xChg;
                        xChg      += yrSqTwo;
                    }
                }

                // ReInit vars
                x  = 0;
                y  = yr;
                uy = yc + y;                  // Upper half
                ly = yc - y;                  // Lower half
                if (uy < 0)
                {
                    uy = 0;                  // Clip
                }
                if (uy >= h)
                {
                    uy = h - 1;               // ...
                }
                if (ly < 0)
                {
                    ly = 0;
                }
                if (ly >= h)
                {
                    ly = h - 1;
                }
                uh        = uy * w;           // Upper half
                lh        = ly * w;           // Lower half
                xChg      = yr * yr;
                yChg      = xr * xr * (1 - (yr << 1));
                err       = 0;
                xStopping = 0;
                yStopping = xrSqTwo * yr;

                // Draw second set of points clockwise where tangent line slope < -1.
                while (xStopping <= yStopping)
                {
                    // Draw 4 quadrant points at once
                    rx = xc + x;
                    lx = xc - x;
                    if (rx < 0)
                    {
                        rx = 0;                  // Clip
                    }
                    if (rx >= w)
                    {
                        rx = w - 1;               // ...
                    }
                    if (lx < 0)
                    {
                        lx = 0;
                    }
                    if (lx >= w)
                    {
                        lx = w - 1;
                    }
                    pixels[rx + uh] = color;      // Quadrant I (Actually an octant)
                    pixels[lx + uh] = color;      // Quadrant II
                    pixels[lx + lh] = color;      // Quadrant III
                    pixels[rx + lh] = color;      // Quadrant IV

                    x++;
                    xStopping += yrSqTwo;
                    err       += xChg;
                    xChg      += yrSqTwo;
                    if ((yChg + (err << 1)) > 0)
                    {
                        y--;
                        uy = yc + y;                  // Upper half
                        ly = yc - y;                  // Lower half
                        if (uy < 0)
                        {
                            uy = 0;                  // Clip
                        }
                        if (uy >= h)
                        {
                            uy = h - 1;               // ...
                        }
                        if (ly < 0)
                        {
                            ly = 0;
                        }
                        if (ly >= h)
                        {
                            ly = h - 1;
                        }
                        uh         = uy * w;          // Upper half
                        lh         = ly * w;          // Lower half
                        yStopping -= xrSqTwo;
                        err       += yChg;
                        yChg      += xrSqTwo;
                    }
                }
            }
        }
Example #15
0
 /// <summary>
 /// A Fast Bresenham Type Algorithm For Drawing Ellipses http://homepage.smc.edu/kennedy_john/belipse.pdf
 /// Uses a different parameter representation than DrawEllipse().
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="xc">The x-coordinate of the ellipses center.</param>
 /// <param name="yc">The y-coordinate of the ellipses center.</param>
 /// <param name="xr">The radius of the ellipse in x-direction.</param>
 /// <param name="yr">The radius of the ellipse in y-direction.</param>
 /// <param name="color">The color for the line.</param>
 public static void DrawEllipseCentered(this BitmapBuffer bmp, int xc, int yc, int xr, int yr, ColorInt color)
 {
     bmp.DrawEllipseCentered(xc, yc, xr, yr, color.ToPreMultAlphaColor());
 }
Example #16
0
 public void ReleaseSurface(BitmapBuffer surface)
 {
     lock (this) ReleasedSurfaces.Enqueue(surface);
 }
Example #17
0
        static async Task Main()
        {
            Console.WriteLine("Video Capture Test");

            //await ListDevicesAndFormats();
            //Console.ReadLine();

            var mediaFrameReader = await StartVideoCapture().ConfigureAwait(false);

            if (mediaFrameReader != null)
            {
                // Open a Window to display the video feed from video capture device
                _form          = new Form();
                _form.AutoSize = true;
                _form.BackgroundImageLayout = ImageLayout.Center;
                _picBox = new PictureBox
                {
                    Size     = new Size(FRAME_WIDTH, FRAME_HEIGHT),
                    Location = new Point(0, 0),
                    Visible  = true
                };
                _form.Controls.Add(_picBox);

                bool           taskRunning = false;
                SoftwareBitmap backBuffer  = null;

                // Lambda handler for captured frames.
                mediaFrameReader.FrameArrived += async(MediaFrameReader sender, MediaFrameArrivedEventArgs e) =>
                {
                    if (taskRunning)
                    {
                        return;
                    }
                    taskRunning = true;

                    var mediaFrameReference = sender.TryAcquireLatestFrame();
                    var videoMediaFrame     = mediaFrameReference?.VideoMediaFrame;
                    var softwareBitmap      = videoMediaFrame?.SoftwareBitmap;

                    if (softwareBitmap == null && videoMediaFrame != null)
                    {
                        var videoFrame = videoMediaFrame.GetVideoFrame();
                        softwareBitmap = await SoftwareBitmap.CreateCopyFromSurfaceAsync(videoFrame.Direct3DSurface);
                    }

                    if (softwareBitmap != null)
                    {
                        Console.WriteLine($"Software bitmap pixel fmt {softwareBitmap.BitmapPixelFormat}, alpha mode {softwareBitmap.BitmapAlphaMode}.");

                        if (softwareBitmap.BitmapPixelFormat != Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8 ||
                            softwareBitmap.BitmapAlphaMode != Windows.Graphics.Imaging.BitmapAlphaMode.Premultiplied)
                        {
                            softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
                        }

                        int width  = softwareBitmap.PixelWidth;
                        int height = softwareBitmap.PixelHeight;

                        Console.WriteLine($"Software bitmap frame size {width}x{height}.");

                        // Swap the processed frame to _backBuffer and dispose of the unused image.
                        softwareBitmap = Interlocked.Exchange(ref backBuffer, softwareBitmap);
                        softwareBitmap?.Dispose();

                        _form.BeginInvoke(new Action(() =>
                        {
                            if (_picBox.Width != width || _picBox.Height != height)
                            {
                                _picBox.Size = new Size(width, height);
                            }

                            using (BitmapBuffer buffer = backBuffer.LockBuffer(BitmapBufferAccessMode.Read))
                            {
                                using (var reference = buffer.CreateReference())
                                {
                                    unsafe
                                    {
                                        byte *dataInBytes;
                                        uint capacity;
                                        reference.As <IMemoryBufferByteAccess>().GetBuffer(out dataInBytes, out capacity);

                                        Bitmap bmpImage = new Bitmap((int)width, (int)height, (int)(capacity / height), PixelFormat.Format32bppArgb, (IntPtr)dataInBytes);
                                        _picBox.Image   = bmpImage;
                                    }
                                }
                            }
                        }));
                    }
                    else
                    {
                        Console.WriteLine("null");
                    }

                    taskRunning = false;
                };

                Console.WriteLine("Starting media frame reader.");
                _ = Task.Run(async() => await mediaFrameReader.StartAsync()).ConfigureAwait(false);

                Console.WriteLine("Starting Windows Forms message loop.");
                Application.EnableVisualStyles();
                Application.Run(_form);
            }
            else
            {
                Console.WriteLine("Could not acquire a media frame reader.");
            }
        }
        /// <summary>
        /// Event handler for video frames for the local video capture device.
        /// </summary>
        private async void FrameArrivedHandler(MediaFrameReader sender, MediaFrameArrivedEventArgs e)
        {
            if (!_isClosed)
            {
                using (var frame = sender.TryAcquireLatestFrame())
                {
                    if (_isClosed || frame == null)
                    {
                        return;
                    }

                    var vmf        = frame.VideoMediaFrame;
                    var videoFrame = vmf.GetVideoFrame();

                    var sbmp = await SoftwareBitmap.CreateCopyFromSurfaceAsync(videoFrame.Direct3DSurface);

                    if (sbmp == null)
                    {
                        logger.LogWarning("Failed to get bitmap from video frame reader.");
                    }
                    else
                    {
                        if (!_isClosed && OnVideoSourceEncodedSample != null)
                        {
                            lock (_vp8Encoder)
                            {
                                SoftwareBitmap nv12bmp = null;

                                // If the bitmap is not in the required pixel format for the encoder convert it.
                                if (_mediaFrameSource.CurrentFormat.Subtype != VIDEO_DESIRED_PIXEL_FORMAT)
                                {
                                    nv12bmp = SoftwareBitmap.Convert(sbmp, BitmapPixelFormat.Nv12);
                                }

                                byte[]         nv12Buffer = null;
                                SoftwareBitmap inputBmp   = nv12bmp ?? sbmp;

                                using (BitmapBuffer buffer = inputBmp.LockBuffer(BitmapBufferAccessMode.Read))
                                {
                                    using (var reference = buffer.CreateReference())
                                    {
                                        unsafe
                                        {
                                            byte *dataInBytes;
                                            uint  capacity;
                                            ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity);

                                            nv12Buffer = new byte[capacity];
                                            Marshal.Copy((IntPtr)dataInBytes, nv12Buffer, 0, (int)capacity);
                                        }
                                    }
                                }

                                byte[] encodedBuffer = null;

                                encodedBuffer = _vp8Encoder.Encode(nv12Buffer, _forceKeyFrame);

                                if (encodedBuffer != null)
                                {
                                    uint fps           = (_fpsDenominator > 0 && _fpsNumerator > 0) ? _fpsNumerator / _fpsDenominator : DEFAULT_FRAMES_PER_SECOND;
                                    uint durationRtpTS = VIDEO_SAMPLING_RATE / fps;
                                    OnVideoSourceEncodedSample.Invoke(durationRtpTS, encodedBuffer);
                                }

                                if (_forceKeyFrame)
                                {
                                    _forceKeyFrame = false;
                                }

                                nv12bmp?.Dispose();
                            }
                        }

                        sbmp.Dispose();
                        videoFrame.Dispose();
                    }
                }
            }
        }
Example #19
0
 public Texture2d Get(DisplaySurface ds)
 {
     using var bb = new BitmapBuffer(ds.PeekBitmap(), new BitmapLoadOptions());
     return(Get(bb));
 }
Example #20
0
        public unsafe int[] applyModification(ushort[] image, iPoint2D dim, iPoint2D offset, int colorDepth, ref SoftwareBitmap bitmap)
        {
            int[] value = new int[256];
            using (BitmapBuffer buffer = bitmap.LockBuffer(BitmapBufferAccessMode.Write))
            {
                using (var reference = buffer.CreateReference())
                {
                    BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);
                    ((IMemoryBufferByteAccess)reference).GetBuffer(out var temp, out uint capacity);
                    maxValue = (uint)(1 << colorDepth);
                    int shift = colorDepth - 8;
                    if (!cameraWB)
                    {
                        mul = new float[4];
                        //Balance.calculateRGB((int)temperature, out mul[0], out mul[1], out mul[2]);
                        mul[2] = (float)(255 / temperature);
                        mul[0] = (float)(255.0 / tint);
                        mul[1] = 1;
                    }

                    //generate the curve
                    double[] xCurve = new double[5], yCurve = new double[5];
                    //mid point
                    xCurve[2] = maxValue / 2;
                    yCurve[2] = maxValue / 2;
                    //shadow
                    xCurve[0] = 0;
                    yCurve[0] = shadow * (maxValue / (400));
                    //hightlight
                    xCurve[4] = maxValue;
                    yCurve[4] = maxValue - (hightlight * (maxValue / 400));
                    //contrast
                    xCurve[1] = maxValue / 4;
                    yCurve[1] = ((yCurve[0] + yCurve[2]) / 2) - (maxValue / 200);
                    xCurve[3] = maxValue * 3 / 4;
                    yCurve[3] = ((yCurve[2] + yCurve[4]) / 2) + (maxValue / 200);
                    maxValue--;

                    //interpolate with spline
                    //double[] contrastCurve = Balance.contrast_curve(shadow, hightlight, 1 << colorDepth);
                    double[] contrastCurve = Curve.cubicSpline(xCurve, yCurve);

                    //Change the gamma/No more gammaneeded here, the raw should be transformed to neutral gamma before demos
                    //double[] gammaCurve = Balance.gamma_curve(0.45, 4.5, 2, 8192 << 3);

                    //gammacurve from camera
                    //double[] gammaCurve = Balance.gamma_curve(camCurve[0] / 100, camCurve[1] / 10, 2, 8192 << 3);

                    Parallel.For(offset.y, dim.y + offset.y, y =>
                    {
                        int realY   = y * dim.x * 3;
                        int bufferY = y * dim.x * 4 + +bufferLayout.StartIndex;
                        for (int x = offset.x; x < dim.x + offset.x; x++)
                        {
                            int realPix   = realY + (3 * x);
                            int bufferPix = bufferY + (4 * x);
                            //get the RGB value
                            double red = image[realPix],
                            green      = image[realPix + 1],
                            blue       = image[realPix + 2];

                            //convert to linear rgb (not needed, the raw should be in linear already)

                            /*Balance.sRGBToRGB(ref red, maxValue - 1);
                             * Balance.sRGBToRGB(ref green, maxValue - 1);
                             * Balance.sRGBToRGB(ref blue, maxValue - 1);*/

                            //scale according to the white balance
                            red   *= mul[0];
                            green *= mul[1];
                            blue  *= mul[2];
                            //clip
                            Luminance.Clip(ref red, ref green, ref blue, maxValue);
                            double h = 0, s = 0, l = 0;
                            //transform to HSL value
                            Color.rgbToHsl(red, green, blue, maxValue, ref h, ref s, ref l);
                            //change brightness from curve
                            //add saturation
                            l  = contrastCurve[(uint)(l * maxValue)] / maxValue;
                            s *= saturation;
                            s += vibrance;
                            l *= exposure;
                            l += brightness / 100;
                            //change back to RGB
                            Color.hslToRgb(h, s, l, maxValue, ref red, ref green, ref blue);

                            //Luminance.Exposure(ref red, ref green, ref blue, exposure);
                            //Luminance.Brightness(ref red, ref green, ref blue, brightness);
                            //Balance.scaleGamma(ref red, ref green, ref blue, gamma, maxValue);
                            Luminance.Contraste(ref red, ref green, ref blue, maxValue, contrast);

                            //clip
                            Luminance.Clip(ref red, ref green, ref blue, maxValue);

                            temp[bufferPix]     = (byte)((int)blue >> shift);
                            temp[bufferPix + 1] = (byte)((int)green >> shift);
                            temp[bufferPix + 2] = (byte)((int)red >> shift);

                            Interlocked.Increment(ref value[(((int)red >> shift) + ((int)green >> shift) + ((int)blue >> shift)) / 3]);
                            //set transparency to 255 else image will be blank
                            temp[bufferPix + 3] = 255;
                            //change gamma from curve

                            /*
                             * image[i * 3] = (ushort)gammaCurve[(int)red];
                             * image[(i * 3) + 1] = (ushort)gammaCurve[(int)green];
                             * image[(i * 3) + 2] = (ushort)gammaCurve[(int)blue];*/
                        }
                    });
                }
            }
            return(value);
        }
        FilterProgram UpdateSourceInternal(JobInfo job)
        {
            _glManager.Activate(CR_GraphicsControl);

            IVideoProvider videoProvider = job.videoProvider;
            bool           simulate      = job.simulate;
            Size           chain_outsize = job.chain_outsize;

            int vw = videoProvider.BufferWidth;
            int vh = videoProvider.BufferHeight;

            if (Global.Config.DispFixAspectRatio)
            {
                if (Global.Config.DispManagerAR == Config.EDispManagerAR.System)
                {
                    vw = videoProvider.VirtualWidth;
                    vh = videoProvider.VirtualHeight;
                }
                if (Global.Config.DispManagerAR == Config.EDispManagerAR.Custom)
                {
                    vw = Global.Config.DispCustomUserARWidth;
                    vh = Global.Config.DispCustomUserARHeight;
                }
            }

            int[] videoBuffer = videoProvider.GetVideoBuffer();

            int  bufferWidth   = videoProvider.BufferWidth;
            int  bufferHeight  = videoProvider.BufferHeight;
            bool isGlTextureId = videoBuffer.Length == 1;

            //TODO - need to do some work here for GDI+ to repair gl texture ID importing
            BitmapBuffer bb           = null;
            Texture2d    videoTexture = null;

            if (!simulate)
            {
                if (isGlTextureId)
                {
                    videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight);
                }
                else
                {
                    //wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders)
                    bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer);

                    //now, acquire the data sent from the videoProvider into a texture
                    videoTexture = VideoTextureFrugalizer.Get(bb);
                    GL.SetTextureWrapMode(videoTexture, true);
                }

                //TEST (to be removed once we have an actual example of bring in a texture ID from opengl emu core):
                //if (!isGlTextureId)
                //{
                //  videoBuffer = new int[1] { videoTexture.Id.ToInt32() };
                //  goto TESTEROO;
                //}
            }

            //record the size of what we received, since lua and stuff is gonna want to draw onto it
            currEmuWidth  = bufferWidth;
            currEmuHeight = bufferHeight;

            //build the default filter chain and set it up with services filters will need
            Size chain_insize = new Size(bufferWidth, bufferHeight);

            var filterProgram = BuildDefaultChain(chain_insize, chain_outsize, job.includeOSD);

            filterProgram.GuiRenderer = Renderer;
            filterProgram.GL          = GL;

            //setup the source image filter
            BizHawk.Client.EmuHawk.Filters.SourceImage fInput = filterProgram["input"] as BizHawk.Client.EmuHawk.Filters.SourceImage;
            fInput.Texture = videoTexture;

            //setup the final presentation filter
            BizHawk.Client.EmuHawk.Filters.FinalPresentation fPresent = filterProgram["presentation"] as BizHawk.Client.EmuHawk.Filters.FinalPresentation;
            fPresent.VirtualTextureSize = new Size(vw, vh);
            fPresent.TextureSize        = new Size(bufferWidth, bufferHeight);
            fPresent.BackgroundColor    = videoProvider.BackgroundColor;
            fPresent.GuiRenderer        = Renderer;
            fPresent.GL = GL;

            filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen);

            if (simulate)
            {
            }
            else
            {
                CurrentFilterProgram = filterProgram;
                UpdateSourceDrawingWork(job);
            }

            //cleanup:
            if (bb != null)
            {
                bb.Dispose();
            }

            return(filterProgram);
        }
Example #22
0
        public void LoadTextureData(Texture2d tex, BitmapBuffer bmp)
        {
            var tw = tex.Opaque as GDIPTextureWrapper;

            bmp.ToSysdrawingBitmap(tw.SDBitmap);
        }
Example #23
0
        private void btnExport_Click(object sender, EventArgs e)
        {
            if (mFrameInfos.Count == 0)
            {
                return;
            }

            int width, height;

            using (var bmp = new Bitmap(mFrameInfos[0].pngPath))
            {
                width  = bmp.Width;
                height = bmp.Height;
            }

            var sfd = new SaveFileDialog
            {
                FileName = Path.ChangeExtension(mSynclessConfigFile, ".avi")
            };

            sfd.InitialDirectory = Path.GetDirectoryName(sfd.FileName);
            if (sfd.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            using (var avw = new AviWriter())
            {
                avw.SetAudioParameters(44100, 2, 16);          // hacky
                avw.SetMovieParameters(60, 1);                 // hacky
                avw.SetVideoParameters(width, height);
                var token = avw.AcquireVideoCodecToken(this);
                avw.SetVideoCodecToken(token);
                avw.OpenFile(sfd.FileName);
                foreach (var fi in mFrameInfos)
                {
                    using (var bb = new BitmapBuffer(fi.pngPath, new BitmapLoadOptions()))
                    {
                        var bbvp = new BitmapBufferVideoProvider(bb);
                        avw.AddFrame(bbvp);
                    }

                    // offset = 44 dec
                    var wavBytes = File.ReadAllBytes(fi.wavPath);
                    var ms       = new MemoryStream(wavBytes)
                    {
                        Position = 44
                    };
                    var br         = new BinaryReader(ms);
                    var sampledata = new List <short>();
                    while (br.BaseStream.Position != br.BaseStream.Length)
                    {
                        sampledata.Add(br.ReadInt16());
                    }

                    avw.AddSamples(sampledata.ToArray());
                }

                avw.CloseFile();
            }
        }
Example #24
0
        private void DrawFillDemo(BitmapBuffer writeableBmp)
        {
            // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block
            using (writeableBmp.GetBitmapContext())
            {
                // Init some size vars
                int w  = writeableBmp.PixelWidth - 2;
                int h  = writeableBmp.PixelHeight - 2;
                int w2 = w >> 1;
                int h2 = h >> 1;
                int w4 = w2 >> 1;
                int h4 = h2 >> 1;
                int w8 = w4 >> 1;
                int h8 = h4 >> 1;

                // Clear
                writeableBmp.Clear();

                // Add circles
                const float startTimeFixed  = 1;
                const float endTimeFixed    = startTimeFixed + timeStep;
                const float startTimeRandom = 3;
                const float endTimeCurve    = 9.7f;
                const int   intervalRandom  = 2;
                const int   maxCircles      = 30;

                // Spread fixed position and color circles
                if (time > startTimeFixed && time < endTimeFixed)
                {
                    unchecked
                    {
                        circles.Add(new Circle {
                            X = w8, Y = h8, Radius = 10f, Velocity = 1, Color = (int)0xFFC88717
                        });
                        circles.Add(new Circle
                        {
                            X = w8, Y = h - h8, Radius = 10f, Velocity = 1, Color = (int)0xFFFB522B
                        });
                        circles.Add(new Circle
                        {
                            X = w - w8, Y = h8, Radius = 10f, Velocity = 1, Color = (int)0xFFDB6126
                        });
                        circles.Add(new Circle
                        {
                            X = w - w8, Y = h - h8, Radius = 10f, Velocity = 1, Color = (int)0xFFFFCE25
                        });
                    }
                }

                // Spread random position and color circles
                if (time > startTimeRandom && (int)time % intervalRandom == 0)
                {
                    unchecked
                    {
                        circles.Add(new Circle
                        {
                            X        = rand.Next(w),
                            Y        = rand.Next(h),
                            Radius   = 1f,
                            Velocity = rand.Next(1, 5),
                            Color    = rand.Next((int)0xFFFF0000, (int)0xFFFFFFFF),
                        });
                    }
                }

                // Render and update circles
                foreach (var circle in circles)
                {
                    var r = (int)circle.Radius;
                    writeableBmp.FillEllipseCentered(circle.X, circle.Y, r, r, circle.Color);
                    circle.Update();
                }

                if (circles.Count > maxCircles)
                {
                    circles.RemoveAt(0);
                }

                // Fill closed Cardinal Spline curve
                if (time < endTimeCurve)
                {
                    var p = new int[]
                    {
                        w4, h2,
                        w2, h2 + h4,
                        w2 + w4, h2,
                        w2, h4,
                    };
                    writeableBmp.FillCurveClosed(p, (float)Math.Sin(time) * 7, Colors.Black);
                }

                // Update time
                time += timeStep;

                // Invalidates on exit of Using block
            }
        }
Example #25
0
 /// <summary>
 /// Draws a polyline. Add the first point also at the end of the array if the line should be closed.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="points">The points of the polyline in x and y pairs, therefore the array is interpreted as (x1, y1, x2, y2, ..., xn, yn).</param>
 /// <param name="color">The color for the line.</param>
 public static void dbugDrawPolylineAa(this BitmapBuffer bmp, int[] points, ColorInt color)
 {
     bmp.dbugDrawPolylineAa(points, color.ToPreMultAlphaColor());
 }
Example #26
0
        /// <summary>
        /// Draws the different types of shapes.
        /// </summary>
        private void DrawStaticShapes(BitmapBuffer writeableBmp)
        {
            // HideShapeCountText();

            // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block
            using (writeableBmp.GetBitmapContext())
            {
                // Init some size vars
                int w   = writeableBmp.PixelWidth;
                int h   = writeableBmp.PixelHeight;
                int w3  = w / 3;
                int h3  = h / 3;
                int w6  = w3 >> 1;
                int h6  = h3 >> 1;
                int w12 = w6 >> 1;
                int h12 = h6 >> 1;

                // Clear
                writeableBmp.Clear();

                // Fill closed concave polygon
                var p = new int[]
                {
                    w12 >> 1, h12,
                    w6, h3 - (h12 >> 1),
                    w3 - (w12 >> 1), h12,
                    w6 + w12, h12,
                    w6, h6 + h12,
                    w12, h12,
                    w12 >> 1, h12,
                };
                writeableBmp.FillPolygonsEvenOdd(new[] { p }, GetRandomColor());

                // Fill closed convex polygon
                p = new int[]
                {
                    w3 + w6, h12 >> 1,
                    w3 + w6 + w12, h12,
                    w3 + w6 + w12, h6 + h12,
                    w3 + w6, h6 + h12 + (h12 >> 1),
                    w3 + w12, h6 + h12,
                    w3 + w12, h12,
                    w3 + w6, h12 >> 1,
                };
                writeableBmp.FillPolygon(p, GetRandomColor());

                // Fill Triangle + Quad
                writeableBmp.FillTriangle(2 * w3 + w6, h12 >> 1, 2 * w3 + w6 + w12, h6 + h12, 2 * w3 + w12, h6 + h12,
                                          GetRandomColor());
                writeableBmp.FillQuad(w6, h3 + (h12 >> 1), w6 + w12, h3 + h6, w6, h3 + h6 + h12 + (h12 >> 1), w12,
                                      h3 + h6, GetRandomColor());

                // Fill Ellipses
                writeableBmp.FillEllipse(rand.Next(w3, w3 + w6), rand.Next(h3, h3 + h6), rand.Next(w3 + w6, 2 * w3),
                                         rand.Next(h3 + h6, 2 * h3), GetRandomColor());
                writeableBmp.FillEllipseCentered(2 * w3 + w6, h3 + h6, w12, h12, GetRandomColor());

                // Fill closed Cardinal Spline curve
                p = new int[]
                {
                    w12 >> 1, 2 * h3 + h12,
                    w6, h - (h12 >> 1),
                    w3 - (w12 >> 1), 2 * h3 + h12,
                    w6 + w12, 2 * h3 + h12,
                    w6, 2 * h3 + (h12 >> 1),
                    w12, 2 * h3 + h12,
                };
                writeableBmp.FillCurveClosed(p, 0.5f, GetRandomColor());

                // Fill closed Beziér curve
                p = new int[]
                {
                    w3 + w12, 2 * h3 + h6 + h12,
                    w3 + w6 + (w12 >> 1), 2 * h3,
                    w3 + w6 + w12 + (w12 >> 1), 2 * h3,
                    w3 + w6 + w12, 2 * h3 + h6 + h12,
                };
                writeableBmp.FillBeziers(p, GetRandomColor());

                // Fill Rectangle
                writeableBmp.FillRectangle(rand.Next(2 * w3, 2 * w3 + w6), rand.Next(2 * h3, 2 * h3 + h6),
                                           rand.Next(2 * w3 + w6, w), rand.Next(2 * h3 + h6, h), GetRandomColor());
                // Fill another rectangle with alpha blending
                writeableBmp.FillRectangle(rand.Next(2 * w3, 2 * w3 + w6), rand.Next(2 * h3, 2 * h3 + h6),
                                           rand.Next(2 * w3 + w6, w), rand.Next(2 * h3 + h6, h), GetRandomColor(), true);

                BitmapBufferEx.ColorInt black = BitmapBufferEx.ColorInt.FromArgb(255, 0, 0, 0);
                // Draw Grid
                writeableBmp.DrawLine(0, h3, w, h3, Colors.Black);
                writeableBmp.DrawLine(0, 2 * h3, w, 2 * h3, Colors.Black);
                writeableBmp.DrawLine(w3, 0, w3, h, Colors.Black);
                writeableBmp.DrawLine(2 * w3, 0, 2 * w3, h, Colors.Black);

                // Invalidates on exit of Using block
            }
        }
Example #27
0
        unsafe public static byte[] GetCroppedBitmap(SoftwareBitmap inputBitmap, uint startPointX, uint startPointY, uint width, uint height)
        {
            int bigger;

            if (width >= height)
            {
                bigger = (int)width;
            }
            else
            {
                bigger = (int)height;
            }
            // なぜか0が入れられることがある?けど無視したら動いてるからヨシ!
            if (bigger == 0)
            {
                return(new byte[0]);
            }
            SoftwareBitmap softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, bigger, bigger, BitmapAlphaMode.Premultiplied);

            using (BitmapBuffer buffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.Write))
                using (BitmapBuffer inputBuffer = inputBitmap.LockBuffer(BitmapBufferAccessMode.Write))
                {
                    using (var reference = buffer.CreateReference())
                        using (var inputReference = inputBuffer.CreateReference())
                        {
                            byte *dataInBytes;
                            uint  capacity;
                            ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity);


                            byte *inputDataInBytes;
                            uint  inputCapacity;
                            ((IMemoryBufferByteAccess)inputReference).GetBuffer(out inputDataInBytes, out inputCapacity);

                            BitmapPlaneDescription bufferLayout      = buffer.GetPlaneDescription(0);
                            BitmapPlaneDescription inputBufferLayout = inputBuffer.GetPlaneDescription(0);
                            int h = bufferLayout.Height;
                            for (int i = 0; i < bufferLayout.Height; i++)
                            {
                                for (int j = 0; j < bufferLayout.Width; j++)
                                {
                                    byte valueB;
                                    byte valueG;
                                    byte valueR;
                                    byte valueA;
                                    if ((h - height) / 2 < i && (h + height) / 2 > i)
                                    {
                                        valueB = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 0];
                                        valueG = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 1];
                                        valueR = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 2];
                                        valueA = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 3];
                                        if (((double)valueR * 0.2126 + (double)valueG * 0.7152 + (double)valueB * 0.0772) / 255 > 0.5)
                                        {
                                            valueB = (byte)255;
                                            valueG = (byte)255;
                                            valueR = (byte)255;
                                            valueA = 0;
                                        }
                                        else
                                        {
                                            valueB = 0;
                                            valueG = 0;
                                            valueR = 0;
                                            valueA = 0;
                                        }
                                    }
                                    else
                                    {
                                        valueB = 0;
                                        valueG = 0;
                                        valueR = 0;
                                        valueA = 0;
                                    }
                                    dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0] = valueB;
                                    dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1] = valueG;
                                    dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2] = valueR;
                                    dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3] = valueA;
                                }
                            }
                            byte[] data = new byte[capacity];
                            Marshal.Copy((IntPtr)dataInBytes, data, 0, (int)capacity);
                            return(data);
                        }
                }
        }
Example #28
0
 public void Dispose()
 {
     _bb?.Dispose();
     _bb = null;
 }
Example #29
0
 public Texture2d LoadTexture(Stream stream)
 {
     using var bmp = new BitmapBuffer(stream, new BitmapLoadOptions());
     return((this as IGL).LoadTexture(bmp));
 }
Example #30
0
        /// <summary>
        /// Draws the different types of shapes.
        /// </summary>
        private void DrawStaticShapes(BitmapBuffer writeableBmp)
        {
            // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block
            using (writeableBmp.GetBitmapContext())
            {
                // Init some size vars
                int w    = writeableBmp.PixelWidth - 2;
                int h    = writeableBmp.PixelHeight - 2;
                int w3rd = w / 3;
                int h3rd = h / 3;
                int w6th = w3rd >> 1;
                int h6th = h3rd >> 1;

                // Clear
                writeableBmp.Clear();

                // Draw some points
                for (int i = 0; i < 200; i++)
                {
                    writeableBmp.SetPixel(rand.Next(w3rd), rand.Next(h3rd), GetRandomColor());
                }

                // Draw Standard shapes
                writeableBmp.DrawLine(rand.Next(w3rd, w3rd * 2), rand.Next(h3rd), rand.Next(w3rd, w3rd * 2), rand.Next(h3rd),
                                      GetRandomColor());
                writeableBmp.DrawTriangle(rand.Next(w3rd * 2, w - w6th), rand.Next(h6th), rand.Next(w3rd * 2, w),
                                          rand.Next(h6th, h3rd), rand.Next(w - w6th, w), rand.Next(h3rd),
                                          GetRandomColor());

                writeableBmp.DrawQuad(rand.Next(0, w6th), rand.Next(h3rd, h3rd + h6th), rand.Next(w6th, w3rd),
                                      rand.Next(h3rd, h3rd + h6th), rand.Next(w6th, w3rd),
                                      rand.Next(h3rd + h6th, 2 * h3rd), rand.Next(0, w6th), rand.Next(h3rd + h6th, 2 * h3rd),
                                      GetRandomColor());
                writeableBmp.DrawRectangle(rand.Next(w3rd, w3rd + w6th), rand.Next(h3rd, h3rd + h6th),
                                           rand.Next(w3rd + w6th, w3rd * 2), rand.Next(h3rd + h6th, 2 * h3rd),
                                           GetRandomColor());

                // Random polyline
                int[] p = new int[rand.Next(7, 10) * 2];
                for (int j = 0; j < p.Length; j += 2)
                {
                    p[j]     = rand.Next(w3rd * 2, w);
                    p[j + 1] = rand.Next(h3rd, 2 * h3rd);
                }
                writeableBmp.DrawPolyline(p, GetRandomColor());

                // Random closed polyline
                p = new int[rand.Next(6, 9) * 2];
                for (int j = 0; j < p.Length - 2; j += 2)
                {
                    p[j]     = rand.Next(w3rd);
                    p[j + 1] = rand.Next(2 * h3rd, h);
                }
                p[p.Length - 2] = p[0];
                p[p.Length - 1] = p[1];
                writeableBmp.DrawPolyline(p, GetRandomColor());

                // Ellipses
                writeableBmp.DrawEllipse(rand.Next(w3rd, w3rd + w6th), rand.Next(h3rd * 2, h - h6th),
                                         rand.Next(w3rd + w6th, w3rd * 2), rand.Next(h - h6th, h), GetRandomColor());
                writeableBmp.DrawEllipseCentered(w - w6th, h - h6th, w6th >> 1, h6th >> 1, GetRandomColor());


                // Draw Grid
                writeableBmp.DrawLine(0, h3rd, w, h3rd, Colors.Black);
                writeableBmp.DrawLine(0, 2 * h3rd, w, 2 * h3rd, Colors.Black);
                writeableBmp.DrawLine(w3rd, 0, w3rd, h, Colors.Black);
                writeableBmp.DrawLine(2 * w3rd, 0, 2 * w3rd, h, Colors.Black);

                // Invalidates on exit of using block
            }
        }