diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs
index 9c123131..0aa91787 100644
--- a/Vocaluxe/Lib/Draw/CDirect3D.cs
+++ b/Vocaluxe/Lib/Draw/CDirect3D.cs
@@ -210,7 +210,7 @@ namespace Vocaluxe.Lib.Draw
_PresentParameters.BackBufferHeight = _Form.ClientSize.Height;
if (_Run)
{
- ClearScreen();
+ _ClearScreen();
//To set new PresentParameters the device has to be resetted
_Reset();
//All configurations got flushed due to Reset(), so apply them again
@@ -469,7 +469,7 @@ namespace Vocaluxe.Lib.Draw
///
/// Removes all textures from the screen
///
- public override void ClearScreen()
+ protected override void _ClearScreen()
{
if (_Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0).IsFailure)
CLog.LogError("Failed to clear the backbuffer");
diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs
index 78f1598d..1eca5564 100644
--- a/Vocaluxe/Lib/Draw/CDrawBase.cs
+++ b/Vocaluxe/Lib/Draw/CDrawBase.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
-using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
@@ -88,7 +87,7 @@ namespace Vocaluxe.Lib.Draw
protected int _BorderBottom;
protected EGeneralAlignment _CurrentAlignment = EGeneralAlignment.Middle;
- public abstract void ClearScreen();
+ protected abstract void _ClearScreen();
protected abstract void _AdjustNewBorders();
protected abstract void _LeaveFullScreen();
@@ -174,6 +173,63 @@ namespace Vocaluxe.Lib.Draw
#region Textures
#region private/protected
+ ///
+ /// Returns the maximum area allowed for a texture based on the current quality
+ ///
+ ///
+ private static int _GetMaxTextureArea()
+ {
+ switch (CConfig.TextureQuality)
+ {
+ case ETextureQuality.TR_CONFIG_TEXTURE_LOWEST:
+ return 128 * 128;
+ case ETextureQuality.TR_CONFIG_TEXTURE_LOW:
+ return 256 * 128;
+ case ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM:
+ return 512 * 256;
+ case ETextureQuality.TR_CONFIG_TEXTURE_HIGH:
+ return 1024 * 512;
+ case ETextureQuality.TR_CONFIG_TEXTURE_HIGHEST:
+ return CSettings.RenderW * CSettings.RenderH;
+ default:
+ throw new ArgumentException();
+ }
+ }
+
+ ///
+ /// Calculates the size for a new texture using the quality and smart values for rescaling
+ ///
+ /// New size for the texture
+ private Size _GetNewTextureSize(Size size)
+ {
+ Debug.Assert(size.Width > 0 && size.Height > 0);
+ int maxArea = _GetMaxTextureArea();
+ int curArea = size.Width * size.Height;
+ if (curArea <= maxArea)
+ return size;
+ double factor = Math.Sqrt((double)maxArea / curArea);
+ Size newSize = new Size((int)(size.Width * factor), (int)(size.Height * factor));
+ if (!_NonPowerOf2TextureSupported)
+ {
+ if (size.Width < size.Height)
+ {
+ newSize.Width = _CheckForNextPowerOf2(newSize.Width);
+ newSize.Height = _CheckForNextPowerOf2(maxArea / newSize.Width);
+ if (newSize.Width * newSize.Height > maxArea)
+ newSize.Height /= 2;
+ }
+ else
+ {
+ newSize.Height = _CheckForNextPowerOf2(newSize.Height);
+ newSize.Width = _CheckForNextPowerOf2(maxArea / newSize.Height);
+ if (newSize.Width * newSize.Height > maxArea)
+ newSize.Width /= 2;
+ }
+ }
+ Debug.Assert(newSize.Width * newSize.Height <= maxArea);
+ return newSize;
+ }
+
protected abstract void _WriteDataToTexture(TTextureType texture, byte[] data);
protected virtual void _WriteDataToTexture(TTextureType texture, IntPtr data)
@@ -211,56 +267,18 @@ namespace Vocaluxe.Lib.Draw
///
private void _WriteBitmapToTexture(ref TTextureType texture, Bitmap bmp)
{
- int maxSize;
- //Apply the right max size
- switch (CConfig.TextureQuality)
- {
- case ETextureQuality.TR_CONFIG_TEXTURE_LOWEST:
- maxSize = 128;
- break;
- case ETextureQuality.TR_CONFIG_TEXTURE_LOW:
- maxSize = 256;
- break;
- case ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM:
- maxSize = 512;
- break;
- case ETextureQuality.TR_CONFIG_TEXTURE_HIGH:
- maxSize = 1024;
- break;
- case ETextureQuality.TR_CONFIG_TEXTURE_HIGHEST:
- maxSize = 2048;
- break;
- default:
- maxSize = 512;
- break;
- }
-
- // Make sure maxSize is a power of 2 if required
- maxSize = _CheckForNextPowerOf2(maxSize);
-
Bitmap bmp2 = null;
try
{
- // Do not stretch the texture, only make it smaller
- int w = Math.Min(bmp.Width, maxSize);
- int h = Math.Min(bmp.Height, maxSize);
- if (bmp.Width != w || bmp.Height != h)
+ Size size = _GetNewTextureSize(bmp.GetSize());
+ if (!size.Equals(bmp.GetSize()))
{
- //Create a new Bitmap with the new sizes
- bmp2 = new Bitmap(w, h);
- //Scale the texture
- using (Graphics g = Graphics.FromImage(bmp2))
- {
- g.InterpolationMode = InterpolationMode.HighQualityBicubic;
- g.SmoothingMode = SmoothingMode.HighQuality;
- g.DrawImage(bmp, new Rectangle(0, 0, bmp2.Width, bmp2.Height));
- }
+ bmp2 = bmp.Resize(size);
bmp = bmp2;
}
//Fill the new Bitmap with the texture data
- BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
- Size size = new Size(w, h);
+ BitmapData bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
if (texture == null)
texture = _CreateTexture(size);
else
@@ -624,7 +642,7 @@ namespace Vocaluxe.Lib.Draw
_OnBeforeDraw();
//Clear the previous Frame
- ClearScreen();
+ _ClearScreen();
if (!CGraphics.Draw())
_Run = false;
_OnAfterDraw();
diff --git a/Vocaluxe/Lib/Draw/CDrawBaseWindows.cs b/Vocaluxe/Lib/Draw/CDrawBaseWindows.cs
index eb3a4b5e..e387281b 100644
--- a/Vocaluxe/Lib/Draw/CDrawBaseWindows.cs
+++ b/Vocaluxe/Lib/Draw/CDrawBaseWindows.cs
@@ -105,7 +105,7 @@ namespace Vocaluxe.Lib.Draw
private void _OnLoad(object sender, EventArgs e)
{
- ClearScreen();
+ _ClearScreen();
}
protected virtual void _OnResize(object sender, EventArgs e)
diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs
index 39730246..997bd148 100644
--- a/Vocaluxe/Lib/Draw/COpenGL.cs
+++ b/Vocaluxe/Lib/Draw/COpenGL.cs
@@ -254,7 +254,7 @@ namespace Vocaluxe.Lib.Draw
return _Control.Height;
}
- public override void ClearScreen()
+ protected override void _ClearScreen()
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
}
diff --git a/VocaluxeLib/Extensions.cs b/VocaluxeLib/Extensions.cs
index 80d0ce3e..3716cbb5 100644
--- a/VocaluxeLib/Extensions.cs
+++ b/VocaluxeLib/Extensions.cs
@@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
+using System.Drawing.Drawing2D;
using System.Globalization;
using System.Linq;
@@ -143,7 +144,39 @@ namespace VocaluxeLib
public static Rectangle GetRect(this Bitmap bmp)
{
- return new Rectangle(0, 0, bmp.Width, bmp.Height);
+ return Rectangle.Round(new Rectangle(0, 0, bmp.Width, bmp.Height));
+ }
+
+ ///
+ /// Resizes the bitmap to the given size creating a copy of it
+ ///
+ ///
+ ///
+ /// Resized bitmap or null on error
+ public static Bitmap Resize(this Bitmap bmp, Size newSize)
+ {
+ Bitmap result = null;
+ try
+ {
+ //Create a new Bitmap with the new sizes
+ result = new Bitmap(newSize.Width, newSize.Height);
+ //Scale the texture
+ using (Graphics g = Graphics.FromImage(result))
+ {
+ g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ g.SmoothingMode = SmoothingMode.HighQuality;
+ g.DrawImage(bmp, result.GetRect());
+ }
+ }
+ catch (Exception)
+ {
+ if (result != null)
+ {
+ result.Dispose();
+ result = null;
+ }
+ }
+ return result;
}
}
}
\ No newline at end of file