Example #1
0
        /// <summary>image processing render pass on entire image; given multiple input images, technique name, and parms</summary>
        public ImageTex Xrender(ImageTex[] inimages, String name, float[] parms)
        {
            FullTechnique technique = GetTechnique(name, parms);
            ImageTex      nimage    = Xrender(inimages, technique);

            return(nimage);
        }
Example #2
0
        /* test
         * for(int i=0; i<100;i++) { DE("q", "float p1=parms[1]; float p2=parms[2];col=(ii0+i[p1,p2])/2;"); i1.Xrender("q", new float[]{2,i,2*i}).Show(); }
         * */

        /// <summary>
        /// Get the technique given a possibly abbbreviated name, and apply parms
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public FullTechnique GetTechnique(string name, float[] parms)
        {
            name = name.ToLower();
            FullTechnique r = null;

            if (dynamicEffects.ContainsKey(name))
            {
                r = dynamicEffects[name];
            }
            foreach (var technique in mainEffect.Techniques)
            {
                if (technique.Name.ToLower().StartsWith(name.ToLower()))
                {
                    r = new FullTechnique(mainEffect, technique, technique.Name);
                }
            }
            if (r == null)
            {
                r = DynamicTechnique(name);
            }
            if (r == null)
            {
                throw new Exception("Technique not found for " + name);
            }
            r       = new FullTechnique(r); // clone so we don't corrupt others
            r.parms = parms;
            return(new FullTechnique(r));   // surely we don't need TWO new FullTechnique ???
        }
Example #3
0
 /// <summary>copy constructor for technique (eg use this if you want different parms)</summary>
 internal FullTechnique(FullTechnique t)
 {
     technique    = t.technique;
     effect       = t.effect;
     stepKernelXy = t.stepKernelXy;
     imageparm    = t.imageparm;
     parms        = t.parms == null ? null : (float[])(t.parms.Clone());
     Name         = t.Name;
 }
Example #4
0
        ///// <summary>Create an effect from a string, using a file as a temporary staging post (only used for some time tests)</summary>
        //internal Effect CreateEffectViaFile(string name, string s) {
        //    string fid = "temp.fx";
        //    string c = CreateFullEffectCode(s);
        //    File.WriteAllText(fid, c, Encoding.ASCII);
        //    Effect effect = LoadContentRuntimeFid(fid);
        //    dynamicEffects[name] = new FullTechnique(effect, effect.Techniques["Standard"]);
        //    return effect;
        //}

        /// <summary>Create a named technique from the "Standard" technique in an effect string </summary>
        private FullTechnique CreateEffectDirectI(string name, string s)
        {
            string c      = CreateFullEffectCode(s);
            Effect effect = LoadContentRuntimeString(c, name);

            if (effect == null)
            {
                return(null);
            }
            FullTechnique ft = new FullTechnique(effect, effect.Techniques["Standard"], name);

            return(ft);
        }
Example #5
0
        /// <summary>
        /// generate a dynamic technique for the given name (TODO: make more generic)
        /// name may be xxx_N_M for an NxM filter, and also xxx_N for an NxN filter
        /// Unsharp_ 1..5
        /// Percentile_ 0..2  (requires a single percentile parameter)
        /// Median_ 0..2
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private FullTechnique DynamicTechnique(String name)
        {
            name = name.ToLower();
            string[]      nn  = name.Split('_');
            int           pp0 = nn.Count() > 1 ? nn[1].Int() : 0;
            int           pp1 = nn.Count() > 2 ? nn[2].Int() : pp0;
            FullTechnique ft  = null;

            try {
                if (nn[0] == "median")
                {
                    ft = MedianTest(pp0, pp1);
                }
                else if (nn[0] == "percentile")
                {
                    ft = PercentileTest(pp0, pp1);
                }
                else if (nn[0] == "unsharp")
                {
                    ft = CreateEffectDirect(name, DynamicFx.Unsharp, "X", pp0 + "", "Y", pp1 + "");
                }
                else
                {
                    return(null);
                }
            } catch (Exception e) {
                Form1.Beep("Cannot create technique " + name + "   " + e);
                return(null);
            }

            string nname = nn[0] + "_" + pp0 + "_" + pp1;

            Console.Out.WriteLine("Generated technique " + nname);
            dynamicEffects[nname] = ft;
            if (pp0 == pp1)
            {
                dynamicEffects[nn[0] + "_" + pp0] = ft;
            }
            return(ft);
        }
Example #6
0
        /// <summary>image processing render pass on entire image;
        /// given multiple input images, technique and transformation matrix and required output size
        /// </summary>
        internal ImageTex Xrender(ImageTex[] inimage, FullTechnique ftechnique, Matrix tran, int ssizeX, int ssizeY)
        {
            //*//if (dotime) timer.Start();
            EffectTechnique ltechnique = ftechnique.technique;
            Effect          effect     = ftechnique.effect;

            RenderTarget2D xxtarget;
            NextOp         op     = inimage[0].nextOpNew; // STD, ALT, SHARE, NEW
            int            isizeX = inimage[0].Width;
            int            isizeY = inimage[0].Height;

            if (ssizeX == 0)
            {
                ssizeX = isizeX;
            }
            if (ssizeY == 0)
            {
                ssizeY = isizeY;
            }

            switch (op)
            {
            case NextOp.STD: xxtarget = xtarget; break;

            case NextOp.ALT: xxtarget = xtarget1; break;

            case NextOp.SHARE: rtn++; xxtarget = rts[rtn % SIZE]; break;

            case NextOp.NEW: xxtarget = null; break;

            default: throw new Exception("Unexpected NewOp " + op);
            }
            SurfaceFormat sf = useVector4 ? SurfaceFormat.Vector4 : graphicsDevice.DisplayMode.Format;

            if (xxtarget == null || xxtarget.Width != ssizeX || xxtarget.Height != ssizeY || xxtarget.Format != sf)
            {
                // programming note:  TODO:
                // If the xxtarget is not the right size, I can't get things to work.
                // Even if it is too big and I cut it down with viewports.
                // This reallocation does not seem to matter too much with graphicsDevice.DisplayMode.Format,
                // but is a performance problem with SurfaceFormat.Vector4.
                // We probably don't need Vector4 too much anyway, but if we do we should cache a few RenderTargets for the case of size changing often
                // (this multisize case arises a lot in the scanline test code).
                // Console.WriteLine("xxsize " + ssizeX + " " + ssizeY);
                xxtarget = new RenderTarget2D(graphicsDevice, ssizeX, ssizeY, 1, sf);
                switch (op)
                {
                case NextOp.STD: xtarget = xxtarget; break;

                case NextOp.ALT: xtarget1 = xxtarget; break;

                case NextOp.SHARE: rts[rtn % SIZE] = xxtarget; break;

                case NextOp.NEW: break;

                default: throw new Exception("Unexpected NewOp " + op);
                }
            }

            Viewport savevp = graphicsDevice.Viewport;                         // this should match the screen size

            graphicsDevice.SetRenderTarget(0, xxtarget);                       // << note that this changes graphicsDevice.Viewport to xxtarget = image size

            graphicsDevice.Clear(Microsoft.Xna.Framework.Graphics.Color.Gray); // this processing should often cover entire image, so no need to clear


            float h = 0.5f;
            //Matrix mat = new Matrix(h, 0, 0, 0, 0, -h, 0, 0, 0, 0, 1, 0, h + h / isizeX, h + h / isizeY, 0, 1);
            //Matrix ss0 = new Matrix(1, 0, 0, 0, 0, isizeY * 1.0f / isizeX, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
            //Matrix ss1 = new Matrix(1, 0, 0, 0, 0, isizeX * 1.0f / isizeY, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
            //mat = mat * ss0 * tran * ss1; // *mat;
            Matrix mat = new Matrix(h, 0, 0, 0, 0, -h, 0, 0, 0, 0, 1, 0, h + h / isizeX, h + h / isizeY, 0, 1);

            mat = mat * tran; // *mat;
            effect.Parameters["TexProj"].SetValue(mat);
            effect.Parameters["isize"].SetValue(new Vector2(isizeX, isizeY));
            effect.Parameters["stepImageXy"].SetValue(inimage[0].stepImageXy);
            ftechnique.SetParameters();
            if (inimage.Length >= 1)
            {
                effect.Parameters["image"].SetValue(inimage[0].texture);
            }
            if (inimage.Length >= 2)
            {
                effect.Parameters["image2"].SetValue(inimage[1].texture);
            }
            if (inimage.Length >= 3)
            {
                effect.Parameters["image3"].SetValue(inimage[2].texture);
            }
            if (inimage.Length >= 4)
            {
                effect.Parameters["image4"].SetValue(inimage[3].texture);
            }

            RunEffect(effect);
            graphicsDevice.SetRenderTarget(0, null);  // << note that this changes graphicsDevice.Viewport to (large) backBuffer size
            Texture2D result = xxtarget.GetTexture();

            graphicsDevice.Viewport = savevp;         // restore the back buffer

            // ? timer not reliable, work not complete behind the scenes
            //*//if (dotime) timer.time(ltechnique.Name);
            // TODO: improve fid text
            ImageTex r = new ImageTex(inimage[0].fid + ";" + ltechnique, result, this, inimage[0].fileInfo + " " + ftechnique.Name);

            // r.Show();
            return(r);
        }
Example #7
0
 /// <summary>image processing render pass on entire image; given multiple input images and technique</summary>
 public ImageTex Xrender(ImageTex[] inimage, FullTechnique ltechnique)
 {
     return(Xrender(inimage, ltechnique, Matrix.Identity, 0, 0));
 }
Example #8
0
 /// <summary>image processing render pass on entire image; given input image and technique</summary>
 public ImageTex Xrender(ImageTex inimage, FullTechnique ltechnique)
 {
     return(Xrender(new ImageTex[] { inimage }, ltechnique));
 }