Example #1
0
        /// <summary>
        /// executes the shader for the outer image layer
        /// </summary>
        /// <returns></returns>
        public Color Run(TextureArray2D source, Models models)
        {
            var texDst = models.GlData.TextureCache.GetTexture();

            models.GlData.BindSampler(0, false, false);
            source.BindAsTexture2D(0, 0, 0);
            texDst.BindAsImage(1, 0, 0, TextureAccess.WriteOnly);

            // bind and set uniforms
            program.Bind();
            // direction
            GL.Uniform2(0, 1, 0);
            // stride
            var curStride = 2;

            GL.Uniform1(1, curStride);

            var curWidth = models.Images.Width;

            GL.DispatchCompute(Utility.Utility.DivideRoundUp(curWidth, LocalSize * 2), models.Images.Height, 1);

            // swap textures
            var texSrc = models.GlData.TextureCache.GetTexture();

            GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit);

            // do invocation until finished
            while (curWidth > 2)
            {
                //curWidth /= 2;
                curWidth   = Utility.Utility.DivideRoundUp(curWidth, 2);
                curStride *= 2;

                // swap textures
                Swap(ref texSrc, ref texDst);
                texSrc.BindAsTexture2D(0, 0, 0);
                texDst.BindAsImage(1, 0, 0, TextureAccess.WriteOnly);

                // stride
                GL.Uniform1(1, curStride);

                // dispatch
                GL.DispatchCompute(Utility.Utility.DivideRoundUp(curWidth, LocalSize * 2), models.Images.Height, 1);
                GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit);
            }

            // do the scan in y direction
            var curHeight = models.Images.Height;

            curStride = 2;

            // set direction
            GL.Uniform2(0, 0, 1);

            while (curHeight > 1)
            {
                // swap textures
                Swap(ref texSrc, ref texDst);
                texSrc.BindAsTexture2D(0, 0, 0);
                texDst.BindAsImage(1, 0, 0, TextureAccess.WriteOnly);

                // stride
                GL.Uniform1(1, curStride);

                GL.DispatchCompute(1, Utility.Utility.DivideRoundUp(curHeight, LocalSize * 2), 1);
                GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit);

                curHeight  = Utility.Utility.DivideRoundUp(curHeight, 2);
                curStride *= 2;
            }

            GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);
            // the result is in pixel 0 0

            texDst.BindAsTexture2D(models.GlData.GetPixelShader.GetTextureLocation(), 0, 0);
            // y coordinates for the texture fetch are reverted
            var res = models.GlData.GetPixelShader.GetPixelColor(0, 0, 0);

            // cleanup
            models.GlData.TextureCache.StoreTexture(texSrc);
            models.GlData.TextureCache.StoreTexture(texDst);

            return(ModifyResult(res));
        }