diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs
index 9e7a6193..919fdef7 100644
--- a/Vocaluxe/Lib/Draw/CDirect3D.cs
+++ b/Vocaluxe/Lib/Draw/CDirect3D.cs
@@ -46,11 +46,11 @@ namespace Vocaluxe.Lib.Draw
{
public readonly Texture D3DTexture;
- public CD3DTexture(Device device, Size dataSize, int texWidth = 0, int texHeight = 0) : base(dataSize, texWidth, texHeight)
+ public CD3DTexture(Device device, Size dataSize, int texWidth = 0, int texHeight = 0) : base(dataSize, new Size(texWidth, texHeight))
{
//Create a new texture in the managed pool, which does not need to be recreated on a lost device
//because a copy of the texture is hold in the Ram
- D3DTexture = device == null ? null : new Texture(device, W2, H2, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed);
+ D3DTexture = device == null ? null : new Texture(device, texWidth, texHeight, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed);
}
public override bool IsLoaded
diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs
index cefca707..c00535d7 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;
@@ -61,14 +62,14 @@ namespace Vocaluxe.Lib.Draw
//The texture "name" according to the specs
public readonly int Name;
- public COGLTexture(int name, Size dataSize, int texWidth = 0, int texHeight = 0) : base(dataSize, texWidth, texHeight)
+ public COGLTexture(int name, Size dataSize, int texWidth = 0, int texHeight = 0) : base(dataSize, new Size(texWidth, texHeight))
{
Name = name;
if (name == 0)
return;
GL.BindTexture(TextureTarget.Texture2D, Name);
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, W2, H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texWidth, texHeight, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
@@ -94,6 +95,7 @@ namespace Vocaluxe.Lib.Draw
class COpenGL : CDrawBaseWindows, IDraw
{
private readonly GLControl _Control;
+ private int _FBO;
public COpenGL()
{
@@ -233,9 +235,17 @@ namespace Vocaluxe.Lib.Draw
GL.Enable(EnableCap.DepthTest);
GL.ClearColor(Color.Black);
+ GL.GenFramebuffers(1, out _FBO);
+
return true;
}
+ public override void Unload()
+ {
+ base.Unload();
+ GL.DeleteFramebuffers(1, ref _FBO);
+ }
+
protected override void _OnBeforeDraw()
{
//Nothing to do
@@ -400,8 +410,23 @@ namespace Vocaluxe.Lib.Draw
return texture;
}
+ private void _ClearTexture(COGLTexture texture)
+ {
+ if (texture.DataSize.Equals(texture.Size))
+ return;
+ GL.BindFramebuffer(OpenTK.Graphics.OpenGL.FramebufferTarget.Framebuffer, _FBO);
+ GL.FramebufferTexture2D(OpenTK.Graphics.OpenGL.FramebufferTarget.Framebuffer, OpenTK.Graphics.OpenGL.FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D,
+ texture.Name, 0);
+ GL.ClearColor(Color.FromArgb(0));
+ GL.Clear(ClearBufferMask.ColorBufferBit);
+ GL.ClearColor(Color.Black);
+ GL.BindFramebuffer(OpenTK.Graphics.OpenGL.FramebufferTarget.Framebuffer, 0);
+ }
+
protected override void _WriteDataToTexture(COGLTexture texture, byte[] data)
{
+ Debug.Assert(texture.Name > 0);
+ _ClearTexture(texture);
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.DataSize.Width, texture.DataSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
@@ -412,6 +437,8 @@ namespace Vocaluxe.Lib.Draw
protected override void _WriteDataToTexture(COGLTexture texture, IntPtr data)
{
+ Debug.Assert(texture.Name > 0);
+ _ClearTexture(texture);
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.DataSize.Width, texture.DataSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
diff --git a/Vocaluxe/Lib/Draw/CTextureBase.cs b/Vocaluxe/Lib/Draw/CTextureBase.cs
index ab4850b3..385c1227 100644
--- a/Vocaluxe/Lib/Draw/CTextureBase.cs
+++ b/Vocaluxe/Lib/Draw/CTextureBase.cs
@@ -23,13 +23,9 @@ namespace Vocaluxe.Lib.Draw
}
///
- /// texture width (on device), a power of 2 if necessary
+ /// texture Size (on device), a power of 2 if necessary
///
- public int W2 { get; protected set; }
- ///
- /// texture height (on device), a power of 2 if necessary
- ///
- public int H2 { get; protected set; }
+ public Size Size { get; private set; }
///
/// Specifies which part of texture memory is actually used
@@ -49,38 +45,25 @@ namespace Vocaluxe.Lib.Draw
/// Creates a new texture
///
/// Size of the data used
- /// Width in video memory
- /// Height in video memory
- protected CTextureBase(Size dataSize, int texWidth = 0, int texHeight = 0)
+ /// Size in video memory
+ protected CTextureBase(Size dataSize, Size textureSize)
{
_DataSize = dataSize;
- W2 = (texWidth > 0) ? texWidth : dataSize.Width;
- H2 = (texHeight > 0) ? texHeight : dataSize.Height;
+ Size = textureSize;
_CalcRatios();
}
private void _CalcRatios()
{
- if (_DataSize.Width == W2)
+ if (_DataSize.Width == Size.Width)
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;
- WidthRatio = (float)(_DataSize.Width + mod) / W2;
- }
- if (_DataSize.Height == H2)
+ WidthRatio = (float)_DataSize.Width / Size.Width;
+ if (_DataSize.Height == Size.Height)
HeightRatio = 1f;
else
- {
- int mod = 0;
- if (_DataSize.Height > 1)
- mod = -1;
- HeightRatio = (float)(_DataSize.Height + mod) / H2;
- }
+ HeightRatio = (float)_DataSize.Height / Size.Height;
}
private bool _IsDisposed;
diff --git a/Vocaluxe/Lib/Draw/CTextureProvider.cs b/Vocaluxe/Lib/Draw/CTextureProvider.cs
index 8a2f31a0..0c863979 100644
--- a/Vocaluxe/Lib/Draw/CTextureProvider.cs
+++ b/Vocaluxe/Lib/Draw/CTextureProvider.cs
@@ -388,15 +388,15 @@ namespace Vocaluxe.Lib.Draw
return _GetTextureReference(new Size(origWidth, origHeight), texture);
}
- private static bool _IsTextureUsable(TTextureType texture, int dataWidth, int dataHeight)
+ private static bool _IsTextureUsable(TTextureType texture, Size dataSize)
{
if (texture == null)
return false;
- if (texture.DataSize.Width != dataWidth || texture.DataSize.Height != dataHeight)
+ if (!texture.DataSize.Equals(dataSize))
{
- if (texture.W2 > dataWidth || texture.H2 > dataHeight)
+ if (texture.Size.Width < dataSize.Width || texture.Size.Height < dataSize.Height)
return false; // Texture memory to small
- if (texture.W2 * 0.9 < dataWidth || texture.H2 * 0.9 < dataHeight)
+ if (texture.Size.Width * 0.9 > dataSize.Width || texture.Size.Height * 0.9 > dataSize.Height)
return false; // Texture memory to big
}
return true;
@@ -491,7 +491,7 @@ namespace Vocaluxe.Lib.Draw
bmp.Dispose();
}
else if (q.Data is byte[])
- UpdateTexture(textureRef, q.DataSize.Width, q.DataSize.Height, (byte[])q.Data);
+ UpdateTexture(textureRef, q.DataSize, (byte[])q.Data);
else
throw new ArgumentException("q.Data is of invalid type");
// ReSharper restore CanBeReplacedWithTryCastAndCheckForNull
@@ -776,30 +776,34 @@ namespace Vocaluxe.Lib.Draw
_EnqueueTextureAddOrUpdate(textureRef, bmp, EQueueAction.Update, true);
}
+ public void UpdateTexture(CTextureRef textureRef, int w, int h, byte[] data)
+ {
+ UpdateTexture(textureRef, new Size(w, h), data);
+ }
+
///
/// Updates the data of a texture
///
/// The texture to update
- ///
- ///
+ ///
/// A byte array containing the new texture's data
/// True if succeeded
- public void UpdateTexture(CTextureRef textureRef, int w, int h, byte[] data)
+ public void UpdateTexture(CTextureRef textureRef, Size dataSize, byte[] data)
{
_EnsureMainThread();
TTextureType texture;
if (!_GetTexture(textureRef, out texture, false))
return;
- bool reuseTexture = _IsTextureUsable(texture, w, h);
+ bool reuseTexture = _IsTextureUsable(texture, dataSize);
if (reuseTexture && texture.RefCount == 1)
{
- texture.DataSize = new Size(w, h);
+ texture.DataSize = dataSize;
_WriteDataToTexture(texture, data);
}
else
{
_DisposeTexture(texture);
- texture = _CreateAndFillTexture(new Size(w, h), data);
+ texture = _CreateAndFillTexture(dataSize, data);
texture.RefCount = 1;
_Textures[textureRef.ID] = texture;
}
@@ -811,7 +815,7 @@ namespace Vocaluxe.Lib.Draw
TTextureType texture;
if (!_GetTexture(textureRef, out texture, false))
return;
- bool reuseTexture = _IsTextureUsable(texture, bmp.Width, bmp.Height);
+ bool reuseTexture = _IsTextureUsable(texture, bmp.Size);
if (reuseTexture && texture.RefCount == 1)
_WriteBitmapToTexture(ref texture, bmp);
else