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); }
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(); } }