diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs index d227c7c0..5c8bfa50 100644 --- a/Vocaluxe/Base/CBackgroundMusic.cs +++ b/Vocaluxe/Base/CBackgroundMusic.cs @@ -463,15 +463,17 @@ namespace Vocaluxe.Base if (_Video != -1) { float vtime; - CVideo.GetFrame(_Video, ref _CurrentVideoTexture, CSound.GetPosition(_CurrentMusicStream), out vtime); - if (_FadeTimer.ElapsedMilliseconds <= 3000L) - _CurrentVideoTexture.Color.A = _FadeTimer.ElapsedMilliseconds / 3000f; - else + if (CVideo.GetFrame(_Video, ref _CurrentVideoTexture, CSound.GetPosition(_CurrentMusicStream), out vtime)) { - _CurrentVideoTexture.Color.A = 1f; - _FadeTimer.Stop(); + if (_FadeTimer.ElapsedMilliseconds <= 3000L) + _CurrentVideoTexture.Color.A = _FadeTimer.ElapsedMilliseconds / 3000f; + else + { + _CurrentVideoTexture.Color.A = 1f; + _FadeTimer.Stop(); + } + return _CurrentVideoTexture; } - return _CurrentVideoTexture; } return null; } diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs index 6f377402..2acc4d35 100644 --- a/Vocaluxe/Base/CDraw.cs +++ b/Vocaluxe/Base/CDraw.cs @@ -160,9 +160,14 @@ namespace Vocaluxe.Base return _Draw.EnqueueTexture(w, h, data); } - public static bool UpdateTexture(CTexture texture, byte[] data) + public static bool UpdateTexture(CTexture texture, int w, int h, byte[] data) { - return _Draw.UpdateTexture(texture, data); + return _Draw.UpdateTexture(texture, w, h, data); + } + + public static bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data) + { + return _Draw.UpdateOrAddTexture(ref texture, w, h, data); } public static void RemoveTexture(ref CTexture texture) diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index 079fa61c..9d92cb2b 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -891,7 +891,7 @@ namespace Vocaluxe.Lib.Draw bmp2.Dispose(); } - CTexture texture = new CTexture(bmp.Width, bmp.Height, w, h,true); + CTexture texture = new CTexture(bmp.Width, bmp.Height, w, h, true); return _AddTexture(texture, w, data); } @@ -924,12 +924,12 @@ namespace Vocaluxe.Lib.Draw t = new Texture(_Device, texture.W2, texture.H2, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed); //Lock the texture and fill it with the data DataRectangle rect = t.LockRectangle(0, LockFlags.Discard); - int rowWidth = 4 * texture.W2; - for (int i = 0; i + rowWidth <= data.Length; i += 4 * w) + int rowWidth = 4 * w; + for (int i = 0; i + rowWidth <= data.Length; i += rowWidth) { - rect.Data.Write(data, i, 4 * w); - rect.Data.Position = rect.Data.Position - rowWidth; - rect.Data.Position += rect.Pitch; + rect.Data.Write(data, i, rowWidth); + //Go to next row + rect.Data.Position = rect.Data.Position - rowWidth + rect.Pitch; } t.UnlockRectangle(0); } @@ -969,27 +969,39 @@ namespace Vocaluxe.Lib.Draw /// Updates the data of a texture /// /// The texture to update + /// + /// /// A byte array containing the new texture's data /// True if succeeded - public bool UpdateTexture(CTexture texture, byte[] data) + public bool UpdateTexture(CTexture texture, int w, int h, byte[] data) { - if (!_TextureExists(texture)) + //Check if texture exists and extend matches + if (!_TextureExists(texture) || texture.UsedWidth != w || texture.UsedHeight != h) return false; lock (_MutexTexture) { DataRectangle rect = _D3DTextures[texture.Index].LockRectangle(0, LockFlags.Discard); - int w = texture.OrigSize.Width; - int rowWidth = 4 * texture.W2; - for (int i = 0; i + rowWidth <= data.Length; i += 4 * w) + int rowWidth = 4 * w; + for (int i = 0; i + rowWidth <= data.Length; i += rowWidth) { - rect.Data.Write(data, i, 4 * w); - rect.Data.Position = rect.Data.Position - rowWidth; - rect.Data.Position += rect.Pitch; + rect.Data.Write(data, i, rowWidth); + //Go to next row + rect.Data.Position = rect.Data.Position - rowWidth + rect.Pitch; } _D3DTextures[texture.Index].UnlockRectangle(0); } return true; } + + public bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data) + { + if (!UpdateTexture(texture, w, h, data)) + { + RemoveTexture(ref texture); + texture = AddTexture(w, h, data); + } + return true; + } #endregion updating /// @@ -1288,15 +1300,9 @@ namespace Vocaluxe.Lib.Draw CTexture texture; if (!_Textures.TryGetValue(q.Index, out texture)) continue; - if (q.Width == texture.OrigSize.Width && q.Height == texture.OrigSize.Height) - { - texture.W2 = _CheckForNextPowerOf2(texture.OrigSize.Width); - texture.H2 = _CheckForNextPowerOf2(texture.OrigSize.Height); - Texture t = _CreateTexture(texture, q.Width, q.Data); - _D3DTextures[q.Index] = t; - } - else - CLog.LogError("Wrong texture size in queue!"); + + Texture t = _CreateTexture(texture, q.Width, q.Data); + _D3DTextures[q.Index] = t; } } } diff --git a/Vocaluxe/Lib/Draw/CDrawWinForm.cs b/Vocaluxe/Lib/Draw/CDrawWinForm.cs index ca19a4fa..ff52c50d 100644 --- a/Vocaluxe/Lib/Draw/CDrawWinForm.cs +++ b/Vocaluxe/Lib/Draw/CDrawWinForm.cs @@ -398,7 +398,7 @@ namespace Vocaluxe.Lib.Draw } } - public bool UpdateTexture(CTexture texture, byte[] data) + public bool UpdateTexture(CTexture texture, int w, int h, byte[] data) { if (_TextureExists(texture)) { @@ -411,6 +411,16 @@ namespace Vocaluxe.Lib.Draw return false; } + public bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data) + { + if (!UpdateTexture(texture, w, h, data)) + { + RemoveTexture(ref texture); + texture = AddTexture(w, h, data); + } + return true; + } + public void DrawTexture(CTexture texture) { if (texture != null) diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 8dd43f54..57e93f9a 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -518,8 +518,8 @@ namespace Vocaluxe.Lib.Draw public void CopyScreen(ref CTexture texture) { - //Check for actual texture sizes! (W2/H2) as it may be up/downsized compared to OrigSize - if (!_TextureExists(texture) || texture.W2 != GetScreenWidth() || texture.H2 != GetScreenHeight()) + //Check for actual texture sizes as it may be downsized compared to OrigSize + if (!_TextureExists(texture) || texture.UsedWidth != GetScreenWidth() || texture.UsedHeight != GetScreenHeight()) { RemoveTexture(ref texture); texture = CopyScreen(); @@ -528,7 +528,7 @@ namespace Vocaluxe.Lib.Draw { GL.BindTexture(TextureTarget.Texture2D, texture.ID); - GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, 0, 0, texture.OrigSize.Width, texture.OrigSize.Height); + GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, 0, 0, texture.UsedWidth, texture.UsedHeight); GL.BindTexture(TextureTarget.Texture2D, 0); } @@ -831,9 +831,10 @@ namespace Vocaluxe.Lib.Draw #endregion adding #region updating - public bool UpdateTexture(CTexture texture, byte[] data) + public bool UpdateTexture(CTexture texture, int w, int h, byte[] data) { - if (!_TextureExists(texture)) + //Check if texture exists and extend matches + if (!_TextureExists(texture) || texture.UsedWidth != w || texture.UsedHeight != h) return false; if (_UsePBO) { @@ -845,7 +846,7 @@ namespace Vocaluxe.Lib.Draw GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer); GL.BindTexture(TextureTarget.Texture2D, texture.ID); - GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.OrigSize.Width, texture.OrigSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); + GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); GL.BindTexture(TextureTarget.Texture2D, 0); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); @@ -855,7 +856,7 @@ namespace Vocaluxe.Lib.Draw GL.BindTexture(TextureTarget.Texture2D, texture.ID); - GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.OrigSize.Width, texture.OrigSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data); + GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, data); //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge); //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge); @@ -869,6 +870,16 @@ namespace Vocaluxe.Lib.Draw return true; } + + public bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data) + { + if (!UpdateTexture(texture, w, h, data)) + { + RemoveTexture(ref texture); + texture = AddTexture(w, h, data); + } + return true; + } #endregion updating public void RemoveTexture(ref CTexture texture) @@ -1172,10 +1183,7 @@ namespace Vocaluxe.Lib.Draw if (!_Textures.TryGetValue(q.Index, out texture)) continue; - if (q.Width == texture.OrigSize.Width && q.Height == texture.OrigSize.Height) - _CreateTexture(texture, q.Width, q.Height, q.Data); - else - CLog.LogError("Wrong texture size in queue!"); + _CreateTexture(texture, q.Width, q.Height, q.Data); } } } diff --git a/Vocaluxe/Lib/Draw/IDraw.cs b/Vocaluxe/Lib/Draw/IDraw.cs index 9c8f2dd3..96a9df0b 100644 --- a/Vocaluxe/Lib/Draw/IDraw.cs +++ b/Vocaluxe/Lib/Draw/IDraw.cs @@ -43,7 +43,8 @@ namespace Vocaluxe.Lib.Draw CTexture AddTexture(Bitmap bitmap); CTexture AddTexture(int w, int h, byte[] data); CTexture EnqueueTexture(int w, int h, byte[] data); - bool UpdateTexture(CTexture texture, byte[] data); + bool UpdateTexture(CTexture texture, int w, int h, byte[] data); + bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data); void RemoveTexture(ref CTexture texture); // Basic Draw Methods diff --git a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs index fb5c2951..003f1a09 100644 --- a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs +++ b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs @@ -323,7 +323,7 @@ namespace Vocaluxe.Lib.Video _UploadNewFrame(ref frame); //EventDecode.Set(); - return true; + return frame != null; } if (Math.Abs(_SetTime - time) > float.Epsilon) @@ -335,7 +335,7 @@ namespace Vocaluxe.Lib.Video _UploadNewFrame(ref frame); videoTime = _CurrentVideoTime; //EventDecode.Set(); - return true; + return frame != null; } return false; } @@ -661,13 +661,7 @@ namespace Vocaluxe.Lib.Video if (num >= 0) { - if (frame == null || _Width != frame.OrigSize.Width || _Height != frame.OrigSize.Height) - { - CDraw.RemoveTexture(ref frame); - frame = CDraw.AddTexture(_Width, _Height, _FrameBuffer[num].Data); - } - else - CDraw.UpdateTexture(frame, _FrameBuffer[num].Data); + CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _FrameBuffer[num].Data); lock (_MutexSyncSignals) { diff --git a/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs b/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs index 199b82d5..f37b0dc8 100644 --- a/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs +++ b/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs @@ -84,7 +84,7 @@ namespace Vocaluxe.Lib.Video videoTime = managedFrame.Videotime; _UploadNewFrame(ref frame, ref managedFrame.Buffer, managedFrame.Width, managedFrame.Height); - return true; + return frame != null; } public bool Skip(int streamID, float start, float gap) @@ -121,13 +121,7 @@ namespace Vocaluxe.Lib.Video { if (data == null) return; - if (frame == null || width != frame.OrigSize.Width || height != frame.OrigSize.Height || data.Length == 0) - { - CDraw.RemoveTexture(ref frame); - frame = CDraw.AddTexture(width, height, data); - } - else - CDraw.UpdateTexture(frame, data); + CDraw.UpdateOrAddTexture(ref frame, width, height, data); data = null; } } diff --git a/Vocaluxe/Lib/Video/IVideoDecoder.cs b/Vocaluxe/Lib/Video/IVideoDecoder.cs index ded5d7a5..dcf1120e 100644 --- a/Vocaluxe/Lib/Video/IVideoDecoder.cs +++ b/Vocaluxe/Lib/Video/IVideoDecoder.cs @@ -41,7 +41,17 @@ namespace Vocaluxe.Lib.Video int GetNumStreams(); float GetLength(int streamID); + + /// + /// + /// + /// + /// + /// + /// + /// True if frame is valid bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime); + bool Skip(int streamID, float start, float gap); void SetLoop(int streamID, bool loop); void Pause(int streamID); diff --git a/Vocaluxe/Lib/Webcam/CAForgeNet.cs b/Vocaluxe/Lib/Webcam/CAForgeNet.cs index 1413cd73..2d056ac3 100644 --- a/Vocaluxe/Lib/Webcam/CAForgeNet.cs +++ b/Vocaluxe/Lib/Webcam/CAForgeNet.cs @@ -41,29 +41,20 @@ namespace Vocaluxe.Lib.Webcam public void Close() { - if (_Webcam != null) - { - _Webcam.SignalToStop(); - _Webcam.WaitForStop(); - _Webcam.NewFrame -= _OnFrame; - _Data = new byte[1]; - } + if (_Webcam == null) + return; + _Webcam.SignalToStop(); + _Webcam.WaitForStop(); + _Webcam.NewFrame -= _OnFrame; + _Data = new byte[1]; } public bool GetFrame(ref CTexture frame) { - if (_Webcam != null && _Width > 0 && _Height > 0 && _Data.Length == _Width * _Height * 4) + lock (_MutexData) { - lock (_MutexData) - { - if (frame == null || _Width != frame.OrigSize.Width || _Height != frame.OrigSize.Height) - { - CDraw.RemoveTexture(ref frame); - frame = CDraw.AddTexture(_Width, _Height, _Data); - } - else - CDraw.UpdateTexture(frame, _Data); - } + if (_Webcam != null && _Width > 0 && _Height > 0 && _Data.Length == _Width * _Height * 4) + CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _Data); } return false; } @@ -114,19 +105,18 @@ namespace Vocaluxe.Lib.Webcam private void _OnFrame(object sender, NewFrameEventArgs e) { - if (!_Paused) + if (_Paused) + return; + lock (_MutexData) { - lock (_MutexData) - { - if (_Width != e.Frame.Width || _Height != e.Frame.Height || _Data.Length != e.Frame.Width * e.Frame.Height * 4) - _Data = new byte[4 * e.Frame.Width * e.Frame.Height]; + if (_Width != e.Frame.Width || _Height != e.Frame.Height || _Data.Length != e.Frame.Width * e.Frame.Height * 4) + _Data = new byte[4 * e.Frame.Width * e.Frame.Height]; - _Width = e.Frame.Width; - _Height = e.Frame.Height; - BitmapData bitmapdata = e.Frame.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); - Marshal.Copy(bitmapdata.Scan0, _Data, 0, _Data.Length); - e.Frame.UnlockBits(bitmapdata); - } + _Width = e.Frame.Width; + _Height = e.Frame.Height; + BitmapData bitmapdata = e.Frame.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + Marshal.Copy(bitmapdata.Scan0, _Data, 0, _Data.Length); + e.Frame.UnlockBits(bitmapdata); } } @@ -138,14 +128,13 @@ namespace Vocaluxe.Lib.Webcam public void Start() { - if (_Webcam != null) - { - _Webcam.NewFrame -= _OnFrame; - //Subscribe to NewFrame event - _Webcam.NewFrame += _OnFrame; - _Webcam.Start(); - _Paused = false; - } + if (_Webcam == null) + return; + _Webcam.NewFrame -= _OnFrame; + //Subscribe to NewFrame event + _Webcam.NewFrame += _OnFrame; + _Webcam.Start(); + _Paused = false; } public void Stop() diff --git a/Vocaluxe/Screens/CScreenCredits.cs b/Vocaluxe/Screens/CScreenCredits.cs index 861adea3..226e21ee 100644 --- a/Vocaluxe/Screens/CScreenCredits.cs +++ b/Vocaluxe/Screens/CScreenCredits.cs @@ -213,7 +213,7 @@ namespace Vocaluxe.Screens if (paragraph[e] == null) continue; string newLine = " " + paragraph[e]; - CText text = GetNewText(75, lastY, -2, 30, -1, EAlignment.Left, EStyle.Bold, "Outline", new SColorF(1, 1, 1, 1), line); + CText text = GetNewText(75, lastY, -2, 25, -1, EAlignment.Left, EStyle.Bold, "Outline", new SColorF(1, 1, 1, 1), line); if (CFonts.GetTextBounds(text).Width < (CSettings.RenderW - 220)) { line += newLine; diff --git a/VocaluxeLib/Draw/CTexture.cs b/VocaluxeLib/Draw/CTexture.cs index f3823112..841a4c55 100644 --- a/VocaluxeLib/Draw/CTexture.cs +++ b/VocaluxeLib/Draw/CTexture.cs @@ -28,7 +28,7 @@ namespace VocaluxeLib.Draw public SColorF Color = new SColorF(1f, 1f, 1f, 1f); private int _W2, _H2; - private bool _UseFullTexture; + private readonly bool _UseFullTexture; /// /// Internal texture width (on device), a power of 2 if necessary /// @@ -38,7 +38,9 @@ namespace VocaluxeLib.Draw set { _W2 = value; - if (!_UseFullTexture) + if (_UseFullTexture) + WidthRatio = 1; + else WidthRatio = (float)OrigSize.Width / _W2; } } @@ -51,7 +53,9 @@ namespace VocaluxeLib.Draw set { _H2 = value; - if (!_UseFullTexture) + if (_UseFullTexture) + HeightRatio = 1; + else HeightRatio = (float)OrigSize.Height / _H2; } } @@ -65,6 +69,22 @@ namespace VocaluxeLib.Draw /// public float HeightRatio { get; private set; } + /// + /// Actual texture space used in x direction + /// + public int UsedWidth + { + get { return (int)(_W2 * WidthRatio); } + } + + /// + /// Actual texture space used in y direction + /// + public int UsedHeight + { + get { return (int)(_H2 * HeightRatio); } + } + /* /// /// Internal use. Specifies if full texture memory should be used diff --git a/VocaluxeLib/Menu/CBackground.cs b/VocaluxeLib/Menu/CBackground.cs index 21e6814d..f86041f0 100644 --- a/VocaluxeLib/Menu/CBackground.cs +++ b/VocaluxeLib/Menu/CBackground.cs @@ -204,7 +204,7 @@ namespace VocaluxeLib.Menu private bool _DrawTexture() { CTexture texture = CBase.Theme.GetSkinTexture(_Theme.TextureName, _PartyModeID); - if (texture.OrigSize.Height > 1) + if (texture != null) { RectangleF bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH()); RectangleF rect; @@ -219,7 +219,7 @@ namespace VocaluxeLib.Menu private bool _DrawVideo() { CTexture videoTexture = CBase.Theme.GetSkinVideoTexture(_Theme.VideoName, _PartyModeID); - if (videoTexture.OrigSize.Height > 1) + if (videoTexture != null) { RectangleF bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH()); RectangleF rect; @@ -234,7 +234,7 @@ namespace VocaluxeLib.Menu private bool _DrawBackgroundMusicVideo() { CTexture videoTexture = CBase.BackgroundMusic.GetVideoTexture(); - if (videoTexture.OrigSize.Height > 1) + if (videoTexture != null) { RectangleF bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH()); RectangleF rect; diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs index 5b073b48..dc6fea65 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs @@ -438,19 +438,21 @@ namespace VocaluxeLib.Menu.SongMenu if (_Actsong != _PreviewSelected) _SelectSong(_PreviewSelected); - if (_Streams.Count > 0 && _Video != -1) + if (_Streams.Count <= 0 || _Video == -1) + return; + + if (CBase.Video.IsFinished(_Video) || CBase.Sound.IsFinished(_Actsongstream)) { - if (CBase.Video.IsFinished(_Video) || CBase.Sound.IsFinished(_Actsongstream)) - { - CBase.Video.Close(_Video); - _Video = -1; - return; - } + CBase.Video.Close(_Video); + _Video = -1; + return; + } - float time = CBase.Sound.GetPosition(_Actsongstream); + float time = CBase.Sound.GetPosition(_Actsongstream); - float vtime; - CBase.Video.GetFrame(_Video, ref _Vidtex, time, out vtime); + float vtime; + if (CBase.Video.GetFrame(_Video, ref _Vidtex, time, out vtime)) + { if (_VideoFadeTimer.ElapsedMilliseconds <= 3000L) _Vidtex.Color.A = _VideoFadeTimer.ElapsedMilliseconds / 3000f; else