diff --git a/Vocaluxe/Base/CDataBase.cs b/Vocaluxe/Base/CDataBase.cs index daa25460..e1040bf8 100644 --- a/Vocaluxe/Base/CDataBase.cs +++ b/Vocaluxe/Base/CDataBase.cs @@ -1008,7 +1008,7 @@ namespace Vocaluxe.Base result = true; reader.Read(); byte[] data = GetBytes(reader); - tex = CDraw.AddTexture(w, h, ref data); + tex = CDraw.QuequeTexture(w, h, ref data); } } else @@ -1053,7 +1053,7 @@ namespace Vocaluxe.Base Graphics g = Graphics.FromImage(bmp); g.DrawImage(origin, new Rectangle(0, 0, w, h)); g.Dispose(); - tex = CDraw.AddTexture(bmp); + byte[] data = new byte[w * h * 4]; BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); @@ -1061,6 +1061,8 @@ namespace Vocaluxe.Base bmp.UnlockBits(bmp_data); bmp.Dispose(); + tex = CDraw.QuequeTexture(w, h, ref data); + command.CommandText = "INSERT INTO Cover (Path, width, height) " + "VALUES (@path, " + w.ToString() + ", " + h.ToString() + ")"; command.Parameters.Add("@path", System.Data.DbType.String, 0).Value = CoverPath; diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs index 6c0e0684..7c13e322 100644 --- a/Vocaluxe/Base/CDraw.cs +++ b/Vocaluxe/Base/CDraw.cs @@ -156,6 +156,11 @@ namespace Vocaluxe.Base return _Draw.AddTexture(W, H, ref Data); } + public static STexture QuequeTexture(int W, int H, ref byte[] Data) + { + return _Draw.QuequeTexture(W, H, ref Data); + } + public static bool UpdateTexture(ref STexture Texture, ref byte[] Data) { return _Draw.UpdateTexture(ref Texture, ref Data); diff --git a/Vocaluxe/Base/CFont.cs b/Vocaluxe/Base/CFont.cs index 16eb4208..fbf5d97a 100644 --- a/Vocaluxe/Base/CFont.cs +++ b/Vocaluxe/Base/CFont.cs @@ -133,7 +133,7 @@ namespace Vocaluxe.Base sizeB = TextRenderer.MeasureText(g, chr.ToString(), fo, new Size(int.MaxValue, int.MaxValue), flags); //size = g.MeasureString(chr.ToString(), fo); float h_style = sizeB.Height; - + g.Dispose(); return h_normal / h_style; } } diff --git a/Vocaluxe/Base/CSongs.cs b/Vocaluxe/Base/CSongs.cs index c9d4d71d..67a55e83 100644 --- a/Vocaluxe/Base/CSongs.cs +++ b/Vocaluxe/Base/CSongs.cs @@ -826,11 +826,32 @@ namespace Vocaluxe.Base CLog.StopBenchmark(2, "Sort Songs"); Category = -1; _SongsLoaded = true; + + if (CConfig.Renderer == ERenderer.TR_CONFIG_OPENGL) + { + CLog.StartBenchmark(2, "Load Cover"); + for (int i = 0; i < _Songs.Count; i++) + { + CSong song = _Songs[i]; + + song.ReadNotes(); + STexture texture = song.CoverTextureSmall; + song.CoverTextureBig = texture; + _CoverLoadIndex++; + } + + _CoverLoaded = true; + CDataBase.CommitCovers(); + CLog.StopBenchmark(2, "Load Cover"); + } CLog.StopBenchmark(1, "Load Songs "); } public static void LoadCover(long WaitTime, int NumLoads) { + if (CConfig.Renderer == ERenderer.TR_CONFIG_OPENGL) + return; //should be removed as soon as the other renderer are ready for queque + if (!SongsLoaded) return; diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index 851b3028..d4e7e1f3 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -625,6 +625,11 @@ namespace Vocaluxe.Lib.Draw return AddTexture(W, H , ref PointerData); } + public STexture QuequeTexture(int W, int H, ref byte[] Data) + { + return AddTexture(W, H, ref Data); + } + public STexture AddTexture(int W, int H, ref byte[] Data) { STexture texture = new STexture(-1); diff --git a/Vocaluxe/Lib/Draw/CDrawWinForm.cs b/Vocaluxe/Lib/Draw/CDrawWinForm.cs index 254763d9..702fcc57 100644 --- a/Vocaluxe/Lib/Draw/CDrawWinForm.cs +++ b/Vocaluxe/Lib/Draw/CDrawWinForm.cs @@ -400,6 +400,11 @@ namespace Vocaluxe.Lib.Draw return new STexture(-1); } + public STexture QuequeTexture(int W, int H, ref byte[] Data) + { + return AddTexture(W, H, ref Data); + } + public STexture AddTexture(int W, int H, ref byte[] Data) { Bitmap bmp = new Bitmap(W, H); diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 0552995e..ae42fcb7 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -18,14 +18,21 @@ using Vocaluxe.Menu; namespace Vocaluxe.Lib.Draw { - public struct SClientRect + struct SClientRect { public Point location; public int width; public int height; }; - + struct STextureQueque + { + public int ID; + public int width; + public int height; + public byte[] data; + } + class COpenGL : Form, IDraw { #region private vars @@ -40,14 +47,18 @@ namespace Vocaluxe.Lib.Draw private bool _fullscreen = false; private List _Textures; + private List _IDs; private List _GLList; + private List _Queque; + + private Object MutexTexture = new Object(); private int h = 1; private int w = 1; private int y = 0; private int x = 0; - private bool _UsePBO = true; + private bool _UsePBO = false; #endregion private vars @@ -57,6 +68,13 @@ namespace Vocaluxe.Lib.Draw _Textures = new List(); _GLList = new List(); + _Queque = new List(); + _IDs = new List(); + + for (int i = 1; i < 1000000; i++) + { + _IDs.Add(i); + } //Check AA Mode CConfig.AAMode = (EAntiAliasingModes)CheckAntiAliasingMode((int)CConfig.AAMode); @@ -454,6 +472,8 @@ namespace Vocaluxe.Lib.Draw if ((CSettings.bFullScreen && !_fullscreen) || (!CSettings.bFullScreen && _fullscreen)) ToggleFullScreen(); + CheckQueque(); + if (CTime.IsRunning()) delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds()); @@ -513,7 +533,7 @@ namespace Vocaluxe.Lib.Draw int id = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, id); - texture.index = id; + texture.ID = id; texture.width = w; texture.height = h; @@ -537,21 +557,27 @@ namespace Vocaluxe.Lib.Draw // Add to Texture List texture.color = new SColorF(1f, 1f, 1f, 1f); texture.rect = new SRectF(0f, 0f, texture.width, texture.height, 0f); - _Textures.Add(texture); + + lock (MutexTexture) + { + texture.index = _IDs[0]; + _IDs.RemoveAt(0); + _Textures.Add(texture); + } return texture; } public void CopyScreen(ref STexture Texture) { - if (!_TextureExists(Texture) || (Texture.width != GetScreenWidth()) || (Texture.height != GetScreenHeight())) + if (!_TextureExists(ref Texture) || (Texture.width != GetScreenWidth()) || (Texture.height != GetScreenHeight())) { RemoveTexture(ref Texture); Texture = CopyScreen(); } else { - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, 0, 0, (int)Texture.width, (int)Texture.height); @@ -658,10 +684,6 @@ namespace Vocaluxe.Lib.Draw if (bmp.Height == 0 || bmp.Width == 0) return texture; - int id = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, id); - texture.index = id; - int MaxSize; switch (CConfig.TextureQuality) { @@ -700,6 +722,10 @@ namespace Vocaluxe.Lib.Draw h = MaxSize; } + int id = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2D, id); + texture.ID = id; + texture.width = w; texture.height = h; @@ -711,7 +737,8 @@ namespace Vocaluxe.Lib.Draw g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.DrawImage(bmp, new Rectangle(0, 0, bmp2.Width, bmp2.Height)); - + g.Dispose(); + texture.width_ratio = 1f; texture.height_ratio = 1f; @@ -742,6 +769,12 @@ namespace Vocaluxe.Lib.Draw texture.color = new SColorF(1f, 1f, 1f, 1f); texture.rect = new SRectF(0f, 0f, texture.width, texture.height, 0f); texture.TexturePath = String.Empty; + + lock (MutexTexture) + { + texture.index = _IDs[0]; + _IDs.RemoveAt(0); + } _Textures.Add(texture); return texture; @@ -768,7 +801,7 @@ namespace Vocaluxe.Lib.Draw int id = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, id); - texture.index = id; + texture.ID = id; texture.width = W; texture.height = H; @@ -801,6 +834,12 @@ namespace Vocaluxe.Lib.Draw texture.color = new SColorF(1f, 1f, 1f, 1f); texture.rect = new SRectF(0f, 0f, texture.width, texture.height, 0f); texture.TexturePath = String.Empty; + + lock (MutexTexture) + { + texture.index = _IDs[0]; + _IDs.RemoveAt(0); + } _Textures.Add(texture); return texture; @@ -828,7 +867,7 @@ namespace Vocaluxe.Lib.Draw int id = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, id); - texture.index = id; + texture.ID = id; texture.width = W; texture.height = H; @@ -861,14 +900,41 @@ namespace Vocaluxe.Lib.Draw texture.color = new SColorF(1f, 1f, 1f, 1f); texture.rect = new SRectF(0f, 0f, texture.width, texture.height, 0f); texture.TexturePath = String.Empty; + + lock (MutexTexture) + { + texture.index = _IDs[0]; + _IDs.RemoveAt(0); + } _Textures.Add(texture); return texture; } + public STexture QuequeTexture(int W, int H, ref byte[] Data) + { + STexture texture = new STexture(-1); + STextureQueque queque = new STextureQueque(); + + queque.data = Data; + queque.height = H; + queque.width = W; + + lock (MutexTexture) + { + texture.index = _IDs[0]; + _IDs.RemoveAt(0); + queque.ID = texture.index; + _Queque.Add(queque); + _Textures.Add(texture); + } + + return texture; + } + public bool UpdateTexture(ref STexture Texture, IntPtr Data) { - if (_TextureExists(Texture)) + if (_TextureExists(ref Texture)) { if (_UsePBO) { @@ -884,7 +950,7 @@ namespace Vocaluxe.Lib.Draw GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer); - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, (int)Texture.width, (int)Texture.height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); @@ -899,7 +965,7 @@ namespace Vocaluxe.Lib.Draw } } - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, (int)Texture.width, (int)Texture.height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, Data); @@ -923,7 +989,7 @@ namespace Vocaluxe.Lib.Draw public bool UpdateTexture(ref STexture Texture, ref byte[] Data) { - if (_TextureExists(Texture)) + if (_TextureExists(ref Texture)) { if (_UsePBO) { @@ -936,7 +1002,7 @@ namespace Vocaluxe.Lib.Draw GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer); - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, (int)Texture.width, (int)Texture.height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); @@ -952,7 +1018,7 @@ namespace Vocaluxe.Lib.Draw } } - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, (int)Texture.width, (int)Texture.height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, Data); @@ -978,30 +1044,41 @@ namespace Vocaluxe.Lib.Draw { if ((Texture.index > 0) && (_Textures.Count > 0)) { - for (int i = 0; i < _Textures.Count; i++) - { - if (_Textures[i].index == Texture.index) + lock (MutexTexture) + { + for (int i = 0; i < _Textures.Count; i++) { - GL.DeleteTexture(Texture.index); - if (Texture.PBO > 0) - GL.DeleteBuffers(1, ref Texture.PBO); - _Textures.RemoveAt(i); - Texture.index = -1; - break; + if (_Textures[i].index == Texture.index) + { + _IDs.Add(Texture.index); + + GL.DeleteTexture(Texture.ID); + if (Texture.PBO > 0) + GL.DeleteBuffers(1, ref Texture.PBO); + _Textures.RemoveAt(i); + Texture.index = -1; + Texture.ID = -1; + break; + } } } } } - private bool _TextureExists(STexture Texture) + private bool _TextureExists(ref STexture Texture) { - if ((Texture.index > 0) && (_Textures.Count > 0)) + lock (MutexTexture) { for (int i = 0; i < _Textures.Count; i++) { - if (_Textures[i].index == Texture.index) + if (Texture.index == _Textures[i].index) { - return true; + if (_Textures[i].ID > 0) + { + Texture = _Textures[i]; + return true; + } + break; } } } @@ -1044,14 +1121,14 @@ namespace Vocaluxe.Lib.Draw if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y) return; - if (_TextureExists(Texture)) + if (_TextureExists(ref Texture)) { int list = GL.GenLists(1); _GLList.Add(list); GL.NewList(list, ListMode.Compile); { - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); float x1 = (bounds.X - rect.X) / rect.W * Texture.width_ratio; float x2 = (bounds.X + bounds.W - rect.X) / rect.W * Texture.width_ratio; @@ -1149,14 +1226,14 @@ namespace Vocaluxe.Lib.Draw public void DrawTexture(STexture Texture, SRectF rect, SColorF color, float begin, float end) { - if (_TextureExists(Texture)) + if (_TextureExists(ref Texture)) { int list = GL.GenLists(1); _GLList.Add(list); GL.NewList(list, ListMode.Compile); { - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); GL.Enable(EnableCap.Blend); GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); @@ -1200,14 +1277,14 @@ namespace Vocaluxe.Lib.Draw if (height > bounds.H) height = bounds.H; - if (_TextureExists(Texture)) + if (_TextureExists(ref Texture)) { int list = GL.GenLists(1); _GLList.Add(list); GL.NewList(list, ListMode.Compile); { - GL.BindTexture(TextureTarget.Texture2D, Texture.index); + GL.BindTexture(TextureTarget.Texture2D, Texture.ID); float x1 = (bounds.X - rect.X) / rect.W * Texture.width_ratio; float x2 = (bounds.X + bounds.W - rect.X) / rect.W * Texture.width_ratio; @@ -1291,6 +1368,79 @@ namespace Vocaluxe.Lib.Draw { return _Textures.Count; } + + private void CheckQueque() + { + lock (MutexTexture) + { + if (_Queque.Count == 0) + return; + + STextureQueque q = _Queque[0]; + STexture texture = new STexture(-1); + int index = -1; + for (int i = 0; i < _Textures.Count; i++) + { + if (_Textures[i].index == q.ID) + { + texture = _Textures[i]; + index = i; + break; + } + } + + if (texture.index < 1) + return; + + if (_UsePBO) + { + try + { + GL.GenBuffers(1, out texture.PBO); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, texture.PBO); + GL.BufferData(BufferTarget.PixelUnpackBuffer, (IntPtr)q.data.Length, IntPtr.Zero, BufferUsageHint.StreamDraw); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); + } + catch (Exception) + { + //throw; + _UsePBO = false; + } + } + + int id = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2D, id); + texture.ID = id; + + texture.width = q.width; + texture.height = q.height; + texture.w2 = (float)MathHelper.NextPowerOfTwo(texture.width); + texture.h2 = (float)MathHelper.NextPowerOfTwo(texture.height); + + texture.width_ratio = texture.width / texture.w2; + texture.height_ratio = texture.height / texture.h2; + + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, (int)texture.w2, (int)texture.h2, 0, + OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); + + GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, q.width, q.height, + OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, q.data); + + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + + GL.BindTexture(TextureTarget.Texture2D, 0); + + // Add to Texture List + texture.color = new SColorF(1f, 1f, 1f, 1f); + texture.rect = new SRectF(0f, 0f, texture.width, texture.height, 0f); + texture.TexturePath = String.Empty; + + _Textures[index] = texture; + _Queque.RemoveAt(0); + } + } + #endregion Textures #endregion implementation diff --git a/Vocaluxe/Lib/Draw/IDraw.cs b/Vocaluxe/Lib/Draw/IDraw.cs index 5a2a5c09..2f8bbc82 100644 --- a/Vocaluxe/Lib/Draw/IDraw.cs +++ b/Vocaluxe/Lib/Draw/IDraw.cs @@ -67,6 +67,7 @@ namespace Vocaluxe.Lib.Draw { public int index; public int PBO; + public int ID; public string TexturePath; @@ -85,10 +86,11 @@ namespace Vocaluxe.Lib.Draw { index = Index; PBO = 0; + ID = -1; TexturePath = String.Empty; - width = 0f; - height = 0f; + width = 1f; + height = 1f; rect = new SRectF(0f, 0f, 1f, 1f, 0f); w2 = 2f; @@ -136,6 +138,7 @@ namespace Vocaluxe.Lib.Draw STexture AddTexture(Bitmap Bitmap); STexture AddTexture(int W, int H, IntPtr Data); STexture AddTexture(int W, int H, ref byte[] Data); + STexture QuequeTexture(int W, int H, ref byte[] Data); bool UpdateTexture(ref STexture Texture, ref byte[] Data); bool UpdateTexture(ref STexture Texture, IntPtr Data); diff --git a/Vocaluxe/Screens/CScreenLoad.cs b/Vocaluxe/Screens/CScreenLoad.cs index 9d3f92c2..924a1094 100644 --- a/Vocaluxe/Screens/CScreenLoad.cs +++ b/Vocaluxe/Screens/CScreenLoad.cs @@ -135,6 +135,7 @@ namespace Vocaluxe.Screens } CLog.StartBenchmark(3, "Load Cover"); + _SongLoaderThread.IsBackground = true; _SongLoaderThread.Start(); _timer.Start(); @@ -306,6 +307,7 @@ namespace Vocaluxe.Screens _Finished = CVideo.VdFinished(_VideoStream); STexture tex = new STexture(-1); + tex.height = 0f; CVideo.VdGetFrame(_VideoStream, ref tex, VideoTime, ref VideoTime); if (tex.height > 0)