private IEffectParameterSet GetEffectParameterSet(IMaterial material, ref bool changedRenderRequest, ref string changedRenderRequestBy)
        {
            if (_effectUsedForParameterSetCache == _cachedEffect &&
                changedRenderRequest == false &&
                (!_lastDidSetDiffuseTexture || _lastSetDiffuseTexture == _lastCachedDiffuseTexture?.Texture) &&
                (!_lastDidSetNormalMap || _lastSetNormalMap == _lastCachedNormalMapTexture?.Texture) &&
                (!_lastDidSetSpecularPower || _lastSetSpecularPower == _lastCachedSpecularPower) &&
                (!_lastDidSetSpecularColorMap || _lastSetSpecularColorMap == _lastCachedSpecularColorMapTexture?.Texture) &&
                (!_lastDidSetSpecularColor || _lastSetSpecularColor == _lastCachedSpecularColor) &&
                (!_lastDidSetDiffuseColor || _lastSetDiffuseColor == (material.ColorDiffuse ?? Color.Black)))
            {
                // Reuse the existing parameter set.
                return(_cachedEffectParameterSet);
            }

            changedRenderRequest    = true;
            changedRenderRequestBy += ":parameterset";

            // Create a new parameter set and cache it.
            _cachedEffectParameterSet       = _cachedEffect.CreateParameterSet();
            _effectUsedForParameterSetCache = _cachedEffect;

            _lastSetDiffuseTexture      = null;
            _lastSetNormalMap           = null;
            _lastSetSpecularPower       = null;
            _lastSetSpecularColorMap    = null;
            _lastSetSpecularColor       = null;
            _lastSetDiffuseColor        = null;
            _lastDidSetDiffuseTexture   = false;
            _lastDidSetNormalMap        = false;
            _lastDidSetSpecularPower    = false;
            _lastDidSetSpecularColorMap = false;
            _lastDidSetSpecularColor    = false;
            _lastDidSetDiffuseColor     = false;

            if (_cachedEffectParameterSet.HasSemantic <ITextureEffectSemantic>())
            {
                if (_lastCachedDiffuseTexture?.Texture != null)
                {
                    _cachedEffectParameterSet.GetSemantic <ITextureEffectSemantic>().Texture =
                        _lastCachedDiffuseTexture.Texture;
                    _lastSetDiffuseTexture    = _lastCachedDiffuseTexture.Texture;
                    _lastDidSetDiffuseTexture = true;
                }
            }

            if (_cachedEffectParameterSet.HasSemantic <INormalMapEffectSemantic>())
            {
                if (_lastCachedNormalMapTexture?.Texture != null)
                {
                    _cachedEffectParameterSet.GetSemantic <INormalMapEffectSemantic>().NormalMap =
                        _lastCachedNormalMapTexture.Texture;
                    _lastSetNormalMap    = _lastCachedNormalMapTexture.Texture;
                    _lastDidSetNormalMap = true;
                }
            }

            if (_cachedEffectParameterSet.HasSemantic <ISpecularEffectSemantic>())
            {
                if (_lastCachedSpecularPower != null)
                {
                    var semantic = _cachedEffectParameterSet.GetSemantic <ISpecularEffectSemantic>();
                    semantic.SpecularPower   = _lastCachedSpecularPower.Value;
                    _lastSetSpecularPower    = _lastCachedSpecularPower.Value;
                    _lastDidSetSpecularPower = true;

                    if (_lastCachedSpecularColorMapTexture != null)
                    {
                        semantic.SpecularColorMap   = _lastCachedSpecularColorMapTexture.Texture;
                        _lastSetSpecularColorMap    = _lastCachedSpecularColorMapTexture.Texture;
                        _lastDidSetSpecularColorMap = true;
                    }
                    else if (_lastCachedSpecularColor != null)
                    {
                        semantic.SpecularColor   = _lastCachedSpecularColor.Value;
                        _lastSetSpecularColor    = _lastCachedSpecularColor.Value;
                        _lastDidSetSpecularColor = true;
                    }
                }
            }

            if (_cachedEffectParameterSet.HasSemantic <IColorDiffuseEffectSemantic>())
            {
                var v = material.ColorDiffuse ?? Color.Black;
                _cachedEffectParameterSet.GetSemantic <IColorDiffuseEffectSemantic>().Diffuse = v;
                _lastSetDiffuseColor    = v;
                _lastDidSetDiffuseColor = true;
            }

            return(_cachedEffectParameterSet);
        }
示例#2
0
        private void BlitInternal(
            IRenderContext renderContext,
            Texture2D source,
            RenderTarget2D[] destinations = null,
            IEffect shader = null,
            IEffectParameterSet effectParameterSet = null,
            BlendState blendState = null,
            Vector2?offset        = null,
            Vector2?size          = null)
        {
            float destWidth, destHeight;

            if (destinations != null)
            {
                var destinationsBound = new RenderTargetBinding[destinations.Length];
                for (var i = 0; i < destinations.Length; i++)
                {
                    // Implicit cast.
                    destinationsBound[i] = destinations[i];
                }

                renderContext.PushRenderTarget(destinationsBound);
                destWidth  = destinations[0].Width;
                destHeight = destinations[0].Height;
            }
            else
            {
                // TODO: renderContext.GraphicsDevice.GetRenderTargets();
                destWidth  = renderContext.GraphicsDevice.PresentationParameters.BackBufferWidth;
                destHeight = renderContext.GraphicsDevice.PresentationParameters.BackBufferHeight;
            }

            offset = offset ?? new Vector2(0, 0);
            size   = size ?? new Vector2(1 - offset.Value.X, 1 - offset.Value.Y);

            if (blendState == null)
            {
                blendState = BlendState.Opaque;
            }

            if (shader == null && _blitEffect.IsReady)
            {
                shader = _blitEffect.Asset.Effects["Texture"];
            }

            if (shader == null)
            {
                // Can't perform blit; no shader is available.
                return;
            }

            if (effectParameterSet == null)
            {
                effectParameterSet = shader.CreateParameterSet();
            }

            if (_vertexBuffer == null)
            {
                _vertexBuffer = new VertexBuffer(renderContext.GraphicsDevice, typeof(VertexPositionNormalTexture),
                                                 _vertexes.Length, BufferUsage.WriteOnly);
                _vertexBuffer.SetData(_vertexes);
            }

            if (_indexBuffer == null)
            {
                _indexBuffer = new IndexBuffer(renderContext.GraphicsDevice, typeof(short), _indicies.Length,
                                               BufferUsage.WriteOnly);
                _indexBuffer.SetData(_indicies);
            }

            var oldWorld      = renderContext.World;
            var oldProjection = renderContext.Projection;
            var oldView       = renderContext.View;

            renderContext.GraphicsDevice.BlendState        = blendState;
            renderContext.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            renderContext.GraphicsDevice.SamplerStates[0]  = SamplerState.LinearWrap;
            renderContext.GraphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;

            renderContext.World      = Matrix.CreateScale(destWidth, destHeight, 1);
            renderContext.Projection =
#if !PLATFORM_WINDOWS
                Matrix.CreateTranslation(-0.5f, -0.5f, 0) *
#endif
                Matrix.CreateOrthographicOffCenter(
                    destWidth * (-offset.Value.X / size.Value.X),
                    destWidth * (-offset.Value.X / size.Value.X) + destWidth / size.Value.X,
                    destHeight * (-offset.Value.Y / size.Value.Y) + destHeight / size.Value.Y,
                    destHeight * (-offset.Value.Y / size.Value.Y),
                    0,
                    1);
            renderContext.View = Matrix.Identity;

            if (source != null && effectParameterSet != null)
            {
                var semantic = effectParameterSet.GetSemantic <ITextureEffectSemantic>();
                if (semantic.Texture != source)
                {
                    semantic.Texture = source;
                }
            }

            renderContext.GraphicsDevice.SetVertexBuffer(_vertexBuffer);
            renderContext.GraphicsDevice.Indices = _indexBuffer;

            shader.LoadParameterSet(renderContext, effectParameterSet);
            foreach (var pass in shader.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                renderContext.GraphicsDevice.DrawIndexedPrimitives(
                    PrimitiveType.TriangleStrip,
                    0,
                    0,
                    2);
            }

            renderContext.World      = oldWorld;
            renderContext.Projection = oldProjection;
            renderContext.View       = oldView;

            if (destinations != null)
            {
                renderContext.PopRenderTarget();
            }
        }
        private void BlitInternal(
            IRenderContext renderContext,
            Texture2D source,
            RenderTarget2D[] destinations = null, 
            IEffect shader = null,
            IEffectParameterSet effectParameterSet = null,
            BlendState blendState = null,
            Vector2? offset = null,
            Vector2? size = null)
        {
            float destWidth, destHeight;
            if (destinations != null)
            {
                var destinationsBound = new RenderTargetBinding[destinations.Length];
                for (var i = 0; i < destinations.Length; i++)
                {
                    // Implicit cast.
                    destinationsBound[i] = destinations[i];
                }

                renderContext.PushRenderTarget(destinationsBound);
                destWidth = destinations[0].Width;
                destHeight = destinations[0].Height;
            }
            else
            {
                // TODO: renderContext.GraphicsDevice.GetRenderTargets();
                destWidth = renderContext.GraphicsDevice.PresentationParameters.BackBufferWidth;
                destHeight = renderContext.GraphicsDevice.PresentationParameters.BackBufferHeight;
            }

            offset = offset ?? new Vector2(0, 0);
            size = size ?? new Vector2(1 - offset.Value.X, 1 - offset.Value.Y);

            if (blendState == null)
            {
                blendState = BlendState.Opaque;
            }

            if (shader == null)
            {
                shader = _blitEffect;
            }

            if (effectParameterSet == null)
            {
                effectParameterSet = shader.CreateParameterSet();
            }

            if (_vertexBuffer == null)
            {
                _vertexBuffer = new VertexBuffer(renderContext.GraphicsDevice, typeof (VertexPositionNormalTexture),
                    _vertexes.Length, BufferUsage.WriteOnly);
                _vertexBuffer.SetData(_vertexes);
            }

            if (_indexBuffer == null)
            {
                _indexBuffer = new IndexBuffer(renderContext.GraphicsDevice, typeof (short), _indicies.Length,
                    BufferUsage.WriteOnly);
                _indexBuffer.SetData(_indicies);
            }

            var oldWorld = renderContext.World;
            var oldProjection = renderContext.Projection;
            var oldView = renderContext.View;

            renderContext.GraphicsDevice.BlendState = blendState;
            renderContext.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            renderContext.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
            renderContext.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;

            renderContext.World = Matrix.CreateScale(destWidth, destHeight, 1);
            renderContext.Projection =
#if !PLATFORM_WINDOWS
                Matrix.CreateTranslation(-0.5f, -0.5f, 0) *
#endif
                Matrix.CreateOrthographicOffCenter(
                    destWidth * (-offset.Value.X / size.Value.X),
                    destWidth * (-offset.Value.X / size.Value.X) + destWidth / size.Value.X, 
                    destHeight * (-offset.Value.Y / size.Value.Y) + destHeight / size.Value.Y,
                    destHeight * (-offset.Value.Y / size.Value.Y),
                    0,
                    1);
            renderContext.View = Matrix.Identity;

            if (source != null && effectParameterSet != null)
            {
                var semantic = effectParameterSet.GetSemantic<ITextureEffectSemantic>();
                if (semantic.Texture != source)
                {
                    semantic.Texture = source;
                }
            }

            renderContext.GraphicsDevice.SetVertexBuffer(_vertexBuffer);
            renderContext.GraphicsDevice.Indices = _indexBuffer;
            
            shader.LoadParameterSet(renderContext, effectParameterSet);
            foreach (var pass in shader.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                renderContext.GraphicsDevice.DrawIndexedPrimitives(
                    PrimitiveType.TriangleStrip,
                    0,
                    0,
                    2);
            }

            renderContext.World = oldWorld;
            renderContext.Projection = oldProjection;
            renderContext.View = oldView;

            if (destinations != null)
            {
                renderContext.PopRenderTarget();
            }
        }