예제 #1
0
        /// <summary>
        ///		Internal method for clearing the illumination pass list.
        /// </summary>
        protected void ClearIlluminationPasses()
        {
            for (int i = 0; i < illuminationPasses.Count; i++)
            {
                IlluminationPass iPass = (IlluminationPass)illuminationPasses[i];

                if (iPass.DestroyOnShutdown)
                {
                    iPass.Pass.QueueForDeletion();
                }
            }

            illuminationPasses.Clear();
        }
예제 #2
0
        /// <summary>
        ///    Loads resources required by this Technique.
        /// </summary>
        public void Load()
        {
            Debug.Assert(isSupported, "This technique is not supported.");

            // load each pass
            for (int i = 0; i < passes.Count; i++)
            {
                ((Pass)passes[i]).Load();
            }
            // load each illumination pass
            for (int i = 0; i < illuminationPasses.Count; i++)
            {
                IlluminationPass pass = (IlluminationPass)illuminationPasses[i];
                if (pass.Pass != pass.OriginalPass)
                {
                    pass.Pass.Load();
                }
            }
        }
        /// <summary>
        ///		Internal method for adding a solid renderable ot the group based on lighting stage.
        /// </summary>
        /// <param name="technique">Technique to use for this renderable.</param>
        /// <param name="renderable">Renderable to add to the queue.</param>
        protected void AddSolidRenderableSplitByLightType(Technique technique, IRenderable renderable)
        {
            // Divide the passes into the 3 categories
            for (int i = 0; i < technique.IlluminationPassCount; i++)
            {
                // Insert into solid list
                IlluminationPass illpass = technique.GetIlluminationPass(i);
                SortedList       passMap = null;

                switch (illpass.Stage)
                {
                case IlluminationStage.Ambient:
                    passMap = solidPasses;
                    break;

                case IlluminationStage.PerLight:
                    passMap = solidPassesDiffuseSpecular;
                    break;

                case IlluminationStage.Decal:
                    passMap = solidPassesDecal;
                    break;
                }

                RenderableList solidList = (RenderableList)passMap[illpass.Pass];

                if (solidList == null)
                {
                    // add a new list to hold renderables for this pass
                    solidList = new RenderableList();
                    passMap.Add(illpass.Pass, solidList);
                }

                solidList.Add(renderable);
            }
        }
예제 #4
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(IlluminationPass obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
예제 #5
0
        /// <summary>
        ///		Internal method for splitting the passes into illumination passes.
        /// </summary>
        public void CompileIlluminationPasses()
        {
            ClearIlluminationPasses();

            // don't need to split transparent passes since they are rendered seperately
            if (this.IsTransparent)
            {
                return;
            }

            // start off with ambient passes
            IlluminationStage stage = IlluminationStage.Ambient;

            bool hasAmbient = false;

            for (int i = 0; i < passes.Count; /* increment in logic */)
            {
                Pass             pass = (Pass)passes[i];
                IlluminationPass iPass;

                switch (stage)
                {
                case IlluminationStage.Ambient:
                    // keep looking for ambient only
                    if (pass.IsAmbientOnly)
                    {
                        iPass = new IlluminationPass();
                        iPass.OriginalPass = pass;
                        iPass.Pass         = pass;
                        iPass.Stage        = stage;
                        illuminationPasses.Add(iPass);
                        hasAmbient = true;

                        // progress to the next pass
                        i++;
                    }
                    else
                    {
                        // split off any ambient part
                        if (pass.Ambient.CompareTo(ColorEx.Black) != 0 ||
                            pass.Emissive.CompareTo(ColorEx.Black) != 0 ||
                            pass.AlphaRejectFunction != CompareFunction.AlwaysPass)
                        {
                            Pass newPass = new Pass(this, pass.Index);
                            pass.CopyTo(newPass);
                            if (newPass.AlphaRejectFunction != CompareFunction.AlwaysPass)
                            {
                                // Alpha rejection passes must retain their transparency, so
                                // we allow the texture units, but override the colour functions
                                for (int tindex = 0; tindex < newPass.NumTextureUnitStages; tindex++)
                                {
                                    TextureUnitState tus = newPass.GetTextureUnitState(tindex);
                                    tus.SetColorOperationEx(LayerBlendOperationEx.Source1, LayerBlendSource.Current, LayerBlendSource.Current);
                                }
                            }
                            else
                            {
                                // remove any texture units
                                newPass.RemoveAllTextureUnitStates();
                            }

                            // also remove any fragment program
                            if (newPass.HasFragmentProgram)
                            {
                                newPass.SetFragmentProgram("");
                            }

                            // We have to leave vertex program alone (if any) and
                            // just trust that the author is using light bindings, which
                            // we will ensure there are none in the ambient pass
                            newPass.Diffuse  = new ColorEx(newPass.Diffuse.a, 0f, 0f, 0f);                                    // Preserving alpha
                            newPass.Specular = ColorEx.Black;

                            // Calculate hash value for new pass, because we are compiling
                            // illumination passes on demand, which will loss hash calculate
                            // before it add to render queue first time.
                            newPass.RecalculateHash();

                            iPass = new IlluminationPass();
                            iPass.DestroyOnShutdown = true;
                            iPass.OriginalPass      = pass;
                            iPass.Pass  = newPass;
                            iPass.Stage = stage;

                            illuminationPasses.Add(iPass);
                            hasAmbient = true;
                        }

                        if (!hasAmbient)
                        {
                            // make up a new basic pass
                            Pass newPass = new Pass(this, pass.Index);
                            pass.CopyTo(newPass);

                            newPass.Ambient = ColorEx.Black;
                            newPass.Diffuse = ColorEx.Black;

                            // Calculate hash value for new pass, because we are compiling
                            // illumination passes on demand, which will loss hash calculate
                            // before it add to render queue first time.
                            newPass.RecalculateHash();

                            iPass = new IlluminationPass();
                            iPass.DestroyOnShutdown = true;
                            iPass.OriginalPass      = pass;
                            iPass.Pass  = newPass;
                            iPass.Stage = stage;
                            illuminationPasses.Add(iPass);
                            hasAmbient = true;
                        }

                        // this means we are done with ambients, progress to per-light
                        stage = IlluminationStage.PerLight;
                    }

                    break;

                case IlluminationStage.PerLight:
                    if (pass.RunOncePerLight)
                    {
                        // if this is per-light already, use it directly
                        iPass = new IlluminationPass();
                        iPass.DestroyOnShutdown = false;
                        iPass.OriginalPass      = pass;
                        iPass.Pass  = pass;
                        iPass.Stage = stage;
                        illuminationPasses.Add(iPass);

                        // progress to the next pass
                        i++;
                    }
                    else
                    {
                        // split off per-light details (can only be done for one)
                        if (pass.LightingEnabled &&
                            (pass.Diffuse.CompareTo(ColorEx.Black) != 0 ||
                             pass.Specular.CompareTo(ColorEx.Black) != 0))
                        {
                            // copy existing pass
                            Pass newPass = new Pass(this, pass.Index);
                            pass.CopyTo(newPass);

                            if (newPass.AlphaRejectFunction != CompareFunction.AlwaysPass)
                            {
                                // Alpha rejection passes must retain their transparency, so
                                // we allow the texture units, but override the colour functions
                                for (int tindex = 0; tindex < newPass.NumTextureUnitStages; tindex++)
                                {
                                    TextureUnitState tus = newPass.GetTextureUnitState(tindex);
                                    tus.SetColorOperationEx(LayerBlendOperationEx.Source1, LayerBlendSource.Current, LayerBlendSource.Current);
                                }
                            }
                            else
                            {
                                // remove any texture units
                                newPass.RemoveAllTextureUnitStates();
                            }

                            // also remove any fragment program
                            if (newPass.HasFragmentProgram)
                            {
                                newPass.SetFragmentProgram("");
                            }

                            // Cannot remove vertex program, have to assume that
                            // it will process diffuse lights, ambient will be turned off
                            newPass.Ambient  = ColorEx.Black;
                            newPass.Emissive = ColorEx.Black;

                            // must be additive
                            newPass.SetSceneBlending(SceneBlendFactor.One, SceneBlendFactor.One);

                            iPass = new IlluminationPass();
                            iPass.DestroyOnShutdown = true;
                            iPass.OriginalPass      = pass;
                            iPass.Pass  = newPass;
                            iPass.Stage = stage;

                            illuminationPasses.Add(iPass);
                        }

                        // This means the end of per-light passes
                        stage = IlluminationStage.Decal;
                    }

                    break;

                case IlluminationStage.Decal:
                    // We just want a 'lighting off' pass to finish off
                    // and only if there are texture units
                    if (pass.NumTextureUnitStages > 0)
                    {
                        if (!pass.LightingEnabled)
                        {
                            // we assume this pass already combines as required with the scene
                            iPass = new IlluminationPass();
                            iPass.DestroyOnShutdown = false;
                            iPass.OriginalPass      = pass;
                            iPass.Pass  = pass;
                            iPass.Stage = stage;
                            illuminationPasses.Add(iPass);
                        }
                        else
                        {
                            // Copy the pass and tweak away the lighting parts
                            Pass newPass = new Pass(this, pass.Index);
                            pass.CopyTo(newPass);
                            newPass.Ambient         = ColorEx.Black;
                            newPass.Diffuse         = new ColorEx(newPass.Diffuse.a, 0f, 0f, 0f);                             // Preserving alpha
                            newPass.Specular        = ColorEx.Black;
                            newPass.Emissive        = ColorEx.Black;
                            newPass.LightingEnabled = false;
                            // modulate
                            newPass.SetSceneBlending(SceneBlendFactor.DestColor, SceneBlendFactor.Zero);

                            // Calculate hash value for new pass, because we are compiling
                            // illumination passes on demand, which will loss hash calculate
                            // before it add to render queue first time.
                            newPass.RecalculateHash();

                            // there is nothing we can do about vertex & fragment
                            // programs here, so people will just have to make their
                            // programs friendly-like if they want to use this technique
                            iPass = new IlluminationPass();
                            iPass.DestroyOnShutdown = true;
                            iPass.OriginalPass      = pass;
                            iPass.Pass  = newPass;
                            iPass.Stage = stage;
                            illuminationPasses.Add(iPass);
                        }
                    }

                    // always increment on decal, since nothing more to do with this pass
                    i++;

                    break;
                }
            }
        }