From 125be98466cd3d2d8c2dca56bc4f2f700e8870a0 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Thu, 25 Sep 2014 20:07:30 +0200 Subject: [PATCH 1/6] Actually dispose queued Bitmaps --- Vocaluxe/Lib/Draw/CDrawBase.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs index 3a8eeed2..2b3ee242 100644 --- a/Vocaluxe/Lib/Draw/CDrawBase.cs +++ b/Vocaluxe/Lib/Draw/CDrawBase.cs @@ -508,11 +508,20 @@ namespace Vocaluxe.Lib.Draw Debug.Assert(oldTexture != null, "Queued type is wrong"); Debug.Assert(!oldTexture.IsLoaded); if (oldTexture.RefCount <= 0) + { + Bitmap bmp = q.Data as Bitmap; + if (bmp != null) + bmp.Dispose(); continue; + } TTextureType texture = null; // ReSharper disable CanBeReplacedWithTryCastAndCheckForNull if (q.Data is Bitmap) - _WriteBitmapToTexture(ref texture, (Bitmap)q.Data); + { + Bitmap bmp = (Bitmap)q.Data; + _WriteBitmapToTexture(ref texture, bmp); + bmp.Dispose(); + } else if (q.Data is byte[]) texture = _CreateAndFillTexture(q.DataSize, (byte[])q.Data); else @@ -525,12 +534,21 @@ namespace Vocaluxe.Lib.Draw CTextureRef textureRef = q.TextureOrRef as CTextureRef; Debug.Assert(textureRef != null, "Queued type is wrong"); if (!_Textures.ContainsKey(textureRef.ID)) + { + Bitmap bmp = q.Data as Bitmap; + if (bmp != null) + bmp.Dispose(); continue; + } if (q.Action == EQueueAction.Update) { // ReSharper disable CanBeReplacedWithTryCastAndCheckForNull if (q.Data is Bitmap) - UpdateTexture(textureRef, (Bitmap)q.Data); + { + Bitmap bmp = (Bitmap)q.Data; + UpdateTexture(textureRef, bmp); + bmp.Dispose(); + } else if (q.Data is byte[]) UpdateTexture(textureRef, q.DataSize.Width, q.DataSize.Height, (byte[])q.Data); else From 25653ee55fe425d9d3288ccaee9bcb5919071676 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 26 Sep 2014 14:45:04 +0200 Subject: [PATCH 2/6] Revert "Remove bounds from DrawTextureReflection because it was never used" This reverts commit f5f1a9148149e17a9856e0b4c35e439802c26f39. Conflicts: Vocaluxe/Base/CMain.cs Vocaluxe/Screens/CScreenSing.cs VocaluxeLib/IBasic.cs VocaluxeLib/Menu/CStatic.cs VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs --- Vocaluxe/Base/CDraw.cs | 5 +-- Vocaluxe/Base/Fonts/CFont.cs | 2 +- Vocaluxe/Lib/Draw/CDirect3D.cs | 51 +++++++++++++++++++++++++------ Vocaluxe/Lib/Draw/CDrawWinForm.cs | 2 +- Vocaluxe/Lib/Draw/COpenGL.cs | 49 ++++++++++++++++++++++++----- Vocaluxe/Lib/Draw/IDraw.cs | 2 +- VocaluxeLib/Menu/CButton.cs | 6 ++-- VocaluxeLib/Menu/CStatic.cs | 12 +++----- 8 files changed, 97 insertions(+), 32 deletions(-) diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs index 4a9d50e6..0be03c05 100644 --- a/Vocaluxe/Base/CDraw.cs +++ b/Vocaluxe/Base/CDraw.cs @@ -391,11 +391,12 @@ namespace Vocaluxe.Base /// /// (Original) rectangle to draw the reflection for /// + /// /// Spacing between the rect and the reflection /// Height of the reflection - public static void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, float space, float height) + public static void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) { - _Draw.DrawTextureReflection(textureRef, rect, color, space, height); + _Draw.DrawTextureReflection(textureRef, rect, color, bounds, space, height); } } } \ No newline at end of file diff --git a/Vocaluxe/Base/Fonts/CFont.cs b/Vocaluxe/Base/Fonts/CFont.cs index 844c8247..a9c31e7a 100644 --- a/Vocaluxe/Base/Fonts/CFont.cs +++ b/Vocaluxe/Base/Fonts/CFont.cs @@ -104,7 +104,7 @@ namespace Vocaluxe.Base.Fonts CTextureRef texture; SRectF rect; GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect); - CDraw.DrawTextureReflection(texture, rect, color, rspace, rheight); + CDraw.DrawTextureReflection(texture, rect, color, rect, rspace, rheight); } public float GetWidth(char chr) diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index 682905bc..446e600f 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -552,7 +552,7 @@ namespace Vocaluxe.Lib.Draw /// The height of the reflection public void DrawRectReflection(SColorF color, SRectF rect, float space, float height) { - DrawTextureReflection(_BlankTexture, rect, color, space, height); + DrawTextureReflection(_BlankTexture, rect, color, rect, space, height); } #endregion Basic Draw Methods @@ -755,30 +755,63 @@ namespace Vocaluxe.Lib.Draw /// The texture of which a reflection should be drawn /// A SRectF struct containing the destination coordinates /// A SColorF struct containing a color which the texture will be colored in + /// A SRectF struct containing which part of the texture should be drawn /// The space between the texture and the reflection /// The height of the reflection - public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, float space, float height) + public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) { CD3DTexture texture; if (!_GetTexture(textureRef, out texture)) return; - if (Math.Abs(rect.W) < float.Epsilon || Math.Abs(rect.H) < float.Epsilon || Math.Abs(color.A) < float.Epsilon || height <= 0f) + if (Math.Abs(rect.W) < float.Epsilon || Math.Abs(rect.H) < float.Epsilon || Math.Abs(bounds.H) < float.Epsilon || Math.Abs(bounds.W) < float.Epsilon || + Math.Abs(color.A) < float.Epsilon || height <= 0f) return; - if (height > rect.H) - height = rect.H; + if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X) + return; + + if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y) + return; + + if (height > bounds.H) + height = bounds.H; + + float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio; + float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio; + float y1 = (bounds.Y - rect.Y + rect.H - height) / rect.H * texture.HeightRatio; + float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio; + + if (x1 < 0) + x1 = 0f; + + if (x2 > texture.WidthRatio) + x2 = texture.WidthRatio; + + if (y1 < 0) + y1 = 0f; + + if (y2 > texture.HeightRatio) + y2 = texture.HeightRatio; - const float x1 = 0; - float x2 = texture.WidthRatio; - float y1 = (rect.H - height) / rect.H * texture.HeightRatio; - float y2 = texture.HeightRatio; float rx1 = rect.X; float rx2 = rect.X + rect.W; float ry1 = rect.Y + rect.H + space; float ry2 = rect.Y + rect.H + space + height; + if (rx1 < bounds.X) + rx1 = bounds.X; + + if (rx2 > bounds.X + bounds.W) + rx2 = bounds.X + bounds.W; + + if (ry1 < bounds.Y + space) + ry1 = bounds.Y + space; + + if (ry2 > bounds.Y + bounds.H + space + height) + ry2 = bounds.Y + bounds.H + space + height; + //Align the pixels because Direct3D expects the pixels to be the left top corner rx1 -= 0.5f; ry1 -= 0.5f; diff --git a/Vocaluxe/Lib/Draw/CDrawWinForm.cs b/Vocaluxe/Lib/Draw/CDrawWinForm.cs index 0c9cb5c4..5fff48f2 100644 --- a/Vocaluxe/Lib/Draw/CDrawWinForm.cs +++ b/Vocaluxe/Lib/Draw/CDrawWinForm.cs @@ -435,7 +435,7 @@ namespace Vocaluxe.Lib.Draw public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end) {} - public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float space, float height) {} + public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float space, float height) {} public int GetTextureCount() { diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 94f0b63d..4096572e 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -627,24 +627,43 @@ namespace Vocaluxe.Lib.Draw GL.BindTexture(TextureTarget.Texture2D, 0); } - public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, float space, float height) + public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) { COGLTexture texture; if (!_GetTexture(textureRef, out texture)) return; - if (Math.Abs(rect.W) < float.Epsilon || Math.Abs(rect.H) < float.Epsilon || Math.Abs(color.A) < float.Epsilon || height <= float.Epsilon) + if (Math.Abs(rect.W) < float.Epsilon || Math.Abs(rect.H) < float.Epsilon || Math.Abs(bounds.H) < float.Epsilon || Math.Abs(bounds.W) < float.Epsilon || + Math.Abs(color.A) < float.Epsilon || height <= float.Epsilon) return; - if (height > rect.H) - height = rect.H; + if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X) + return; + + if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y) + return; + + if (height > bounds.H) + height = bounds.H; GL.BindTexture(TextureTarget.Texture2D, texture.Name); - const float x1 = 0; - float x2 = texture.WidthRatio; - float y1 = (rect.H - height) / rect.H * texture.HeightRatio; - float y2 = texture.HeightRatio; + float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio; + float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio; + float y1 = (bounds.Y - rect.Y + rect.H - height) / rect.H * texture.HeightRatio; + float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio; + + if (x1 < 0) + x1 = 0f; + + if (x2 > texture.WidthRatio) + x2 = texture.WidthRatio; + + if (y1 < 0) + y1 = 0f; + + if (y2 > texture.HeightRatio) + y2 = texture.HeightRatio; float rx1 = rect.X; @@ -652,6 +671,18 @@ namespace Vocaluxe.Lib.Draw float ry1 = rect.Y + rect.H + space; float ry2 = rect.Y + rect.H + space + height; + if (rx1 < bounds.X) + rx1 = bounds.X; + + if (rx2 > bounds.X + bounds.W) + rx2 = bounds.X + bounds.W; + + if (ry1 < bounds.Y + space) + ry1 = bounds.Y + space; + + if (ry2 > bounds.Y + bounds.H + space + height) + ry2 = bounds.Y + bounds.H + space + height; + GL.Enable(EnableCap.Blend); GL.MatrixMode(MatrixMode.Texture); @@ -664,6 +695,7 @@ namespace Vocaluxe.Lib.Draw GL.Translate(-0.5f, -0.5f, 0); } + GL.Begin(BeginMode.Quads); GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); @@ -684,6 +716,7 @@ namespace Vocaluxe.Lib.Draw GL.End(); + GL.PopMatrix(); GL.Disable(EnableCap.Blend); diff --git a/Vocaluxe/Lib/Draw/IDraw.cs b/Vocaluxe/Lib/Draw/IDraw.cs index 0b2421ff..acea643f 100644 --- a/Vocaluxe/Lib/Draw/IDraw.cs +++ b/Vocaluxe/Lib/Draw/IDraw.cs @@ -56,6 +56,6 @@ namespace Vocaluxe.Lib.Draw void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false); void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end); - void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float space, float height); + void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float space, float height); } } \ No newline at end of file diff --git a/VocaluxeLib/Menu/CButton.cs b/VocaluxeLib/Menu/CButton.cs index d842a04a..a0fd6039 100644 --- a/VocaluxeLib/Menu/CButton.cs +++ b/VocaluxeLib/Menu/CButton.cs @@ -273,7 +273,7 @@ namespace VocaluxeLib.Menu if (_Reflection) { - CBase.Drawing.DrawTextureReflection(texture, Rect, Color, _ReflectionSpace, _ReflectionHeight); + CBase.Drawing.DrawTextureReflection(texture, Rect, Color, Rect, _ReflectionSpace, _ReflectionHeight); Text.DrawRelative(Rect.X, Rect.Y, _ReflectionHeight, _ReflectionSpace, Rect.H); } else @@ -287,7 +287,7 @@ namespace VocaluxeLib.Menu if (_Reflection) { - CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, _ReflectionSpace, _ReflectionHeight); + CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, Rect, _ReflectionSpace, _ReflectionHeight); Text.DrawRelative(Rect.X, Rect.Y, _ReflectionHeight, _ReflectionSpace, Rect.H); } else @@ -301,7 +301,7 @@ namespace VocaluxeLib.Menu if (_Reflection) { - CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, _ReflectionSpace, _ReflectionHeight); + CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, Rect, _ReflectionSpace, _ReflectionHeight); _SelText.DrawRelative(Rect.X, Rect.Y, _ReflectionHeight, _ReflectionSpace, Rect.H); } else diff --git a/VocaluxeLib/Menu/CStatic.cs b/VocaluxeLib/Menu/CStatic.cs index 7d1dde1e..e53f3130 100644 --- a/VocaluxeLib/Menu/CStatic.cs +++ b/VocaluxeLib/Menu/CStatic.cs @@ -180,19 +180,17 @@ namespace VocaluxeLib.Menu public void Draw(EAspect aspect, float scale = 1f, float zModify = 0f, bool forceDraw = false) { CTextureRef texture = Texture; - SRectF rect = Rect.Scale(scale); - rect.Z += zModify; - if (texture != null) - rect = CHelper.FitInBounds(rect, texture.OrigAspect, aspect); - + SRectF bounds = Rect.Scale(scale); + bounds.Z += zModify; + SRectF rect = texture == null ? bounds : CHelper.FitInBounds(bounds, texture.OrigAspect, aspect); var color = new SColorF(Color.R, Color.G, Color.B, Color.A * Alpha); if (Visible || forceDraw || (CBase.Settings.GetProgramState() == EProgramState.EditTheme)) { if (texture != null) { - CBase.Drawing.DrawTexture(texture, rect, color); + CBase.Drawing.DrawTexture(texture, rect, color, bounds); if (Reflection) - CBase.Drawing.DrawTextureReflection(texture, rect, color, ReflectionSpace, ReflectionHeight); + CBase.Drawing.DrawTextureReflection(texture, rect, color, bounds, ReflectionSpace, ReflectionHeight); } else CBase.Drawing.DrawRect(color, rect); From 19f81943d6772673a5b08dfd0687a851157c0f93 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 26 Sep 2014 15:05:19 +0200 Subject: [PATCH 3/6] Introduce RenderRect for easy access to the full screen rect --- Vocaluxe/Base/CMain.cs | 9 +++- Vocaluxe/Base/CSettings.cs | 1 + Vocaluxe/Base/CVideoPlayer.cs | 3 +- Vocaluxe/Screens/CScreenCredits.cs | 4 +- Vocaluxe/Screens/CScreenSing.cs | 5 +- VocaluxeLib/CHelper.cs | 2 +- VocaluxeLib/IBasic.cs | 3 +- VocaluxeLib/Menu/CBackground.cs | 19 +++---- VocaluxeLib/Menu/CMenu.cs | 49 +++++++------------ VocaluxeLib/Menu/CObjectInteractions.cs | 2 +- .../Menu/SongMenu/CSongMenuTileBoard.cs | 7 ++- 11 files changed, 48 insertions(+), 56 deletions(-) diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index 3da3360c..7831ec19 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -174,6 +174,11 @@ namespace Vocaluxe.Base return CSettings.RenderH; } + public SRectF GetRenderRect() + { + return CSettings.RenderRect; + } + public bool IsTabNavigation() { return CSettings.TabNavigation; @@ -438,9 +443,9 @@ namespace Vocaluxe.Base CDraw.DrawTexture(textureRef, bounds, aspect, color); } - public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float reflectionSpace, float reflectionHeight) + public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight) { - CDraw.DrawTextureReflection(texture, rect, color, reflectionSpace, reflectionHeight); + CDraw.DrawTextureReflection(texture, rect, color, bounds, reflectionSpace, reflectionHeight); } public CTextureRef AddTexture(string fileName) diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index b419e7b1..36a66d15 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -65,6 +65,7 @@ namespace Vocaluxe.Base public const int RenderW = 1280; public const int RenderH = 720; + public static readonly SRectF RenderRect = new SRectF(0, 0, RenderW, RenderH, 0); public const int ZNear = -100; public const int ZFar = 100; diff --git a/Vocaluxe/Base/CVideoPlayer.cs b/Vocaluxe/Base/CVideoPlayer.cs index 0838ae7c..cfa7f6e7 100644 --- a/Vocaluxe/Base/CVideoPlayer.cs +++ b/Vocaluxe/Base/CVideoPlayer.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Drawing; using VocaluxeLib; using VocaluxeLib.Draw; @@ -63,7 +62,7 @@ namespace Vocaluxe.Base if (_VideoTexture == null) return; - CDraw.DrawTexture(_VideoTexture, new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, CSettings.ZFar / 4), EAspect.Crop); + CDraw.DrawTexture(_VideoTexture, CSettings.RenderRect, EAspect.Crop); } public void PreLoad() diff --git a/Vocaluxe/Screens/CScreenCredits.cs b/Vocaluxe/Screens/CScreenCredits.cs index dc9904fc..4404bebc 100644 --- a/Vocaluxe/Screens/CScreenCredits.cs +++ b/Vocaluxe/Screens/CScreenCredits.cs @@ -142,6 +142,8 @@ namespace Vocaluxe.Screens private CTextureRef _TexNamePantero; private CTextureRef _TexNamePinky007; + private static SColorF _BGColor = new SColorF(0, 0.18f, 0.474f, 1); + public override void Init() { base.Init(); @@ -360,7 +362,7 @@ namespace Vocaluxe.Screens base.Draw(); //Draw background - CDraw.DrawRect(new SColorF(0, 0.18f, 0.474f, 1), new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, 0)); + CDraw.DrawRect(_BGColor, CSettings.RenderRect); //Draw stars _StarsBlue.Draw(); diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 2a7da149..e3f1f525 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -478,8 +478,9 @@ namespace Vocaluxe.Screens background = _Background; if (background != null) { - var bounds = new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, 0); - CDraw.DrawTexture(background, bounds, aspect, background.Color); + SRectF bounds = CSettings.RenderRect; + SRectF rect = CHelper.FitInBounds(bounds, background.OrigAspect, aspect); + CDraw.DrawTexture(background, rect, background.Color, bounds); } else if (_SlideShow != null) _SlideShow.Draw(); diff --git a/VocaluxeLib/CHelper.cs b/VocaluxeLib/CHelper.cs index d54a2d00..6c143b59 100644 --- a/VocaluxeLib/CHelper.cs +++ b/VocaluxeLib/CHelper.cs @@ -84,7 +84,7 @@ namespace VocaluxeLib /// Bounds to fit the rect in /// The original aspectRatio of the rect/image/... /// - /// Crop: Fit fully in bounds cutting off overhanging parts (same on both sides)
+ /// Crop: No empty space in bounds but has overhanging parts (same on both sides)
/// LetterBox: Fit the long side possibly leaving some space on the other (rect will be centered)
/// StretcH: Just fit the rect in the bounds (rect=bounds) /// diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index e4b3b4cf..81734aa2 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -70,6 +70,7 @@ namespace VocaluxeLib { int GetRenderW(); int GetRenderH(); + SRectF GetRenderRect(); bool IsTabNavigation(); float GetZFar(); @@ -147,7 +148,7 @@ namespace VocaluxeLib void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false); void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect); void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect, SColorF color); - void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float reflectionSpace, float reflectionHeight); + void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight); CTextureRef AddTexture(string fileName); void RemoveTexture(ref CTextureRef texture); diff --git a/VocaluxeLib/Menu/CBackground.cs b/VocaluxeLib/Menu/CBackground.cs index 9faeb4c9..33cd979c 100644 --- a/VocaluxeLib/Menu/CBackground.cs +++ b/VocaluxeLib/Menu/CBackground.cs @@ -36,16 +36,11 @@ namespace VocaluxeLib.Menu [XmlType("Background")] public struct SThemeBackground { - [XmlAttributeAttribute(AttributeName = "Name")] - public string Name; - [XmlElement("Type")] - public EBackgroundTypes Type; - [XmlArray] - public List SlideShowTextures; - [XmlElement("Video")] - public string VideoName; - [XmlElement("Skin")] - public string TextureName; + [XmlAttribute(AttributeName = "Name")] public string Name; + [XmlElement("Type")] public EBackgroundTypes Type; + [XmlArray] public List SlideShowTextures; + [XmlElement("Video")] public string VideoName; + [XmlElement("Skin")] public string TextureName; public SThemeColor Color; } @@ -225,7 +220,9 @@ namespace VocaluxeLib.Menu #region internal private static SRectF _GetDrawRect() { - return new SRectF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH(), CBase.Settings.GetZFar() / 4); + SRectF rect = CBase.Settings.GetRenderRect(); + rect.Z = CBase.Settings.GetZFar() / 4; + return rect; } private void _DrawColor() diff --git a/VocaluxeLib/Menu/CMenu.cs b/VocaluxeLib/Menu/CMenu.cs index 2a69aed7..fe6189df 100644 --- a/VocaluxeLib/Menu/CMenu.cs +++ b/VocaluxeLib/Menu/CMenu.cs @@ -33,37 +33,24 @@ namespace VocaluxeLib.Menu public string ScreenName; public int ScreenVersion; } + [XmlType("Screen")] public struct STheme { - [XmlElement("Informations")] - public SScreenInformation ScreenInformation; - [XmlArray("Backgrounds")] - public List Backgrounds; - [XmlArray("Statics")] - public List Statics; - [XmlArray("Texts")] - public List Texts; - [XmlArray("Buttons")] - public List Buttons; - [XmlArray("SongMenus")] - public List SongMenus; - [XmlArray("Lyrics")] - public List Lyrics; - [XmlArray("SelectSlides")] - public List SelectSlides; - [XmlArray("SingNotes")] - public List SingNotes; - [XmlArray("NameSelections")] - public List NameSelections; - [XmlArray("Equalizers")] - public List Equalizers; - [XmlArray("Playlists")] - public List Playlists; - [XmlArray("ParticleEffects")] - public List ParticleEffects; - [XmlArray("ScreenSettings")] - public List ScreenSettings; + [XmlElement("Informations")] public SScreenInformation ScreenInformation; + [XmlArray("Backgrounds")] public List Backgrounds; + [XmlArray("Statics")] public List Statics; + [XmlArray("Texts")] public List Texts; + [XmlArray("Buttons")] public List Buttons; + [XmlArray("SongMenus")] public List SongMenus; + [XmlArray("Lyrics")] public List Lyrics; + [XmlArray("SelectSlides")] public List SelectSlides; + [XmlArray("SingNotes")] public List SingNotes; + [XmlArray("NameSelections")] public List NameSelections; + [XmlArray("Equalizers")] public List Equalizers; + [XmlArray("Playlists")] public List Playlists; + [XmlArray("ParticleEffects")] public List ParticleEffects; + [XmlArray("ScreenSettings")] public List ScreenSettings; } struct SZSort @@ -157,7 +144,7 @@ namespace VocaluxeLib.Menu _MouseDY = 0; _Active = false; - _ScreenArea = new SRectF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH(), 0f); + _ScreenArea = CBase.Settings.GetRenderRect(); _ThemeBackgrounds = null; _ThemeStatics = null; @@ -249,7 +236,7 @@ namespace VocaluxeLib.Menu foreach (SThemeParticleEffect pe in Theme.ParticleEffects) _AddParticleEffect(new CParticleEffect(pe, _PartyModeID), pe.Name); - foreach(SThemePlaylist pl in Theme.Playlists) + foreach (SThemePlaylist pl in Theme.Playlists) _AddPlaylist(new CPlaylist(pl, _PartyModeID), pl.Name); foreach (SScreenSetting ss in Theme.ScreenSettings) @@ -268,7 +255,7 @@ namespace VocaluxeLib.Menu _AddStatic(new CStatic(st, _PartyModeID), st.Name); foreach (SThemeText te in Theme.Texts) - _AddText(new CText(te, _PartyModeID), te.Name); + _AddText(new CText(te, _PartyModeID), te.Name); } catch (InvalidOperationException e) { diff --git a/VocaluxeLib/Menu/CObjectInteractions.cs b/VocaluxeLib/Menu/CObjectInteractions.cs index 791412d8..c2c99823 100644 --- a/VocaluxeLib/Menu/CObjectInteractions.cs +++ b/VocaluxeLib/Menu/CObjectInteractions.cs @@ -69,7 +69,7 @@ namespace VocaluxeLib.Menu _MouseDY = 0; Active = false; - _ScreenArea = new SRectF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH(), 0f); + _ScreenArea = CBase.Settings.GetRenderRect(); } public void Clear() diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs index 14504d80..6a3b1248 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs @@ -199,7 +199,7 @@ namespace VocaluxeLib.Menu.SongMenu _Tiles.Add(tile); } } - _ScrollRect = new SRectF(0, 0, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH(), Rect.Z); + _ScrollRect = CBase.Settings.GetRenderRect(); } public override void Update(SScreenSongOptions songOptions) @@ -500,9 +500,8 @@ namespace VocaluxeLib.Menu.SongMenu if (vidtex.Color.A < 1) _CoverBig.Draw(EAspect.Crop); SRectF rect = CHelper.FitInBounds(_CoverBig.Rect, vidtex.OrigAspect, EAspect.Crop); - - CBase.Drawing.DrawTexture(vidtex, rect); - CBase.Drawing.DrawTextureReflection(vidtex, rect, vidtex.Color, _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight); + CBase.Drawing.DrawTexture(vidtex, rect, vidtex.Color, _CoverBig.Rect); + CBase.Drawing.DrawTextureReflection(vidtex, rect, vidtex.Color, _CoverBig.Rect, _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight); } else _CoverBig.Draw(EAspect.Crop); From b48cfa8e77d3959f021fab3cb80d945735cca41f Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 27 Sep 2014 14:09:36 +0200 Subject: [PATCH 4/6] Handle drawing with bounds in one place Also reduces drawing code a lot... --- Vocaluxe/Lib/Draw/CDirect3D.cs | 239 +++++--------------- Vocaluxe/Lib/Draw/CDrawBase.cs | 110 ++++++++++ Vocaluxe/Lib/Draw/COpenGL.cs | 348 +++++++++--------------------- Vocaluxe/Lib/Draw/CTextureBase.cs | 2 +- 4 files changed, 268 insertions(+), 431 deletions(-) diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index 446e600f..8d0f4b75 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -15,6 +15,7 @@ // along with Vocaluxe. If not, see . #endregion +using System.Diagnostics; using SlimDX; using SlimDX.Direct3D9; using System; @@ -420,13 +421,41 @@ namespace Vocaluxe.Lib.Draw return _Device.Viewport.Height; } + /// + /// Adds a texture to the vertext buffer + /// + /// Texture to draw + /// Coordinates to draw on + /// Color to use + /// If true, then color is faded out in y direction + private void _DrawTexture(CD3DTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) + { + color.A *= CGraphics.GlobalAlpha; + int c = color.AsColor().ToArgb(); + int c2; + if (isReflection) + { + color.A = 0; + c2 = color.AsColor().ToArgb(); + } + else + c2 = c; + + var vert = new STexturedColoredVertex[4]; + vert[0] = new STexturedColoredVertex(new Vector3(dc.Wx1, -dc.Wy1, dc.Wz), new Vector2(dc.Tx1, dc.Ty1), c); + vert[1] = new STexturedColoredVertex(new Vector3(dc.Wx1, -dc.Wy2, dc.Wz), new Vector2(dc.Tx1, dc.Ty2), c2); + vert[2] = new STexturedColoredVertex(new Vector3(dc.Wx2, -dc.Wy2, dc.Wz), new Vector2(dc.Tx2, dc.Ty2), c2); + vert[3] = new STexturedColoredVertex(new Vector3(dc.Wx2, -dc.Wy1, dc.Wz), new Vector2(dc.Tx2, dc.Ty1), c); + _DrawTexture(vert, texture.D3DTexture, _CalculateRotationMatrix(dc.Rotation, dc.Wx1, dc.Wx2, dc.Wy1, dc.Wy2)); + } + /// /// Adds a quad a list which will be added and rendered to the vertexbuffer when calling RenderToVertexBuffer to reduce vertexbuffer calls each frame to a minimum /// /// A TexturedColoredVertex array containg 4 vertices /// The texture the vertex should be textured with /// The vertices' rotation - private void _AddToVertexBuffer(STexturedColoredVertex[] vertices, Texture tex, Matrix rotation) + private void _DrawTexture(STexturedColoredVertex[] vertices, Texture tex, Matrix rotation) { //The vertexbuffer is full, so we need to flush it before we can continue if (_Vertices.Count >= CSettings.VertexBufferElements) @@ -593,41 +622,16 @@ namespace Vocaluxe.Lib.Draw /// True if the texture should be mirrored public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) { - if (rect.W < 1 || rect.H < 1) + if (Math.Abs(color.A) < 0.01) return; - + SDrawCoords dc; CD3DTexture texture; if (!_GetTexture(textureRef, out texture)) return; + if (!_CalcDrawCoords(texture, rect, out dc, mirrored)) + return; - //Calculate the position - const float x1 = 0; - float x2 = texture.WidthRatio; - float y1 = 0; - float y2 = texture.HeightRatio; - - //Calculate the size - float rx1 = rect.X; - float rx2 = rect.X + rect.W; - float ry1 = rect.Y; - float ry2 = rect.Y + rect.H; - - color.A *= CGraphics.GlobalAlpha; - - Color c = color.AsColor(); - - if (mirrored) - { - float tmp = y2; - y2 = y1; - y1 = tmp; - } - var vert = new STexturedColoredVertex[4]; - vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), c.ToArgb()); - vert[1] = new STexturedColoredVertex(new Vector3(rx1, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()); - vert[2] = new STexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()); - vert[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb()); - _AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2)); + _DrawTexture(texture, dc, color); } /// @@ -640,71 +644,16 @@ namespace Vocaluxe.Lib.Draw /// True if the texture should be mirrored public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) { - if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(bounds.H) < 1 || Math.Abs(bounds.W) < 1 || - Math.Abs(color.A) < 0.01) + if (Math.Abs(color.A) < 0.01) return; - - if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X) - return; - - if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y) - return; - + SDrawCoords dc; CD3DTexture texture; if (!_GetTexture(textureRef, out texture)) return; + if (!_CalcDrawCoords(texture, rect, bounds, out dc)) + return; - //Calculate the position - float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio; - float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio; - float y1 = (bounds.Y - rect.Y) / rect.H * texture.HeightRatio; - float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio; - - if (x1 < 0) - x1 = 0f; - - if (x2 > texture.WidthRatio) - x2 = texture.WidthRatio; - - if (y1 < 0) - y1 = 0f; - - if (y2 > texture.HeightRatio) - y2 = texture.HeightRatio; - - //Calculate the size - float rx1 = rect.X; - float rx2 = rect.X + rect.W; - float ry1 = rect.Y; - float ry2 = rect.Y + rect.H; - - if (rx1 < bounds.X) - rx1 = bounds.X; - - if (rx2 > bounds.X + bounds.W) - rx2 = bounds.X + bounds.W; - - if (ry1 < bounds.Y) - ry1 = bounds.Y; - - if (ry2 > bounds.Y + bounds.H) - ry2 = bounds.Y + bounds.H; - - color.A *= CGraphics.GlobalAlpha; - - Color c = color.AsColor(); - - if (mirrored) - { - y1 = -y1; - y2 = -y2; - } - var vert = new STexturedColoredVertex[4]; - vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), c.ToArgb()); - vert[1] = new STexturedColoredVertex(new Vector3(rx1, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()); - vert[2] = new STexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()); - vert[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb()); - _AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2)); + _DrawTexture(texture, dc, color); } /// @@ -717,36 +666,16 @@ namespace Vocaluxe.Lib.Draw /// A Value ranging from 0 to 1 containing the ending of the texture public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end) { + if (Math.Abs(color.A) < 0.01) + return; + SDrawCoords dc; CD3DTexture texture; if (!_GetTexture(textureRef, out texture)) return; + if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end)) + return; - float x1 = 0f + begin * texture.WidthRatio; - float x2 = texture.WidthRatio * end; - const float y1 = 0f; - float y2 = texture.HeightRatio; - - float rx1 = rect.X + begin * rect.W; - float rx2 = rect.X + end * rect.W; - float ry1 = rect.Y; - float ry2 = rect.Y + rect.H; - - //Align the pixels because Direct3D expects the pixels to be the left top corner - rx1 -= 0.5f; - ry1 -= 0.5f; - rx2 -= 0.5f; - ry2 -= 0.5f; - - color.A *= CGraphics.GlobalAlpha; - - Color c = color.AsColor(); - - var vert = new STexturedColoredVertex[4]; - vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), c.ToArgb()); - vert[1] = new STexturedColoredVertex(new Vector3(rx1, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()); - vert[2] = new STexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()); - vert[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb()); - _AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2)); + _DrawTexture(texture, dc, color); } /// @@ -760,75 +689,25 @@ namespace Vocaluxe.Lib.Draw /// The height of the reflection public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) { + Debug.Assert(height >= 0); + + if (Math.Abs(color.A) < 0.01 || height < 1) + return; + SDrawCoords dc; CD3DTexture texture; if (!_GetTexture(textureRef, out texture)) return; - - if (Math.Abs(rect.W) < float.Epsilon || Math.Abs(rect.H) < float.Epsilon || Math.Abs(bounds.H) < float.Epsilon || Math.Abs(bounds.W) < float.Epsilon || - Math.Abs(color.A) < float.Epsilon || height <= 0f) + if (!_CalcDrawCoords(texture, rect, bounds, out dc, true)) return; - if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X) - return; + if (height > rect.H) + height = rect.H; - if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y) - return; - - if (height > bounds.H) - height = bounds.H; - - float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio; - float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio; - float y1 = (bounds.Y - rect.Y + rect.H - height) / rect.H * texture.HeightRatio; - float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio; - - if (x1 < 0) - x1 = 0f; - - if (x2 > texture.WidthRatio) - x2 = texture.WidthRatio; - - if (y1 < 0) - y1 = 0f; - - if (y2 > texture.HeightRatio) - y2 = texture.HeightRatio; - - - float rx1 = rect.X; - float rx2 = rect.X + rect.W; - float ry1 = rect.Y + rect.H + space; - float ry2 = rect.Y + rect.H + space + height; - - if (rx1 < bounds.X) - rx1 = bounds.X; - - if (rx2 > bounds.X + bounds.W) - rx2 = bounds.X + bounds.W; - - if (ry1 < bounds.Y + space) - ry1 = bounds.Y + space; - - if (ry2 > bounds.Y + bounds.H + space + height) - ry2 = bounds.Y + bounds.H + space + height; - - //Align the pixels because Direct3D expects the pixels to be the left top corner - rx1 -= 0.5f; - ry1 -= 0.5f; - rx2 -= 0.5f; - ry2 -= 0.5f; - - color.A *= CGraphics.GlobalAlpha; - Color c = color.AsColor(); - color.A = 0; - Color transparent = color.AsColor(); - - var vert = new STexturedColoredVertex[4]; - vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()); - vert[1] = new STexturedColoredVertex(new Vector3(rx1, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), transparent.ToArgb()); - vert[2] = new STexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), transparent.ToArgb()); - vert[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()); - _AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2)); + dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing + dc.Wy2 += space + height; // Move from end of rect + dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2) + if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something + _DrawTexture(texture, dc, color, true); } #endregion drawing diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs index 2b3ee242..19017a5f 100644 --- a/Vocaluxe/Lib/Draw/CDrawBase.cs +++ b/Vocaluxe/Lib/Draw/CDrawBase.cs @@ -213,6 +213,116 @@ namespace Vocaluxe.Lib.Draw #region Textures #region private/protected + /// + /// Struct that contains texture and world coordinates for drawing + /// + protected struct SDrawCoords + { + /// + /// Texture coordinates + /// + public float Tx1, Tx2, Ty1, Ty2; + /// + /// World coordinates + /// + public float Wx1, Wx2, Wy1, Wy2, Wz; + public float Rotation; + } + + /// + /// Calculates the texture and world coordinates for drawing the texture in the rect cropping at the the bounds + /// + /// + /// Rect to draw the texture (might stretch the texture) + /// Rect to stay in (might crop the texture) + /// Struct for the coordinates + /// Mirror on y-axis + /// True if anything will be dawn + protected bool _CalcDrawCoords(TTextureType texture, SRectF rect, SRectF bounds, out SDrawCoords drawCoords, bool mirrored = false) + { + drawCoords = new SDrawCoords(); + if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(bounds.H) < 1 || Math.Abs(bounds.W) < 1) + return false; + + if (bounds.X >= rect.Right || bounds.Right <= rect.X) + return false; + + if (bounds.Y >= rect.Bottom || bounds.Bottom <= rect.Y) + return false; + + drawCoords.Tx1 = Math.Max(0, (bounds.X - rect.X) / rect.W * texture.WidthRatio); + drawCoords.Wx1 = Math.Max(rect.X, bounds.X); + drawCoords.Tx2 = Math.Min(1, (bounds.Right - rect.X) / rect.W) * texture.WidthRatio; + drawCoords.Wx2 = Math.Min(rect.Right, bounds.Right); + + drawCoords.Ty1 = Math.Max(0, (bounds.Y - rect.Y) / rect.H * texture.HeightRatio); + drawCoords.Wy1 = Math.Max(rect.Y, bounds.Y); + drawCoords.Ty2 = Math.Min(1, (bounds.Bottom - rect.Y) / rect.H) * texture.HeightRatio; + drawCoords.Wy2 = Math.Min(rect.Bottom, bounds.Bottom); + + //TODO: Check this: + /*//Align the pixels because Direct3D expects the pixels to be the left top corner + rx1 -= 0.5f; + ry1 -= 0.5f; + rx2 -= 0.5f; + ry2 -= 0.5f;*/ + + if (mirrored) + { + float tmp = drawCoords.Ty1; + drawCoords.Ty1 = drawCoords.Ty2; + drawCoords.Ty2 = tmp; + } + + drawCoords.Wz = rect.Z + CGraphics.ZOffset; + drawCoords.Rotation = rect.Rotation; + + return true; + } + + /// + /// Calculates the texture and world coordinates for drawing (a part of) the texture in the rect + /// + /// Texture to draw + /// Rect to draw in (might stretch the texture) + /// Struct for the coordinates + /// Mirror on y axis + /// Position of the texture to begin drawing (0 <=x<=1) + /// Position of the texture to end drawing (0 <=x<=1) + /// True if anything will be dawn + protected bool _CalcDrawCoords(TTextureType texture, SRectF rect, out SDrawCoords drawCoords, bool mirrored = false, float begin = 0, float end = 1) + { + drawCoords = new SDrawCoords(); + if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1) + return false; + if (begin >= 1 || begin >= end) + return false; + + Debug.Assert(begin.IsInRange(0, 1) && end.IsInRange(0, 1)); + + drawCoords.Tx1 = begin * texture.WidthRatio; + drawCoords.Wx1 = rect.X + begin * rect.W; + drawCoords.Tx2 = end * texture.WidthRatio; + drawCoords.Wx2 = rect.X + end * rect.W; + + drawCoords.Ty1 = 0; + drawCoords.Wy1 = rect.Y; + drawCoords.Ty2 = texture.HeightRatio; + drawCoords.Wy2 = rect.Bottom; + + if (mirrored) + { + float tmp = drawCoords.Ty1; + drawCoords.Ty1 = drawCoords.Ty2; + drawCoords.Ty2 = tmp; + } + + drawCoords.Wz = rect.Z + CGraphics.ZOffset; + drawCoords.Rotation = rect.Rotation; + + return true; + } + /// /// Returns the maximum area allowed for a texture based on the current quality /// diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 4096572e..91cd3e31 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -15,6 +15,7 @@ // along with Vocaluxe. If not, see . #endregion +using System.Diagnostics; using System.Drawing.Imaging; using OpenTK; using OpenTK.Graphics; @@ -437,290 +438,137 @@ namespace Vocaluxe.Lib.Draw } #region drawing + private static void _DrawTexture(COGLTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) + { + GL.BindTexture(TextureTarget.Texture2D, texture.Name); + + GL.Enable(EnableCap.Blend); + + GL.MatrixMode(MatrixMode.Texture); + GL.PushMatrix(); + + if (Math.Abs(dc.Rotation) > float.Epsilon) + { + GL.Translate(0.5f, 0.5f, 0); + GL.Rotate(-dc.Rotation, 0f, 0f, 1f); + GL.Translate(-0.5f, -0.5f, 0); + } + + GL.Begin(BeginMode.Quads); + + GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); + GL.TexCoord2(dc.Tx1, dc.Ty1); + GL.Vertex3(dc.Wx1, dc.Wy1, dc.Wz); + + if (isReflection) + GL.Color4(color.R, color.G, color.B, 0); + GL.TexCoord2(dc.Tx1, dc.Ty2); + GL.Vertex3(dc.Wx1, dc.Wy2, dc.Wz); + + GL.TexCoord2(dc.Tx2, dc.Ty2); + GL.Vertex3(dc.Wx2, dc.Wy2, dc.Wz); + + if (isReflection) + GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); + GL.TexCoord2(dc.Tx2, dc.Ty1); + GL.Vertex3(dc.Wx2, dc.Wy1, dc.Wz); + + GL.End(); + + GL.PopMatrix(); + + GL.Disable(EnableCap.Blend); + GL.BindTexture(TextureTarget.Texture2D, 0); + } + public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) { + if (Math.Abs(color.A) < 0.01) + return; + SDrawCoords dc; COGLTexture texture; if (!_GetTexture(textureRef, out texture)) return; - - if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(color.A) < 0.01) + if (!_CalcDrawCoords(texture, rect, out dc, mirrored)) return; - GL.BindTexture(TextureTarget.Texture2D, texture.Name); - - const float x1 = 0; - float x2 = texture.WidthRatio; - float y1 = 0; - float y2 = texture.HeightRatio; - - float rx1 = rect.X; - float rx2 = rect.X + rect.W; - float ry1 = rect.Y; - float ry2 = rect.Y + rect.H; - - GL.Enable(EnableCap.Blend); - GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); - - GL.MatrixMode(MatrixMode.Texture); - GL.PushMatrix(); - - if (Math.Abs(rect.Rotation) > float.Epsilon) - { - GL.Translate(0.5f, 0.5f, 0); - GL.Rotate(-rect.Rotation, 0f, 0f, 1f); - GL.Translate(-0.5f, -0.5f, 0); - } - - if (mirrored) - { - float tmp = y2; - y2 = y1; - y1 = tmp; - } - - GL.Begin(BeginMode.Quads); - - GL.TexCoord2(x1, y1); - GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(x1, y2); - GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(x2, y2); - GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(x2, y1); - GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset); - - GL.End(); - - GL.PopMatrix(); - - GL.Disable(EnableCap.Blend); - GL.BindTexture(TextureTarget.Texture2D, 0); + _DrawTexture(texture, dc, color); } + /// + /// Draws a texture + /// + /// The texture to be drawn + /// A SRectF struct containing the destination coordinates + /// A SColorF struct containing a color which the texture will be colored in + /// A SRectF struct containing which part of the texture should be drawn + /// True if the texture should be mirrored public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) { + if (Math.Abs(color.A) < 0.01) + return; + SDrawCoords dc; COGLTexture texture; if (!_GetTexture(textureRef, out texture)) return; - - if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(bounds.H) < 1 || Math.Abs(bounds.W) < 1 || - Math.Abs(color.A) < 0.01) + if (!_CalcDrawCoords(texture, rect, bounds, out dc)) return; - if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X) - return; - - if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y) - return; - - GL.BindTexture(TextureTarget.Texture2D, texture.Name); - - float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio; - float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio; - float y1 = (bounds.Y - rect.Y) / rect.H * texture.HeightRatio; - float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio; - - if (x1 < 0) - x1 = 0f; - - if (x2 > texture.WidthRatio) - x2 = texture.WidthRatio; - - if (y1 < 0) - y1 = 0f; - - if (y2 > texture.HeightRatio) - y2 = texture.HeightRatio; - - - float rx1 = rect.X; - float rx2 = rect.X + rect.W; - float ry1 = rect.Y; - float ry2 = rect.Y + rect.H; - - if (rx1 < bounds.X) - rx1 = bounds.X; - - if (rx2 > bounds.X + bounds.W) - rx2 = bounds.X + bounds.W; - - if (ry1 < bounds.Y) - ry1 = bounds.Y; - - if (ry2 > bounds.Y + bounds.H) - ry2 = bounds.Y + bounds.H; - - GL.Enable(EnableCap.Blend); - GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); - - GL.MatrixMode(MatrixMode.Texture); - GL.PushMatrix(); - - if (Math.Abs(rect.Rotation) > float.Epsilon) - { - GL.Translate(0.5f, 0.5f, 0); - GL.Rotate(-rect.Rotation, 0f, 0f, 1f); - GL.Translate(-0.5f, -0.5f, 0); - } - - if (mirrored) - { - float tmp = y2; - y2 = y1; - y1 = tmp; - } - - GL.Begin(BeginMode.Quads); - - GL.TexCoord2(x1, y1); - GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(x1, y2); - GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(x2, y2); - GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(x2, y1); - GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset); - - GL.End(); - - GL.PopMatrix(); - - GL.Disable(EnableCap.Blend); - GL.BindTexture(TextureTarget.Texture2D, 0); + _DrawTexture(texture, dc, color); } + /// + /// Draws a texture + /// + /// The texture to be drawn + /// A SRectF struct containing the destination coordinates + /// A SColorF struct containing a color which the texture will be colored in + /// A Value ranging from 0 to 1 containing the beginning of the texture + /// A Value ranging from 0 to 1 containing the ending of the texture public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end) { + if (Math.Abs(color.A) < 0.01) + return; + SDrawCoords dc; COGLTexture texture; if (!_GetTexture(textureRef, out texture)) return; + if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end)) + return; - GL.BindTexture(TextureTarget.Texture2D, texture.Name); - - GL.Enable(EnableCap.Blend); - GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); - - - GL.Begin(BeginMode.Quads); - - GL.TexCoord2(0f + begin * texture.WidthRatio, 0f); - GL.Vertex3(rect.X + begin * rect.W, rect.Y, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(0f + begin * texture.WidthRatio, texture.HeightRatio); - GL.Vertex3(rect.X + begin * rect.W, rect.Y + rect.H, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(texture.WidthRatio * end, texture.HeightRatio); - GL.Vertex3(rect.X + end * rect.W, rect.Y + rect.H, rect.Z + CGraphics.ZOffset); - - GL.TexCoord2(texture.WidthRatio * end, 0f); - GL.Vertex3(rect.X + end * rect.W, rect.Y, rect.Z + CGraphics.ZOffset); - - GL.End(); - - GL.Disable(EnableCap.Blend); - GL.BindTexture(TextureTarget.Texture2D, 0); + _DrawTexture(texture, dc, color); } + /// + /// Draws a reflection of a texture + /// + /// The texture of which a reflection should be drawn + /// A SRectF struct containing the destination coordinates + /// A SColorF struct containing a color which the texture will be colored in + /// A SRectF struct containing which part of the texture should be drawn + /// The space between the texture and the reflection + /// The height of the reflection public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) { + Debug.Assert(height >= 0); + + if (Math.Abs(color.A) < 0.01 || height < 1) + return; + SDrawCoords dc; COGLTexture texture; if (!_GetTexture(textureRef, out texture)) return; - - if (Math.Abs(rect.W) < float.Epsilon || Math.Abs(rect.H) < float.Epsilon || Math.Abs(bounds.H) < float.Epsilon || Math.Abs(bounds.W) < float.Epsilon || - Math.Abs(color.A) < float.Epsilon || height <= float.Epsilon) + if (!_CalcDrawCoords(texture, rect, bounds, out dc, true)) return; - if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X) - return; + if (height > rect.H) + height = rect.H; - if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y) - return; - - if (height > bounds.H) - height = bounds.H; - - GL.BindTexture(TextureTarget.Texture2D, texture.Name); - - float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio; - float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio; - float y1 = (bounds.Y - rect.Y + rect.H - height) / rect.H * texture.HeightRatio; - float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio; - - if (x1 < 0) - x1 = 0f; - - if (x2 > texture.WidthRatio) - x2 = texture.WidthRatio; - - if (y1 < 0) - y1 = 0f; - - if (y2 > texture.HeightRatio) - y2 = texture.HeightRatio; - - - float rx1 = rect.X; - float rx2 = rect.X + rect.W; - float ry1 = rect.Y + rect.H + space; - float ry2 = rect.Y + rect.H + space + height; - - if (rx1 < bounds.X) - rx1 = bounds.X; - - if (rx2 > bounds.X + bounds.W) - rx2 = bounds.X + bounds.W; - - if (ry1 < bounds.Y + space) - ry1 = bounds.Y + space; - - if (ry2 > bounds.Y + bounds.H + space + height) - ry2 = bounds.Y + bounds.H + space + height; - - GL.Enable(EnableCap.Blend); - - GL.MatrixMode(MatrixMode.Texture); - GL.PushMatrix(); - - if (Math.Abs(rect.Rotation) > float.Epsilon) - { - GL.Translate(0.5f, 0.5f, 0); - GL.Rotate(-rect.Rotation, 0f, 0f, 1f); - GL.Translate(-0.5f, -0.5f, 0); - } - - - GL.Begin(BeginMode.Quads); - - GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); - GL.TexCoord2(x2, y2); - GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset); - - GL.Color4(color.R, color.G, color.B, 0f); - GL.TexCoord2(x2, y1); - GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset); - - GL.Color4(color.R, color.G, color.B, 0f); - GL.TexCoord2(x1, y1); - GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset); - - GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); - GL.TexCoord2(x1, y2); - GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset); - - GL.End(); - - - GL.PopMatrix(); - - GL.Disable(EnableCap.Blend); - GL.BindTexture(TextureTarget.Texture2D, 0); + dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing + dc.Wy2 += space + height; // Move from end of rect + dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2) + if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something + _DrawTexture(texture, dc, color, true); } #endregion drawing diff --git a/Vocaluxe/Lib/Draw/CTextureBase.cs b/Vocaluxe/Lib/Draw/CTextureBase.cs index eb9d11bf..ab4850b3 100644 --- a/Vocaluxe/Lib/Draw/CTextureBase.cs +++ b/Vocaluxe/Lib/Draw/CTextureBase.cs @@ -62,11 +62,11 @@ namespace Vocaluxe.Lib.Draw private void _CalcRatios() { - // OpenGL has a problem with partial (NPOT) textures, so we remove 1 pixel if (_DataSize.Width == W2) WidthRatio = 1f; else { + // OpenGL has a problem with partial (NPOT) textures, so we remove 1 pixel int mod = 0; if (_DataSize.Width > 1) mod = -1; From 158117ce31d5e10421a6cd645c4f96874a31d122 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 27 Sep 2014 16:50:00 +0200 Subject: [PATCH 5/6] Use texture alignment to reduce artifacts --- Vocaluxe/Lib/Draw/CDirect3D.cs | 10 ++++++++-- Vocaluxe/Lib/Draw/CDrawBase.cs | 7 ------- Vocaluxe/Lib/Draw/COpenGL.cs | 6 ++++++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index 8d0f4b75..4856a4d9 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -430,6 +430,12 @@ namespace Vocaluxe.Lib.Draw /// If true, then color is faded out in y direction private void _DrawTexture(CD3DTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) { + //Align the pixels because Direct3D expects the pixels to be the left top corner + dc.Wx1 -= 0.5f; + dc.Wy1 -= 0.5f; + dc.Wx2 -= 0.5f; + dc.Wy2 -= 0.5f; + color.A *= CGraphics.GlobalAlpha; int c = color.AsColor().ToArgb(); int c2; @@ -446,7 +452,7 @@ namespace Vocaluxe.Lib.Draw vert[1] = new STexturedColoredVertex(new Vector3(dc.Wx1, -dc.Wy2, dc.Wz), new Vector2(dc.Tx1, dc.Ty2), c2); vert[2] = new STexturedColoredVertex(new Vector3(dc.Wx2, -dc.Wy2, dc.Wz), new Vector2(dc.Tx2, dc.Ty2), c2); vert[3] = new STexturedColoredVertex(new Vector3(dc.Wx2, -dc.Wy1, dc.Wz), new Vector2(dc.Tx2, dc.Ty1), c); - _DrawTexture(vert, texture.D3DTexture, _CalculateRotationMatrix(dc.Rotation, dc.Wx1, dc.Wx2, dc.Wy1, dc.Wy2)); + _AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(dc.Rotation, dc.Wx1, dc.Wx2, dc.Wy1, dc.Wy2)); } /// @@ -455,7 +461,7 @@ namespace Vocaluxe.Lib.Draw /// A TexturedColoredVertex array containg 4 vertices /// The texture the vertex should be textured with /// The vertices' rotation - private void _DrawTexture(STexturedColoredVertex[] vertices, Texture tex, Matrix rotation) + private void _AddToVertexBuffer(STexturedColoredVertex[] vertices, Texture tex, Matrix rotation) { //The vertexbuffer is full, so we need to flush it before we can continue if (_Vertices.Count >= CSettings.VertexBufferElements) diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs index 19017a5f..c5688320 100644 --- a/Vocaluxe/Lib/Draw/CDrawBase.cs +++ b/Vocaluxe/Lib/Draw/CDrawBase.cs @@ -260,13 +260,6 @@ namespace Vocaluxe.Lib.Draw drawCoords.Ty2 = Math.Min(1, (bounds.Bottom - rect.Y) / rect.H) * texture.HeightRatio; drawCoords.Wy2 = Math.Min(rect.Bottom, bounds.Bottom); - //TODO: Check this: - /*//Align the pixels because Direct3D expects the pixels to be the left top corner - rx1 -= 0.5f; - ry1 -= 0.5f; - rx2 -= 0.5f; - ry2 -= 0.5f;*/ - if (mirrored) { float tmp = drawCoords.Ty1; diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 91cd3e31..6617466c 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -440,6 +440,12 @@ namespace Vocaluxe.Lib.Draw #region drawing private static void _DrawTexture(COGLTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) { + // Align textures to full pixels to reduce artefacts + dc.Wx1 = (float)Math.Round(dc.Wx1); + dc.Wy1 = (float)Math.Round(dc.Wy1); + dc.Wx2 = (float)Math.Round(dc.Wx2); + dc.Wy2 = (float)Math.Round(dc.Wy2); + GL.BindTexture(TextureTarget.Texture2D, texture.Name); GL.Enable(EnableCap.Blend); From 94d3bed47109c8af03af155b21afc89e26443f8e Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 27 Sep 2014 16:56:37 +0200 Subject: [PATCH 6/6] Move same methods to base class --- Vocaluxe/Lib/Draw/CDirect3D.cs | 103 +-------------------------------- Vocaluxe/Lib/Draw/CDrawBase.cs | 103 ++++++++++++++++++++++++++++++++- Vocaluxe/Lib/Draw/COpenGL.cs | 96 +----------------------------- 3 files changed, 104 insertions(+), 198 deletions(-) diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index 4856a4d9..81a69d89 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -15,7 +15,6 @@ // along with Vocaluxe. If not, see . #endregion -using System.Diagnostics; using SlimDX; using SlimDX.Direct3D9; using System; @@ -428,7 +427,7 @@ namespace Vocaluxe.Lib.Draw /// Coordinates to draw on /// Color to use /// If true, then color is faded out in y direction - private void _DrawTexture(CD3DTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) + protected override void _DrawTexture(CD3DTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) { //Align the pixels because Direct3D expects the pixels to be the left top corner dc.Wx1 -= 0.5f; @@ -617,106 +616,6 @@ namespace Vocaluxe.Lib.Draw } texture.D3DTexture.UnlockRectangle(0); } - - #region drawing - /// - /// Draws a texture - /// - /// The texture to be drawn - /// A SRectF struct containing the destination coordinates - /// A SColorF struct containing a color which the texture will be colored in - /// True if the texture should be mirrored - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) - { - if (Math.Abs(color.A) < 0.01) - return; - SDrawCoords dc; - CD3DTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, out dc, mirrored)) - return; - - _DrawTexture(texture, dc, color); - } - - /// - /// Draws a texture - /// - /// The texture to be drawn - /// A SRectF struct containing the destination coordinates - /// A SColorF struct containing a color which the texture will be colored in - /// A SRectF struct containing which part of the texture should be drawn - /// True if the texture should be mirrored - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) - { - if (Math.Abs(color.A) < 0.01) - return; - SDrawCoords dc; - CD3DTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, bounds, out dc)) - return; - - _DrawTexture(texture, dc, color); - } - - /// - /// Draws a texture - /// - /// The texture to be drawn - /// A SRectF struct containing the destination coordinates - /// A SColorF struct containing a color which the texture will be colored in - /// A Value ranging from 0 to 1 containing the beginning of the texture - /// A Value ranging from 0 to 1 containing the ending of the texture - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end) - { - if (Math.Abs(color.A) < 0.01) - return; - SDrawCoords dc; - CD3DTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end)) - return; - - _DrawTexture(texture, dc, color); - } - - /// - /// Draws a reflection of a texture - /// - /// The texture of which a reflection should be drawn - /// A SRectF struct containing the destination coordinates - /// A SColorF struct containing a color which the texture will be colored in - /// A SRectF struct containing which part of the texture should be drawn - /// The space between the texture and the reflection - /// The height of the reflection - public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) - { - Debug.Assert(height >= 0); - - if (Math.Abs(color.A) < 0.01 || height < 1) - return; - SDrawCoords dc; - CD3DTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, bounds, out dc, true)) - return; - - if (height > rect.H) - height = rect.H; - - dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing - dc.Wy2 += space + height; // Move from end of rect - dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2) - if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something - _DrawTexture(texture, dc, color, true); - } - #endregion drawing - #endregion Textures private static Matrix _CalculateRotationMatrix(float rot, float rx1, float rx2, float ry1, float ry2) diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs index c5688320..d44322be 100644 --- a/Vocaluxe/Lib/Draw/CDrawBase.cs +++ b/Vocaluxe/Lib/Draw/CDrawBase.cs @@ -212,7 +212,7 @@ namespace Vocaluxe.Lib.Draw #region Textures - #region private/protected + #region drawing /// /// Struct that contains texture and world coordinates for drawing /// @@ -229,6 +229,15 @@ namespace Vocaluxe.Lib.Draw public float Rotation; } + /// + /// Adds a texture to the vertext buffer + /// + /// Texture to draw + /// Coordinates to draw on + /// Color to use + /// If true, then color is faded out in y direction + protected abstract void _DrawTexture(TTextureType texture, SDrawCoords dc, SColorF color, bool isReflection = false); + /// /// Calculates the texture and world coordinates for drawing the texture in the rect cropping at the the bounds /// @@ -316,6 +325,98 @@ namespace Vocaluxe.Lib.Draw return true; } + public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) + { + if (Math.Abs(color.A) < 0.01) + return; + SDrawCoords dc; + TTextureType texture; + if (!_GetTexture(textureRef, out texture)) + return; + if (!_CalcDrawCoords(texture, rect, out dc, mirrored)) + return; + + _DrawTexture(texture, dc, color); + } + + /// + /// Draws a texture + /// + /// The texture to be drawn + /// A SRectF struct containing the destination coordinates + /// A SColorF struct containing a color which the texture will be colored in + /// A SRectF struct containing which part of the texture should be drawn + /// True if the texture should be mirrored + public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) + { + if (Math.Abs(color.A) < 0.01) + return; + SDrawCoords dc; + TTextureType texture; + if (!_GetTexture(textureRef, out texture)) + return; + if (!_CalcDrawCoords(texture, rect, bounds, out dc)) + return; + + _DrawTexture(texture, dc, color); + } + + /// + /// Draws a texture + /// + /// The texture to be drawn + /// A SRectF struct containing the destination coordinates + /// A SColorF struct containing a color which the texture will be colored in + /// A Value ranging from 0 to 1 containing the beginning of the texture + /// A Value ranging from 0 to 1 containing the ending of the texture + public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end) + { + if (Math.Abs(color.A) < 0.01) + return; + SDrawCoords dc; + TTextureType texture; + if (!_GetTexture(textureRef, out texture)) + return; + if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end)) + return; + + _DrawTexture(texture, dc, color); + } + + /// + /// Draws a reflection of a texture + /// + /// The texture of which a reflection should be drawn + /// A SRectF struct containing the destination coordinates + /// A SColorF struct containing a color which the texture will be colored in + /// A SRectF struct containing which part of the texture should be drawn + /// The space between the texture and the reflection + /// The height of the reflection + public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) + { + Debug.Assert(height >= 0); + + if (Math.Abs(color.A) < 0.01 || height < 1) + return; + SDrawCoords dc; + TTextureType texture; + if (!_GetTexture(textureRef, out texture)) + return; + if (!_CalcDrawCoords(texture, rect, bounds, out dc, true)) + return; + + if (height > rect.H) + height = rect.H; + + dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing + dc.Wy2 += space + height; // Move from end of rect + dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2) + if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something + _DrawTexture(texture, dc, color, true); + } + #endregion drawing + + #region private/protected /// /// Returns the maximum area allowed for a texture based on the current quality /// diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 6617466c..1981f2f7 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -15,7 +15,6 @@ // along with Vocaluxe. If not, see . #endregion -using System.Diagnostics; using System.Drawing.Imaging; using OpenTK; using OpenTK.Graphics; @@ -437,8 +436,7 @@ namespace Vocaluxe.Lib.Draw GL.BindTexture(TextureTarget.Texture2D, 0); } - #region drawing - private static void _DrawTexture(COGLTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) + protected override void _DrawTexture(COGLTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false) { // Align textures to full pixels to reduce artefacts dc.Wx1 = (float)Math.Round(dc.Wx1); @@ -486,98 +484,6 @@ namespace Vocaluxe.Lib.Draw GL.Disable(EnableCap.Blend); GL.BindTexture(TextureTarget.Texture2D, 0); } - - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) - { - if (Math.Abs(color.A) < 0.01) - return; - SDrawCoords dc; - COGLTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, out dc, mirrored)) - return; - - _DrawTexture(texture, dc, color); - } - - /// - /// Draws a texture - /// - /// The texture to be drawn - /// A SRectF struct containing the destination coordinates - /// A SColorF struct containing a color which the texture will be colored in - /// A SRectF struct containing which part of the texture should be drawn - /// True if the texture should be mirrored - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) - { - if (Math.Abs(color.A) < 0.01) - return; - SDrawCoords dc; - COGLTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, bounds, out dc)) - return; - - _DrawTexture(texture, dc, color); - } - - /// - /// Draws a texture - /// - /// The texture to be drawn - /// A SRectF struct containing the destination coordinates - /// A SColorF struct containing a color which the texture will be colored in - /// A Value ranging from 0 to 1 containing the beginning of the texture - /// A Value ranging from 0 to 1 containing the ending of the texture - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end) - { - if (Math.Abs(color.A) < 0.01) - return; - SDrawCoords dc; - COGLTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end)) - return; - - _DrawTexture(texture, dc, color); - } - - /// - /// Draws a reflection of a texture - /// - /// The texture of which a reflection should be drawn - /// A SRectF struct containing the destination coordinates - /// A SColorF struct containing a color which the texture will be colored in - /// A SRectF struct containing which part of the texture should be drawn - /// The space between the texture and the reflection - /// The height of the reflection - public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) - { - Debug.Assert(height >= 0); - - if (Math.Abs(color.A) < 0.01 || height < 1) - return; - SDrawCoords dc; - COGLTexture texture; - if (!_GetTexture(textureRef, out texture)) - return; - if (!_CalcDrawCoords(texture, rect, bounds, out dc, true)) - return; - - if (height > rect.H) - height = rect.H; - - dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing - dc.Wy2 += space + height; // Move from end of rect - dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2) - if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something - _DrawTexture(texture, dc, color, true); - } - #endregion drawing - #endregion Textures #endregion implementation