public void Render() { if (_player == null) { return; } lock (_subtitleLock) { if (_clearOnNextRender) { //Log.Debug("SubtitleRenderer: clearOnNextRender"); _clearOnNextRender = false; if (_subTexture != null) { _subTexture.SafeDispose(); } _subTexture = null; _currentSubtitle = null; } if (_renderSubtitles == false) { return; } // ugly temp! bool timeForNext = false; if (_subtitles.Count > 0) { Subtitle next = _subtitles.First.Value; if (next.presentTime <= _player.StreamPosition) { timeForNext = true; } } _posOnLastRender = _player.StreamPosition; // Check for subtitle if we dont have one currently or if the current one is beyond its timeout if (_currentSubtitle == null || _currentSubtitle.presentTime + _currentSubtitle.timeOut <= _player.StreamPosition || timeForNext) { //Log.Debug("-Current position: "); if (_currentSubtitle != null && !timeForNext) { //Log.Debug("-Current subtitle : " + currentSubtitle.ToString() + " time out expired"); _currentSubtitle = null; } if (timeForNext) { //if (currentSubtitle != null) Log.Debug("-Current subtitle : " + currentSubtitle.ToString() + " TIME FOR NEXT!"); } Subtitle next = null; while (_subtitles.Count > 0) { next = _subtitles.First.Value; //Log.Debug("-next from queue: " + next.ToString()); // if the next should be displayed now or previously if (next.presentTime <= _player.StreamPosition) { // remove from queue _subtitles.RemoveFirst(); // if it is not too late for this sub to be displayed, break // otherwise continue if (next.presentTime + next.timeOut >= _player.StreamPosition) { _currentSubtitle = next; break; } } // next wants to be displayed in the future so break else { //Log.Debug("-next is in the future"); break; } } // if currentSubtitle is non-null we have a new subtitle if (_currentSubtitle != null) { SetSubtitle(_currentSubtitle); } else { return; } } VertexFormats vertexFormat = GUIGraphicsContext.DX9Device.VertexFormat; try { int wx = 0, wy = 0, wwidth = 0, wheight = 0; float rationW = 1, rationH = 1; Rectangle src, dst; VMR9Util.g_vmr9.GetVideoWindows(out src, out dst); rationH = dst.Height / (float)_currentSubtitle.screenHeight; rationW = dst.Width / (float)_currentSubtitle.screenWidth; wx = dst.X + (int)(rationW * (float)_currentSubtitle.horizontalPosition); wy = dst.Y + (int)(rationH * (float)_currentSubtitle.firstScanLine); wwidth = (int)((float)_currentSubtitle.width * rationW); wheight = (int)((float)_currentSubtitle.height * rationH); // make sure the vertex buffer is ready and correct for the coordinates CreateVertexBuffer(wx, wy, wwidth, wheight); // Log.Debug("Subtitle render target: wx = {0} wy = {1} ww = {2} wh = {3}", wx, wy, wwidth, wheight); // enable alpha blending so that the subtitle is rendered with transparent background DXNative.FontEngineSetRenderState((int)D3DRENDERSTATETYPE.D3DRS_ALPHABLENDENABLE, 1); // Make sure D3D objects haven't been disposed for some reason. This would cause // an access violation on native side, causing Skin Engine to halt rendering if (!_subTexture.Disposed && !_vertexBuffer.Disposed) { GUIGraphicsContext.DX9Device.SetStreamSource(0, _vertexBuffer, 0); GUIGraphicsContext.DX9Device.SetTexture(0, _subTexture); GUIGraphicsContext.DX9Device.VertexFormat = CustomVertex.TransformedTextured.Format; GUIGraphicsContext.DX9Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); } else { Log.Debug("Subtitle renderer: D3D resource was disposed! Not trying to render the texture"); } } catch (Exception e) { Log.Error(e); } try { // Restore device settings GUIGraphicsContext.DX9Device.SetTexture(0, null); GUIGraphicsContext.DX9Device.VertexFormat = vertexFormat; } catch (Exception e) { Log.Error(e); } } // end of lock (subtitle) }
public void Render() { lock (_OSDLock) { // Store current settings so they can be restored when we are done VertexFormats vertexFormat = GUIGraphicsContext.DX9Device.VertexFormat; try { if (_OSDTexture == null || _OSDTexture.Disposed) { return; } int wx = 0, wy = 0, wwidth = 0, wheight = 0; if (GUIGraphicsContext.IsFullScreenVideo) { wheight = PlaneScene.DestRect.Height; wwidth = PlaneScene.DestRect.Width; wx = GUIGraphicsContext.OverScanLeft; wy = GUIGraphicsContext.OverScanTop; if (PlaneScene.DestRect.X == 0 || PlaneScene.DestRect.Y == 0) { wx += PlaneScene.DestRect.X; wy += PlaneScene.DestRect.Y; } } else // Video overlay { wheight = GUIGraphicsContext.VideoWindow.Height; wwidth = GUIGraphicsContext.VideoWindow.Width; wx = GUIGraphicsContext.VideoWindow.Right - (GUIGraphicsContext.VideoWindow.Width); wy = GUIGraphicsContext.VideoWindow.Top; } DXNative.FontEngineSetRenderState((int)D3DRENDERSTATETYPE.D3DRS_ALPHABLENDENABLE, 1); CreateVertexBuffer(wx, wy, wwidth, wheight); // Make sure D3D objects haven't been disposed for some reason. This would cause // an access violation on native side, causing Skin Engine to halt rendering if (!_OSDTexture.Disposed && !_vertexBuffer.Disposed) { GUIGraphicsContext.DX9Device.SetStreamSource(0, _vertexBuffer, 0); GUIGraphicsContext.DX9Device.SetTexture(0, _OSDTexture); GUIGraphicsContext.DX9Device.VertexFormat = CustomVertex.TransformedTextured.Format; GUIGraphicsContext.DX9Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); } else { Log.Debug("OSD renderer: D3D resource was disposed! Not trying to render the texture"); } } catch (Exception e) { Log.Error(e); } try { // Restore device settings GUIGraphicsContext.DX9Device.SetTexture(0, null); GUIGraphicsContext.DX9Device.VertexFormat = vertexFormat; } catch (Exception e) { Log.Error(e); } } }
private void DrawTexture(uint texAddr, long lColorDiffuse) { if (texAddr == 0) { return; } unsafe { IntPtr ptr = new IntPtr(texAddr); DXNative.FontEngineSetTexture(ptr.ToPointer()); DXNative.FontEngineSetSamplerState(0, (int)D3DSAMPLERSTATETYPE.D3DSAMP_MINFILTER, (int)D3DTEXTUREFILTERTYPE.D3DTEXF_LINEAR); DXNative.FontEngineSetSamplerState(0, (int)D3DSAMPLERSTATETYPE.D3DSAMP_MAGFILTER, (int)D3DTEXTUREFILTERTYPE.D3DTEXF_LINEAR); DXNative.FontEngineSetSamplerState(0, (int)D3DSAMPLERSTATETYPE.D3DSAMP_MIPFILTER, (int)D3DTEXTUREFILTERTYPE.D3DTEXF_LINEAR); DXNative.FontEngineSetSamplerState(0, (int)D3DSAMPLERSTATETYPE.D3DSAMP_ADDRESSU, (int)D3DTEXTUREADDRESS.D3DTADDRESS_CLAMP); DXNative.FontEngineSetSamplerState(0, (int)D3DSAMPLERSTATETYPE.D3DSAMP_ADDRESSV, (int)D3DTEXTUREADDRESS.D3DTADDRESS_CLAMP); GUIGraphicsContext.DX9Device.VertexFormat = CustomVertex.TransformedColoredTextured.Format; DXNative.FontEngineSetRenderState((int)D3DRENDERSTATETYPE.D3DRS_ALPHABLENDENABLE, 0); if (_useNonLinearStretch) { //draw/stretch each partition separately according to NLS table //top and bottom remain untouched. //left and right start from the left of the rect. int srcLeft = _sourceRect.Left; float srcLeftFloat = (float)_sourceRect.Left; int srcRight = srcLeft; float srcRightFloat = (float)srcLeft; int dstLeft = _destinationRect.Left; float dstLeftFloat = _destinationRect.Left; int dstRight = dstLeft; float dstRightFloat = (float)dstLeft; for (int i = 0; i < nlsSourcePartitioning.Length; i++) { //this left is the previous right srcLeft = srcRight; dstLeft = dstRight; srcLeftFloat = srcRightFloat; dstLeftFloat = dstRightFloat; //calculate new right srcRightFloat = srcLeftFloat + (int)(nlsSourcePartitioning[i] * (float)_sourceRect.Width / 100.0f); dstRightFloat = dstLeftFloat + (int)(nlsDestPartitioning[i] * (float)_destinationRect.Width / 100.0f); srcRight = (int)srcRightFloat; dstRight = (int)dstRightFloat; DrawTextureSegment(_vertexBuffers[i], srcLeft, _sourceRect.Top, srcRight - srcLeft, _sourceRect.Height, dstLeft, _destinationRect.Top, dstRight - dstLeft, _destinationRect.Height, lColorDiffuse); } } else { DrawTextureSegment(_vertexBuffers[0], _sourceRect.Left, _sourceRect.Top, _sourceRect.Width, _sourceRect.Height, _destinationRect.Left, _destinationRect.Top, _destinationRect.Width, _destinationRect.Height, lColorDiffuse); } // unset the texture and palette or the texture caching crashes because the runtime still has a reference GUIGraphicsContext.DX9Device.SetTexture(0, null); } }