Esempio n. 1
0
        /// <summary>
        /// Lazily recomputes the world inverse transpose matrix and
        /// eye position based on the current effect parameter settings.
        /// </summary>
        internal static BlEffectDirtyFlags SetLightingMatrices(BlEffectDirtyFlags dirtyFlags, ref Matrix world, ref Matrix view,
                                                               EffectParameter worldParam, EffectParameter worldInverseTransposeParam, EffectParameter eyePositionParam)
        {
            // Set the world and world inverse transpose matrices.
            if ((dirtyFlags & BlEffectDirtyFlags.World) != 0)
            {
                Matrix worldTranspose;
                Matrix worldInverseTranspose;

                Matrix.Invert(ref world, out worldTranspose);
                Matrix.Transpose(ref worldTranspose, out worldInverseTranspose);

                worldParam.SetValue(world);
                worldInverseTransposeParam.SetValue(worldInverseTranspose);

                dirtyFlags &= ~BlEffectDirtyFlags.World;
            }

            // Set the eye position.
            if ((dirtyFlags & BlEffectDirtyFlags.EyePosition) != 0)
            {
                Matrix viewInverse;

                Matrix.Invert(ref view, out viewInverse);

                eyePositionParam.SetValue(viewInverse.Translation);

                dirtyFlags &= ~BlEffectDirtyFlags.EyePosition;
            }

            return(dirtyFlags);
        }
Esempio n. 2
0
        /// <summary>
        /// Lazily recomputes the world+view+projection matrix and
        /// fog vector based on the current effect parameter settings.
        /// </summary>
        internal static BlEffectDirtyFlags SetWorldViewProjAndFog(BlEffectDirtyFlags dirtyFlags,
                                                                  ref Matrix world, ref Matrix view, ref Matrix projection, ref Matrix worldView,
                                                                  bool fogEnabled, float fogStart, float fogEnd,
                                                                  EffectParameter worldViewProjParam, EffectParameter fogVectorParam)
        {
            // Recompute the world+view+projection matrix?
            if ((dirtyFlags & BlEffectDirtyFlags.WorldViewProj) != 0)
            {
                Matrix worldViewProj;

                Matrix.Multiply(ref world, ref view, out worldView);
                Matrix.Multiply(ref worldView, ref projection, out worldViewProj);

                worldViewProjParam.SetValue(worldViewProj);

                dirtyFlags &= ~BlEffectDirtyFlags.WorldViewProj;
            }

            if (fogEnabled)
            {
                // Recompute the fog vector?
                if ((dirtyFlags & (BlEffectDirtyFlags.Fog | BlEffectDirtyFlags.FogEnable)) != 0)
                {
                    SetFogVector(ref worldView, fogStart, fogEnd, fogVectorParam);

                    dirtyFlags &= ~(BlEffectDirtyFlags.Fog | BlEffectDirtyFlags.FogEnable);
                }
            }
            else
            {
                // When fog is disabled, make sure the fog vector is reset to zero.
                if ((dirtyFlags & BlEffectDirtyFlags.FogEnable) != 0)
                {
                    fogVectorParam.SetValue(Vector4.Zero);

                    dirtyFlags &= ~BlEffectDirtyFlags.FogEnable;
                }
            }

            return(dirtyFlags);
        }
Esempio n. 3
0
        /// <summary>
        /// Lazily computes derived parameter values immediately before applying the effect.
        /// </summary>
        protected override void OnApply()
        {
            // Recompute the world+view+projection matrix or fog vector?
            dirtyFlags = BlEffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);

            // Recompute the diffuse/emissive/alpha material color parameters?
            if ((dirtyFlags & BlEffectDirtyFlags.MaterialColor) != 0)
            {
                BlEffectHelpers.SetMaterialColor(lightingEnabled, alpha, ref diffuseColor, ref emissiveColor, ref ambientLightColor, diffuseColorParam, emissiveColorParam);

                dirtyFlags &= ~BlEffectDirtyFlags.MaterialColor;
            }

            if (lightingEnabled)
            {
                // Recompute the world inverse transpose and eye position?
                dirtyFlags = BlEffectHelpers.SetLightingMatrices(dirtyFlags, ref world, ref view, worldParam, worldInverseTransposeParam, eyePositionParam);


                // Check if we can use the only-bother-with-the-first-light shader optimization.
                bool newOneLight = !light1.Enabled && !light2.Enabled;

                if (oneLight != newOneLight)
                {
                    oneLight    = newOneLight;
                    dirtyFlags |= BlEffectDirtyFlags.ShaderIndex;
                }
            }

            // Recompute the shader index?
            if ((dirtyFlags & BlEffectDirtyFlags.ShaderIndex) != 0)
            {
                int shaderIndex = 0;

                if (!fogEnabled)
                {
                    shaderIndex += 1;
                }

                if (vertexColorEnabled)
                {
                    shaderIndex += 2;
                }

                if (textureEnabled)
                {
                    shaderIndex += 4;
                }

                if (lightingEnabled)
                {
                    if (preferPerPixelLighting)
                    {
                        shaderIndex += 24;
                    }
                    else if (oneLight)
                    {
                        shaderIndex += 16;
                    }
                    else
                    {
                        shaderIndex += 8;
                    }
                }

                dirtyFlags &= ~BlEffectDirtyFlags.ShaderIndex;

                CurrentTechnique = Techniques[shaderIndex];
            }
        }