public void DrawOverlay(Surface targetSurface) { Texture subTexture; Subtitle currentSubtitle; lock (_syncObj) { currentSubtitle = _currentSubtitle; subTexture = _subTexture; // Available sub is not due if (currentSubtitle == null || !currentSubtitle.ShouldDraw) return; if (targetSurface == null || targetSurface.Disposed || subTexture == null) { if (_drawCount > 0) ServiceRegistration.Get<ILogger>().Debug("Draw count for last sub: {0}", _drawCount); _drawCount = 0; return; } _drawCount++; } try { if (!subTexture.Disposed) { // TemporaryRenderTarget changes RenderTarget to texture and restores settings when done (Dispose) using (new TemporaryRenderTarget(targetSurface)) using (TemporaryRenderState temporaryRenderState = new TemporaryRenderState()) using (Sprite sprite = new Sprite(_device)) { sprite.Begin(SpriteFlags.AlphaBlend); // No alpha test here, allow all values temporaryRenderState.SetTemporaryRenderState(RenderState.AlphaTestEnable, 0); // Use the SourceAlpha channel and InverseSourceAlpha for destination temporaryRenderState.SetTemporaryRenderState(RenderState.BlendOperation, (int) BlendOperation.Add); temporaryRenderState.SetTemporaryRenderState(RenderState.SourceBlend, (int) Blend.SourceAlpha); temporaryRenderState.SetTemporaryRenderState(RenderState.DestinationBlend, (int) Blend.InverseSourceAlpha); // Check the target texture dimensions and adjust scaling and translation SurfaceDescription desc = targetSurface.Description; Matrix transform = Matrix.Identity; transform *= Matrix.Translation(currentSubtitle.HorizontalPosition, currentSubtitle.FirstScanLine, 0); // Subtitle could be smaller for 16:9 anamorphic video (subtitle width: 720, video texture: 1024) // then we need to scale the subtitle width also. if (currentSubtitle.ScreenWidth != desc.Width) transform *= Matrix.Scaling((float) desc.Width / currentSubtitle.ScreenWidth, 1, 1); sprite.Transform = transform; sprite.Draw(subTexture, Color.White); sprite.End(); } } } catch (Exception ex) { ServiceRegistration.Get<ILogger>().Debug("Error in DrawOverlay", ex); } if (_onTextureInvalidated != null) _onTextureInvalidated(); }
public void DrawOverlay(Texture targetTexture) { Subtitle currentSubtitle; lock (_syncObj) { currentSubtitle = _subtitles.ToList().FirstOrDefault(s => s.ShouldDraw); if (currentSubtitle == null) return; if (targetTexture == null || targetTexture.IsDisposed || currentSubtitle.SubTexture == null || currentSubtitle.SubTexture.IsDisposed) { if (_drawCount > 0) ServiceRegistration.Get<ILogger>().Debug("Draw count for last sub: {0}", _drawCount); _drawCount = 0; return; } _drawCount++; } try { // TemporaryRenderTarget changes RenderTarget to texture and restores settings when done (Dispose) using (new TemporaryRenderTarget(targetTexture)) using (TemporaryRenderState temporaryRenderState = new TemporaryRenderState()) using (Sprite sprite = new Sprite(_device)) { sprite.Begin(SpriteFlags.AlphaBlend); // No alpha test here, allow all values temporaryRenderState.SetTemporaryRenderState(RenderState.AlphaTestEnable, 0); // Use the SourceAlpha channel and InverseSourceAlpha for destination temporaryRenderState.SetTemporaryRenderState(RenderState.BlendOperation, (int)BlendOperation.Add); temporaryRenderState.SetTemporaryRenderState(RenderState.SourceBlend, (int)Blend.SourceAlpha); temporaryRenderState.SetTemporaryRenderState(RenderState.DestinationBlend, (int)Blend.InverseSourceAlpha); // Check the target texture dimensions and adjust scaling and translation SurfaceDescription desc = targetTexture.GetLevelDescription(0); Matrix transform = Matrix.Identity; // Position subtitle and scale it to match video frame size, if required transform *= Matrix.Translation(currentSubtitle.HorizontalPosition, currentSubtitle.FirstScanLine, 0); if (currentSubtitle.ScreenWidth != desc.Width || currentSubtitle.ScreenHeight != desc.Height) { var factorW = (float)desc.Width / currentSubtitle.ScreenWidth; var factorH = (float)desc.Height / currentSubtitle.ScreenHeight; transform *= Matrix.Scaling(factorW, factorH, 1); } sprite.Transform = transform; sprite.Draw(currentSubtitle.SubTexture, SharpDX.Color.White); sprite.End(); } if (_onTextureInvalidated != null) _onTextureInvalidated(); } catch (Exception ex) { ServiceRegistration.Get<ILogger>().Debug("Error in DrawOverlay", ex); } }