diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs
index ca6c771a..aa337fe0 100644
--- a/Vocaluxe/Lib/Draw/CDirect3D.cs
+++ b/Vocaluxe/Lib/Draw/CDirect3D.cs
@@ -15,13 +15,10 @@
// along with Vocaluxe. If not, see .
#endregion
-using System.Drawing.Drawing2D;
-using System.Threading;
using SlimDX;
using SlimDX.Direct3D9;
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
@@ -34,33 +31,26 @@ using VocaluxeLib.Draw;
namespace Vocaluxe.Lib.Draw
{
- class CRenderFormHook : RenderForm, CDrawBaseWindows.IFormHook
+ class CRenderFormHook : RenderForm, IFormHook
{
- public CDrawBaseWindows.MessageEventHandler OnMessage { private get; set; }
+ public MessageEventHandler OnMessage { private get; set; }
protected override void WndProc(ref Message m)
{
- if (OnMessage(ref m))
+ if (OnMessage == null || OnMessage(ref m))
base.WndProc(ref m);
}
}
- class CDirect3D : CDrawBaseWindows, IDraw
+ class CDirect3D : CDrawBaseWindows, IDraw
{
#region private vars
- private readonly CKeys _Keys;
- private readonly CMouse _Mouse;
- private bool _Run;
-
private readonly Direct3D _D3D;
private readonly Device _Device;
private readonly PresentParameters _PresentParameters;
private Size _SizeBeforeMinimize;
- private readonly Dictionary _D3DTextures = new Dictionary();
- private readonly Queue _TexturesToLoad = new Queue();
-
private VertexBuffer _VertexBuffer;
private IndexBuffer _IndexBuffer;
@@ -69,16 +59,11 @@ namespace Vocaluxe.Lib.Draw
private int _Y;
private int _X;
- private int _BorderLeft;
- private int _BorderRight;
- private int _BorderTop;
- private int _BorderBottom;
-
private CTexture _BlankTexture;
private readonly Queue _Vertices = new Queue();
private readonly Queue _VerticesTextures = new Queue();
- private readonly Queue _VerticesRotationMatrices = new Queue();
+ private readonly Queue _VerticesRotationMatrices = new Queue();
#endregion private vars
///
@@ -87,7 +72,6 @@ namespace Vocaluxe.Lib.Draw
public CDirect3D()
{
_Form = new CRenderFormHook();
- _Keys = new CKeys();
try
{
_D3D = new Direct3D();
@@ -97,17 +81,11 @@ namespace Vocaluxe.Lib.Draw
CLog.LogError("No DirectX runtimes were found, please download and install them from http://www.microsoft.com/download/en/details.aspx?id=8109", true, true, e);
}
- _Form.Closing += _OnClosingEvent;
- _Form.Resize += _OnResize;
- _Form.Load += _OnLoad;
-
-
_Form.KeyDown += _OnKeyDown;
_Form.PreviewKeyDown += _OnPreviewKeyDown;
_Form.KeyPress += _OnKeyPress;
_Form.KeyUp += _OnKeyUp;
- _Mouse = new CMouse();
_Form.MouseMove += _OnMouseMove;
_Form.MouseWheel += _OnMouseWheel;
_Form.MouseDown += _OnMouseDown;
@@ -184,6 +162,10 @@ namespace Vocaluxe.Lib.Draw
{
_Device = new Device(_D3D, _D3D.Adapters.DefaultAdapter.Adapter, DeviceType.Hardware, _Form.Handle, flags, _PresentParameters);
}
+ catch (Exception e)
+ {
+ CLog.LogError("Error during D3D device creation.", false, false, e);
+ }
finally
{
if (_Device == null || _Device.Disposed)
@@ -198,20 +180,6 @@ namespace Vocaluxe.Lib.Draw
}
#region form events
- private void _OnClosingEvent(object sender, CancelEventArgs e)
- {
- _Run = false;
- }
-
- private void _OnLoad(object sender, EventArgs e)
- {
- _Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
- }
-
- private void _OnResize(object sender, EventArgs e)
- {
- _DoResize();
- }
#endregion form events
#region resize
@@ -273,62 +241,6 @@ namespace Vocaluxe.Lib.Draw
// ReSharper restore RedundantOverridenMember
#endregion resize
- #region mouse event handlers
- private void _OnMouseMove(object sender, MouseEventArgs e)
- {
- _Mouse.MouseMove(e);
- }
-
- private void _OnMouseWheel(object sender, MouseEventArgs e)
- {
- _Mouse.MouseWheel(e);
- }
-
- private void _OnMouseDown(object sender, MouseEventArgs e)
- {
- _Mouse.MouseDown(e);
- }
-
- private void _OnMouseUp(object sender, MouseEventArgs e)
- {
- _Mouse.MouseUp(e);
- }
-
- private void _OnMouseLeave(object sender, EventArgs e)
- {
- _Mouse.Visible = false;
- Cursor.Show();
- }
-
- private void _OnMouseEnter(object sender, EventArgs e)
- {
- Cursor.Hide();
- _Mouse.Visible = true;
- }
- #endregion
-
- #region keyboard event handlers
- private void _OnPreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
- {
- _OnKeyDown(sender, new KeyEventArgs(e.KeyData));
- }
-
- private void _OnKeyDown(object sender, KeyEventArgs e)
- {
- _Keys.KeyDown(e);
- }
-
- private void _OnKeyPress(object sender, KeyPressEventArgs e)
- {
- _Keys.KeyPress(e);
- }
-
- private void _OnKeyUp(object sender, KeyEventArgs e)
- {
- _Keys.KeyUp(e);
- }
- #endregion keyboard event handlers
-
#region implementation
#region main stuff
@@ -359,9 +271,9 @@ namespace Vocaluxe.Lib.Draw
CLog.LogError("Failed to enable alpha blending");
if (_Device.SetRenderState(RenderState.Lighting, false).IsFailure)
CLog.LogError("Failed to disable lighting");
- if (_Device.SetRenderState(RenderState.DestinationBlend, SlimDX.Direct3D9.Blend.InverseSourceAlpha).IsFailure)
+ if (_Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha).IsFailure)
CLog.LogError("Failed to set destination blend");
- if (_Device.SetRenderState(RenderState.SourceBlend, SlimDX.Direct3D9.Blend.SourceAlpha).IsFailure)
+ if (_Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha).IsFailure)
CLog.LogError("Failed to set source blend");
if (_PresentParameters.Multisample != MultisampleType.None)
{
@@ -412,84 +324,35 @@ namespace Vocaluxe.Lib.Draw
return true;
}
- ///
- /// Starts the rendering
- ///
- public void MainLoop()
+ protected override void _OnBeforeDraw()
{
- _Run = true;
- int delay = 0;
- _Form.Show();
+ if (_Device.BeginScene().IsFailure)
+ CLog.LogError("Failed to begin scene");
+ }
- if (CConfig.FullScreen == EOffOn.TR_CONFIG_ON)
- _EnterFullScreen();
-
- //Resize window if aspect ratio is incorrect
- if (Math.Abs(_W / (float)_H - CSettings.GetRenderAspect()) > 0.01)
- _DoResize();
-
- while (_Run)
+ protected override void _OnAfterDraw()
+ {
+ _RenderVertexBuffer();
+ if (_Device.EndScene().IsFailure)
+ CLog.LogError("Failed to end scene");
+ try
{
- Application.DoEvents();
- //Clear the previous Frame
- ClearScreen();
- //We want to begin drawing
- if (_Device.BeginScene().IsFailure)
- CLog.LogError("Failed to begin scene");
- _CheckQueue();
- if (!CGraphics.Draw())
- _Run = false;
- _RenderVertexBuffer();
- //We finished drawing the frame
- if (_Device.EndScene().IsFailure)
- CLog.LogError("Failed to end scene");
- if (!CGraphics.UpdateGameLogic(_Keys, _Mouse))
- _Run = false;
- try
- {
- //Now push the frame to the Viewport
- _Device.Present();
- }
- catch (Direct3D9Exception)
- {
- //In Direct3D devices can get lost.
- //This happens for example when opening the Task Manager in Vista/Windows 7 or if a UAC message is opening
- //We need to reset the device to get it to workable state again
- //After a reset Init() needs to be called because all data in the Direct3D default pool are lost and need to be recreated
- if (_Device.TestCooperativeLevel() == ResultCode.DeviceNotReset)
- {
- _Reset();
- Init();
- }
- }
- //Apply fullscreen mode
- if ((CConfig.FullScreen == EOffOn.TR_CONFIG_ON) != _Fullscreen)
- _ToggleFullScreen();
-
- //Apply border changes
- if (_BorderLeft != CConfig.BorderLeft || _BorderRight != CConfig.BorderRight || _BorderTop != CConfig.BorderTop || _BorderBottom != CConfig.BorderBottom)
- {
- _BorderLeft = CConfig.BorderLeft;
- _BorderRight = CConfig.BorderRight;
- _BorderTop = CConfig.BorderTop;
- _BorderBottom = CConfig.BorderBottom;
-
- _AdjustNewBorders();
- }
-
- if (CConfig.VSync == EOffOn.TR_CONFIG_ON)
- {
- if (CTime.IsRunning())
- delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds());
-
- if (delay >= 1 && delay < 500)
- Thread.Sleep(delay);
- }
- //Calculate the FPS Rate and restart the timer after a frame
- CTime.CalculateFPS();
- CTime.Restart();
+ //Now push the frame to the Viewport
+ _Device.Present();
}
- _Form.Close();
+ catch (Direct3D9Exception)
+ {
+ //In Direct3D devices can get lost.
+ //This happens for example when opening the Task Manager in Vista/Windows 7 or if a UAC message is opening
+ //We need to reset the device to get it to workable state again
+ //After a reset Init() needs to be called because all data in the Direct3D default pool are lost and need to be recreated
+ if (_Device.TestCooperativeLevel() == ResultCode.DeviceNotReset)
+ {
+ _Reset();
+ Init();
+ }
+ }
+ Application.DoEvents();
}
///
@@ -505,10 +368,10 @@ namespace Vocaluxe.Lib.Draw
CLog.LogError("Failed to reset the device");
}
- private void _AdjustNewBorders()
+ protected override void _AdjustNewBorders()
{
- SlimDX.Matrix translate = SlimDX.Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0));
- SlimDX.Matrix projection = SlimDX.Matrix.OrthoOffCenterLH(
+ Matrix translate = Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0));
+ Matrix projection = Matrix.OrthoOffCenterLH(
-(float)CSettings.RenderW / 2 - _BorderLeft, (float)CSettings.RenderW / 2 + _BorderRight,
-(float)CSettings.RenderH / 2 - _BorderBottom, (float)CSettings.RenderH / 2 + _BorderTop,
CSettings.ZNear, CSettings.ZFar);
@@ -523,20 +386,9 @@ namespace Vocaluxe.Lib.Draw
/// Unloads all Textures and other objects used by Direct3D for rendering
///
///
- public void Unload()
+ public override void Unload()
{
- try
- {
- _Form.Close();
- }
- catch {}
- //Dispose all textures
- foreach (Texture texture in _D3DTextures.Values)
- {
- if (texture != null)
- texture.Dispose();
- }
-
+ base.Unload();
STexturedColoredVertex.GetDeclaration(_Device).Dispose();
_VertexBuffer.Dispose();
_IndexBuffer.Dispose();
@@ -568,7 +420,7 @@ namespace Vocaluxe.Lib.Draw
/// A TexturedColoredVertex array containg 4 vertices
/// The texture the vertex should be textured with
/// The vertices' rotation
- private void _AddToVertexBuffer(STexturedColoredVertex[] vertices, Texture tex, SlimDX.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)
@@ -617,7 +469,7 @@ namespace Vocaluxe.Lib.Draw
///
/// Removes all textures from the screen
///
- public void ClearScreen()
+ public override void ClearScreen()
{
if (_Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0).IsFailure)
CLog.LogError("Failed to clear the backbuffer");
@@ -629,16 +481,16 @@ namespace Vocaluxe.Lib.Draw
///
public CTexture CopyScreen()
{
- CTexture texture = GetNewTexture(_W, _H);
+ CTexture texture = _GetNewTextureRef(_W, _H);
Surface backbufferSurface = _Device.GetBackBuffer(0, 0);
var tex = new Texture(_Device, texture.W2, texture.H2, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed);
Surface textureSurface = tex.GetSurfaceLevel(0);
Surface.FromSurface(textureSurface, backbufferSurface, Filter.Default, 0, new Rectangle(0, 0, _W, _H), new Rectangle(0, 0, _W, _H));
backbufferSurface.Dispose();
- lock (_D3DTextures)
+ lock (_Textures)
{
- _D3DTextures.Add(texture.ID, tex);
+ _Textures.Add(texture.ID, tex);
}
return texture;
@@ -658,7 +510,7 @@ namespace Vocaluxe.Lib.Draw
else
{
Surface backbufferSurface = _Device.GetBackBuffer(0, 0);
- Surface textureSurface = _D3DTextures[texture.ID].GetSurfaceLevel(0);
+ Surface textureSurface = _Textures[texture.ID].GetSurfaceLevel(0);
Surface.FromSurface(textureSurface, backbufferSurface, Filter.Default, 0);
}
}
@@ -729,132 +581,7 @@ namespace Vocaluxe.Lib.Draw
#region Textures
#region adding
- ///
- /// Adds a texture and stores it in the VRam
- ///
- /// The texture's filepath
- /// A STexture object containing the added texture
- public CTexture AddTexture(string texturePath)
- {
- if (!File.Exists(texturePath))
- {
- CLog.LogError("Can't find File: " + texturePath);
- return null;
- }
- Bitmap bmp;
- try
- {
- bmp = new Bitmap(texturePath);
- }
- catch (Exception)
- {
- CLog.LogError("Error loading Texture: " + texturePath);
- return null;
- }
- CTexture s;
- try
- {
- s = AddTexture(bmp);
- }
- finally
- {
- bmp.Dispose();
- }
- return s;
- }
-
- ///
- /// Adds a texture and stores it in the Vram
- ///
- /// The Bitmap of which the texure will be created from
- /// A STexture object containing the added texture
- public CTexture AddTexture(Bitmap bmp)
- {
- if (bmp.Height == 0 || bmp.Width == 0)
- return null;
- 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;
- }
-
- int w = Math.Min(bmp.Width, maxSize);
- int h = Math.Min(bmp.Height, maxSize);
-
- CTexture texture = GetNewTexture(bmp.Width, bmp.Height, w, h);
-
- Bitmap bmp2 = null;
- byte[] data;
- try
- {
- w = texture.W2;
- h = texture.H2;
- if (bmp.Width != w || bmp.Height != h)
- {
- //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));
- }
- bmp = bmp2;
- texture.DataSize = new Size(w, h);
- }
-
- //Fill the new Bitmap with the texture data
- BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
- data = new byte[4 * w * h];
- Marshal.Copy(bmpData.Scan0, data, 0, data.Length);
- bmp.UnlockBits(bmpData);
- }
- finally
- {
- if (bmp2 != null)
- bmp2.Dispose();
- }
-
- return _AddTexture(texture, data);
- }
-
- public CTexture AddTexture(int w, int h, byte[] data)
- {
- CTexture texture = GetNewTexture(w, h);
- return _AddTexture(texture, data);
- }
-
- private CTexture _AddTexture(CTexture texture, byte[] data)
- {
- Texture t = _CreateTexture(texture, data);
-
- lock (_D3DTextures)
- {
- _D3DTextures.Add(texture.ID, t);
- }
- return texture;
- }
-
- private Texture _CreateTexture(CTexture texture, byte[] data)
+ protected override Texture _CreateTexture(CTexture texture, byte[] data)
{
//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
@@ -881,18 +608,6 @@ namespace Vocaluxe.Lib.Draw
}
t.UnlockRectangle(0);
}
-
- public CTexture EnqueueTexture(int w, int h, byte[] data)
- {
- CTexture texture = GetNewTexture(w, h);
-
- lock (_D3DTextures)
- {
- _D3DTextures.Add(texture.ID, null);
- _TexturesToLoad.Enqueue(new STextureQueue(texture, data));
- }
- return texture;
- }
#endregion adding
#region updating
@@ -904,7 +619,7 @@ namespace Vocaluxe.Lib.Draw
///
/// A byte array containing the new texture's data
/// True if succeeded
- public bool UpdateTexture(CTexture texture, int w, int h, byte[] data)
+ public override bool UpdateTexture(CTexture texture, int w, int h, byte[] data)
{
if (!_TextureExists(texture))
return false;
@@ -916,58 +631,14 @@ namespace Vocaluxe.Lib.Draw
return false; // Texture memory to big
texture.DataSize = new Size(w, h);
}
- lock (_D3DTextures)
+ lock (_Textures)
{
- _WriteDataToTexture(_D3DTextures[texture.ID], w, data);
- }
- return true;
- }
-
- public bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data)
- {
- if (!UpdateTexture(texture, w, h, data))
- {
- RemoveTexture(ref texture);
- texture = AddTexture(w, h, data);
+ _WriteDataToTexture(_Textures[texture.ID], w, data);
}
return true;
}
#endregion updating
- ///
- /// Checks if a texture exists
- ///
- /// The texture to check
- /// True if the texture exists
- private bool _TextureExists(CTexture texture)
- {
- lock (_D3DTextures)
- {
- return texture != null && _D3DTextures.ContainsKey(texture.ID);
- }
- }
-
- ///
- /// Removes a texture from the Vram
- ///
- /// The texture to be removed
- public void RemoveTexture(ref CTexture texture)
- {
- if (texture == null)
- return;
- lock (_D3DTextures)
- {
- Texture t;
- if (_D3DTextures.TryGetValue(texture.ID, out t))
- {
- if (t != null)
- t.Dispose();
- _D3DTextures.Remove(texture.ID);
- }
- }
- texture = null;
- }
-
#region drawing
///
/// Draws a texture
@@ -1016,7 +687,7 @@ namespace Vocaluxe.Lib.Draw
{
if (!_TextureExists(texture))
return;
- if (_D3DTextures[texture.ID] == null)
+ if (_Textures[texture.ID] == null)
return;
//Calculate the position
@@ -1081,7 +752,7 @@ namespace Vocaluxe.Lib.Draw
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, _D3DTextures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
+ _AddToVertexBuffer(vert, _Textures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
}
else
{
@@ -1090,7 +761,7 @@ namespace Vocaluxe.Lib.Draw
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, _D3DTextures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
+ _AddToVertexBuffer(vert, _Textures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
}
}
@@ -1106,7 +777,7 @@ namespace Vocaluxe.Lib.Draw
{
if (!_TextureExists(texture))
return;
- if (_D3DTextures[texture.ID] == null)
+ if (_Textures[texture.ID] == null)
return;
float x1 = 0f + begin * texture.WidthRatio;
@@ -1134,7 +805,7 @@ namespace Vocaluxe.Lib.Draw
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, _D3DTextures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
+ _AddToVertexBuffer(vert, _Textures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
}
///
@@ -1150,7 +821,7 @@ namespace Vocaluxe.Lib.Draw
{
if (!_TextureExists(texture))
return;
- if (_D3DTextures[texture.ID] == null)
+ if (_Textures[texture.ID] == null)
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 ||
@@ -1217,57 +888,33 @@ namespace Vocaluxe.Lib.Draw
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, _D3DTextures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
+ _AddToVertexBuffer(vert, _Textures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
}
#endregion drawing
- private void _CheckQueue()
- {
- lock (_D3DTextures)
- {
- while (_TexturesToLoad.Count > 0)
- {
- STextureQueue q = _TexturesToLoad.Dequeue();
- if (!_D3DTextures.ContainsKey(q.Texture.ID))
- continue;
-
- Texture t = _CreateTexture(q.Texture, q.Data);
- _D3DTextures[q.Texture.ID] = t;
- }
- }
- }
-
- ///
- /// Gets the count of current textures
- ///
- /// The amount of textures
- public int GetTextureCount()
- {
- return _D3DTextures.Count;
- }
#endregion Textures
#endregion implementation
#region utility
- private SlimDX.Matrix _CalculateRotationMatrix(float rot, float rx1, float rx2, float ry1, float ry2)
+ private static Matrix _CalculateRotationMatrix(float rot, float rx1, float rx2, float ry1, float ry2)
{
- SlimDX.Matrix originTranslation = SlimDX.Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0));
+ Matrix originTranslation = Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0));
if (Math.Abs(rot) > float.Epsilon)
{
float rotation = rot * (float)Math.PI / 180;
float centerX = (rx1 + rx2) / 2f;
float centerY = -(ry1 + ry2) / 2f;
- SlimDX.Matrix translationA = SlimDX.Matrix.Translation(-centerX, -centerY, 0);
- SlimDX.Matrix rotationMat = SlimDX.Matrix.RotationZ(-rotation);
- SlimDX.Matrix translationB = SlimDX.Matrix.Translation(centerX, centerY, 0);
+ Matrix translationA = Matrix.Translation(-centerX, -centerY, 0);
+ Matrix rotationMat = Matrix.RotationZ(-rotation);
+ Matrix translationB = Matrix.Translation(centerX, centerY, 0);
//Multiplicate the matrices to get the real world matrix,
//First shift the texture into the center
//Rotate it and shift it back to the origin position
//Apply the originTranslation after
- SlimDX.Matrix result = translationA * rotationMat * translationB * originTranslation;
+ Matrix result = translationA * rotationMat * translationB * originTranslation;
return result;
}
return originTranslation;
diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs
index 7da7073f..c1b7505a 100644
--- a/Vocaluxe/Lib/Draw/CDrawBase.cs
+++ b/Vocaluxe/Lib/Draw/CDrawBase.cs
@@ -1,20 +1,18 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
using System.IO;
-using System.Windows.Forms;
+using System.Runtime.InteropServices;
+using System.Threading;
using Vocaluxe.Base;
+using VocaluxeLib;
using VocaluxeLib.Draw;
namespace Vocaluxe.Lib.Draw
{
- struct SClientRect
- {
- public Point Location;
- public int Width;
- public int Height;
- };
-
struct STextureQueue
{
public readonly CTexture Texture;
@@ -27,104 +25,53 @@ namespace Vocaluxe.Lib.Draw
}
}
- abstract class CDrawBaseWindows : CDrawBase
- {
- public delegate bool MessageEventHandler(ref Message m);
-
- public interface IFormHook
- {
- MessageEventHandler OnMessage { set; }
- }
-
- protected Form _Form;
- private SClientRect _Restore;
-
- protected void _CenterToScreen()
- {
- Screen screen = Screen.FromControl(_Form);
- _Form.Location = new Point((screen.WorkingArea.Width - _Form.Width) / 2,
- (screen.WorkingArea.Height - _Form.Height) / 2);
- }
-
- private bool _OnMessageAvoidScreenOff(ref Message m)
- {
- switch (m.Msg)
- {
- case 0x112: // WM_SYSCOMMAND
- switch ((int)m.WParam & 0xFFF0)
- {
- case 0xF100: // SC_KEYMENU
- m.Result = IntPtr.Zero;
- return false;
- case 0xF140: // SC_SCREENSAVER
- case 0xF170: // SC_MONITORPOWER
- return false;
- }
- break;
- }
- return true;
- }
-
- protected void _ToggleFullScreen()
- {
- if (!_Fullscreen)
- _EnterFullScreen();
- else
- _LeaveFullScreen();
- }
-
- protected virtual void _EnterFullScreen()
- {
- Debug.Assert(!_Fullscreen);
- _Fullscreen = true;
-
- _Restore.Location = _Form.Location;
- _Restore.Width = _Form.Width;
- _Restore.Height = _Form.Height;
-
- _Form.FormBorderStyle = FormBorderStyle.None;
-
- Screen screen = Screen.FromControl(_Form);
- _Form.DesktopBounds = new Rectangle(screen.Bounds.Location, new Size(screen.Bounds.Width, screen.Bounds.Height));
-
- if (_Form.WindowState == FormWindowState.Maximized)
- {
- _Form.WindowState = FormWindowState.Normal;
- _DoResize();
- _Form.WindowState = FormWindowState.Maximized;
- }
- else
- _DoResize();
- }
-
- protected abstract void _DoResize();
-
- protected void _LeaveFullScreen()
- {
- Debug.Assert(_Fullscreen);
- _Fullscreen = false;
-
- _Form.FormBorderStyle = FormBorderStyle.Sizable;
- _Form.DesktopBounds = new Rectangle(_Restore.Location, new Size(_Restore.Width, _Restore.Height));
- }
-
- public virtual bool Init()
- {
- _Form.Icon = new Icon(Path.Combine(CSettings.ProgramFolder, CSettings.FileNameIcon));
- _Form.Text = CSettings.GetFullVersionText();
- ((IFormHook)_Form).OnMessage = _OnMessageAvoidScreenOff;
- return true;
- }
- }
-
- abstract class CDrawBase
+ abstract class CDrawBase where TTextureType : class, IDisposable
{
protected bool _NonPowerOf2TextureSupported;
protected bool _Fullscreen;
+ protected bool _Run;
+
+ protected readonly CKeys _Keys = new CKeys();
+ protected readonly CMouse _Mouse = new CMouse();
+
private readonly Object _MutexID = new object();
private int _NextID;
+ protected readonly Dictionary _Textures = new Dictionary();
+ private readonly Queue _TexturesToLoad = new Queue();
+
+ protected int _BorderLeft;
+ protected int _BorderRight;
+ protected int _BorderTop;
+ protected int _BorderBottom;
+
+ public abstract void ClearScreen();
+ protected abstract void _AdjustNewBorders();
+ protected abstract void _LeaveFullScreen();
+
+ protected abstract void _OnAfterDraw();
+
+ protected abstract void _OnBeforeDraw();
+
+ protected abstract void _DoResize();
+
+ protected abstract void _EnterFullScreen();
+
+ public virtual void Unload()
+ {
+ lock (_Textures)
+ {
+ //Dispose all textures
+ foreach (TTextureType texture in _Textures.Values)
+ {
+ if (texture != null)
+ texture.Dispose();
+ }
+ _Textures.Clear();
+ }
+ }
+
///
/// Calculates the next power of two if the device has the POW2 flag set
///
@@ -139,7 +86,30 @@ namespace Vocaluxe.Lib.Draw
return (int)Math.Pow(2, Math.Ceiling(Math.Log(n, 2)));
}
- public CTexture GetNewTexture(int origWidth, int origHeight, int dataWidth = 0, int dataHeight = 0)
+ #region Textures
+ ///
+ /// Creates the texture specified by the reference and fills it with the given data
+ ///
+ ///
+ ///
+ ///
+ protected abstract TTextureType _CreateTexture(CTexture texture, byte[] data);
+
+ ///
+ /// Creates the texture specified by the reference and fills it with the given data
+ /// Data has to be a pointer to an array of size W*H with 4 Byte values for each pixel (e.g. bmpData.Scan0)
+ ///
+ ///
+ ///
+ ///
+ protected virtual TTextureType _CreateTexture(CTexture texture, IntPtr data)
+ {
+ byte[] dataArray = new byte[4 * texture.DataSize.Width * texture.DataSize.Height];
+ Marshal.Copy(data, dataArray, 0, dataArray.Length);
+ return _CreateTexture(texture, dataArray);
+ }
+
+ protected CTexture _GetNewTextureRef(int origWidth, int origHeight, int dataWidth = 0, int dataHeight = 0)
{
Debug.Assert(origWidth > 0 && origHeight > 0);
Debug.Assert(dataWidth > 0 || dataHeight <= 0);
@@ -152,5 +122,301 @@ namespace Vocaluxe.Lib.Draw
Size dataSize = (dataHeight > 0) ? new Size(dataWidth, dataHeight) : origSize;
return new CTexture(id, origSize, dataSize, _CheckForNextPowerOf2(dataSize.Width), _CheckForNextPowerOf2(dataSize.Height));
}
+
+ ///
+ /// Adds a texture and stores it in the VRam
+ ///
+ /// The texture's filepath
+ /// A STexture object containing the added texture
+ public CTexture AddTexture(string texturePath)
+ {
+ if (!File.Exists(texturePath))
+ {
+ CLog.LogError("Can't find File: " + texturePath);
+ return null;
+ }
+ Bitmap bmp;
+ try
+ {
+ bmp = new Bitmap(texturePath);
+ }
+ catch (Exception)
+ {
+ CLog.LogError("Error loading Texture: " + texturePath);
+ return null;
+ }
+ CTexture s;
+ try
+ {
+ s = AddTexture(bmp);
+ }
+ finally
+ {
+ bmp.Dispose();
+ }
+ return s;
+ }
+
+ ///
+ /// Adds a texture and stores it in the Vram
+ ///
+ /// The Bitmap of which the texure will be created from
+ /// A STexture object containing the added texture
+ public CTexture AddTexture(Bitmap bmp)
+ {
+ if (bmp.Height == 0 || bmp.Width == 0)
+ return null;
+ 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;
+ }
+
+ int w = Math.Min(bmp.Width, maxSize);
+ int h = Math.Min(bmp.Height, maxSize);
+
+ CTexture texture = _GetNewTextureRef(bmp.Width, bmp.Height, w, h);
+
+ Bitmap bmp2 = null;
+ try
+ {
+ // Do not stretch the texture, only make it smaller
+ w = Math.Min(bmp.Width, texture.W2);
+ h = Math.Min(bmp.Height, texture.H2);
+ if (bmp.Width != w || bmp.Height != h)
+ {
+ //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));
+ }
+ bmp = bmp2;
+ texture.DataSize = new Size(w, h);
+ }
+
+ //Fill the new Bitmap with the texture data
+ BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
+ _AddTexture(texture, bmpData.Scan0);
+ bmp.UnlockBits(bmpData);
+ }
+ finally
+ {
+ if (bmp2 != null)
+ bmp2.Dispose();
+ }
+
+ return texture;
+ }
+
+ public CTexture AddTexture(int w, int h, byte[] data)
+ {
+ CTexture texture = _GetNewTextureRef(w, h);
+ _AddTexture(texture, data);
+ return texture;
+ }
+
+ private void _AddTexture(CTexture texture, byte[] data)
+ {
+ TTextureType t = _CreateTexture(texture, data);
+ lock (_Textures)
+ {
+ _Textures.Add(texture.ID, t);
+ }
+ }
+
+ private void _AddTexture(CTexture texture, IntPtr data)
+ {
+ TTextureType t = _CreateTexture(texture, data);
+ lock (_Textures)
+ {
+ _Textures.Add(texture.ID, t);
+ }
+ }
+
+ public CTexture EnqueueTexture(int w, int h, byte[] data)
+ {
+ CTexture texture = _GetNewTextureRef(w, h);
+
+ lock (_Textures)
+ {
+ _Textures.Add(texture.ID, null);
+ _TexturesToLoad.Enqueue(new STextureQueue(texture, data));
+ }
+ return texture;
+ }
+
+ ///
+ /// Updates the data of a texture
+ ///
+ /// The texture to update
+ ///
+ ///
+ /// A byte array containing the new texture's data
+ /// True if succeeded
+ public abstract bool UpdateTexture(CTexture texture, int w, int h, byte[] data);
+
+ public bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data)
+ {
+ if (!UpdateTexture(texture, w, h, data))
+ {
+ RemoveTexture(ref texture);
+ texture = AddTexture(w, h, data);
+ }
+ return true;
+ }
+
+ ///
+ /// Checks if a texture exists
+ ///
+ /// The texture to check
+ /// True if the texture exists
+ protected bool _TextureExists(CTexture texture)
+ {
+ lock (_Textures)
+ {
+ TTextureType t;
+ return texture != null && _Textures.TryGetValue(texture.ID, out t) && t != null;
+ }
+ }
+
+ protected TTextureType _GetTexture(CTexture textureRef)
+ {
+ TTextureType texture;
+ _Textures.TryGetValue(textureRef.ID, out texture);
+ return texture;
+ }
+
+ ///
+ /// Removes a texture from the Vram
+ ///
+ /// The texture to be removed
+ public void RemoveTexture(ref CTexture texture)
+ {
+ if (texture == null)
+ return;
+ lock (_Textures)
+ {
+ TTextureType t;
+ if (_Textures.TryGetValue(texture.ID, out t))
+ {
+ if (t != null)
+ t.Dispose();
+ _Textures.Remove(texture.ID);
+ }
+ }
+ texture = null;
+ }
+
+ protected void _CheckQueue()
+ {
+ lock (_Textures)
+ {
+ while (_TexturesToLoad.Count > 0)
+ {
+ STextureQueue q = _TexturesToLoad.Dequeue();
+ if (!_Textures.ContainsKey(q.Texture.ID))
+ continue;
+
+ TTextureType t = _CreateTexture(q.Texture, q.Data);
+ _Textures[q.Texture.ID] = t;
+ }
+ }
+ }
+
+ public int GetTextureCount()
+ {
+ return _Textures.Count;
+ }
+ #endregion
+
+ ///
+ /// Starts the rendering
+ ///
+ public virtual void MainLoop()
+ {
+ _Run = true;
+
+ _Fullscreen = false;
+ if (CConfig.FullScreen == EOffOn.TR_CONFIG_ON)
+ _EnterFullScreen();
+ else
+ _DoResize(); //Resize window if aspect ratio is incorrect
+
+ while (_Run)
+ {
+ _CheckQueue();
+
+ //We want to begin drawing
+ _OnBeforeDraw();
+
+ //Clear the previous Frame
+ ClearScreen();
+ if (!CGraphics.Draw())
+ _Run = false;
+ _OnAfterDraw();
+
+ if (!CGraphics.UpdateGameLogic(_Keys, _Mouse))
+ _Run = false;
+
+ //Apply fullscreen mode
+ if ((CConfig.FullScreen == EOffOn.TR_CONFIG_ON) != _Fullscreen)
+ _ToggleFullScreen();
+
+ //Apply border changes
+ if (_BorderLeft != CConfig.BorderLeft || _BorderRight != CConfig.BorderRight || _BorderTop != CConfig.BorderTop || _BorderBottom != CConfig.BorderBottom)
+ {
+ _BorderLeft = CConfig.BorderLeft;
+ _BorderRight = CConfig.BorderRight;
+ _BorderTop = CConfig.BorderTop;
+ _BorderBottom = CConfig.BorderBottom;
+
+ _AdjustNewBorders();
+ }
+
+ if (CConfig.VSync == EOffOn.TR_CONFIG_OFF)
+ {
+ if (CTime.IsRunning())
+ {
+ int delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds());
+
+ if (delay >= 1 && delay < 500)
+ Thread.Sleep(delay);
+ }
+ }
+ //Calculate the FPS Rate and restart the timer after a frame
+ CTime.CalculateFPS();
+ CTime.Restart();
+ }
+ }
+
+ protected void _ToggleFullScreen()
+ {
+ if (!_Fullscreen)
+ _EnterFullScreen();
+ else
+ _LeaveFullScreen();
+ }
}
}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Draw/CDrawBaseWindows.cs b/Vocaluxe/Lib/Draw/CDrawBaseWindows.cs
new file mode 100644
index 00000000..7f2c31a5
--- /dev/null
+++ b/Vocaluxe/Lib/Draw/CDrawBaseWindows.cs
@@ -0,0 +1,192 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Windows.Forms;
+using Vocaluxe.Base;
+
+namespace Vocaluxe.Lib.Draw
+{
+ public delegate bool MessageEventHandler(ref Message m);
+
+ public interface IFormHook
+ {
+ MessageEventHandler OnMessage { set; }
+ }
+
+ abstract class CDrawBaseWindows : CDrawBase where TTextureType : class, IDisposable
+ {
+ private struct SClientRect
+ {
+ public Point Location;
+ public int Width;
+ public int Height;
+ }
+
+ protected Form _Form;
+ private SClientRect _Restore;
+
+ public override void Unload()
+ {
+ base.Unload();
+ try
+ {
+ _Form.Close();
+ }
+ catch {}
+ }
+
+ protected void _CenterToScreen()
+ {
+ Screen screen = Screen.FromControl(_Form);
+ _Form.Location = new Point((screen.WorkingArea.Width - _Form.Width) / 2,
+ (screen.WorkingArea.Height - _Form.Height) / 2);
+ }
+
+ private static bool _OnMessageAvoidScreenOff(ref Message m)
+ {
+ switch (m.Msg)
+ {
+ case 0x112: // WM_SYSCOMMAND
+ switch ((int)m.WParam & 0xFFF0)
+ {
+ case 0xF100: // SC_KEYMENU
+ m.Result = IntPtr.Zero;
+ return false;
+ case 0xF140: // SC_SCREENSAVER
+ case 0xF170: // SC_MONITORPOWER
+ return false;
+ }
+ break;
+ }
+ return true;
+ }
+
+ protected override void _EnterFullScreen()
+ {
+ Debug.Assert(!_Fullscreen);
+ _Fullscreen = true;
+
+ _Restore.Location = _Form.Location;
+ _Restore.Width = _Form.Width;
+ _Restore.Height = _Form.Height;
+
+ _Form.FormBorderStyle = FormBorderStyle.None;
+
+ Screen screen = Screen.FromControl(_Form);
+ _Form.DesktopBounds = new Rectangle(screen.Bounds.Location, new Size(screen.Bounds.Width, screen.Bounds.Height));
+
+ if (_Form.WindowState == FormWindowState.Maximized)
+ {
+ _Form.WindowState = FormWindowState.Normal;
+ _DoResize();
+ _Form.WindowState = FormWindowState.Maximized;
+ }
+ else
+ _DoResize();
+ }
+
+ protected override void _LeaveFullScreen()
+ {
+ Debug.Assert(_Fullscreen);
+ _Fullscreen = false;
+
+ _Form.FormBorderStyle = FormBorderStyle.Sizable;
+ _Form.DesktopBounds = new Rectangle(_Restore.Location, new Size(_Restore.Width, _Restore.Height));
+ }
+
+ #region form event handlers
+ private void _OnClose(object sender, CancelEventArgs e)
+ {
+ _Run = false;
+ }
+
+ private void _OnLoad(object sender, EventArgs e)
+ {
+ ClearScreen();
+ }
+
+ protected virtual void _OnResize(object sender, EventArgs e)
+ {
+ _DoResize();
+ }
+
+ #region mouse event handlers
+ protected void _OnMouseMove(object sender, MouseEventArgs e)
+ {
+ _Mouse.MouseMove(e);
+ }
+
+ protected void _OnMouseWheel(object sender, MouseEventArgs e)
+ {
+ _Mouse.MouseWheel(e);
+ }
+
+ protected void _OnMouseDown(object sender, MouseEventArgs e)
+ {
+ _Mouse.MouseDown(e);
+ }
+
+ protected void _OnMouseUp(object sender, MouseEventArgs e)
+ {
+ _Mouse.MouseUp(e);
+ }
+
+ protected void _OnMouseLeave(object sender, EventArgs e)
+ {
+ _Mouse.Visible = false;
+ Cursor.Show();
+ }
+
+ protected void _OnMouseEnter(object sender, EventArgs e)
+ {
+ Cursor.Hide();
+ _Mouse.Visible = true;
+ }
+ #endregion
+
+ #region keyboard event handlers
+ protected void _OnPreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
+ {
+ _OnKeyDown(sender, new KeyEventArgs(e.KeyData));
+ }
+
+ protected void _OnKeyDown(object sender, KeyEventArgs e)
+ {
+ _Keys.KeyDown(e);
+ }
+
+ protected void _OnKeyPress(object sender, KeyPressEventArgs e)
+ {
+ _Keys.KeyPress(e);
+ }
+
+ protected void _OnKeyUp(object sender, KeyEventArgs e)
+ {
+ _Keys.KeyUp(e);
+ }
+ #endregion keyboard event handlers
+
+ #endregion
+
+ public virtual bool Init()
+ {
+ _Form.Icon = new Icon(Path.Combine(CSettings.ProgramFolder, CSettings.FileNameIcon));
+ _Form.Text = CSettings.GetFullVersionText();
+ ((IFormHook)_Form).OnMessage = _OnMessageAvoidScreenOff;
+ _Form.Closing += _OnClose;
+ _Form.Resize += _OnResize;
+ _Form.Load += _OnLoad;
+
+ return true;
+ }
+
+ public override void MainLoop()
+ {
+ _Form.Show();
+ base.MainLoop();
+ _Form.Hide();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs
index 09db4bf7..fa22be66 100644
--- a/Vocaluxe/Lib/Draw/COpenGL.cs
+++ b/Vocaluxe/Lib/Draw/COpenGL.cs
@@ -15,14 +15,10 @@
// along with Vocaluxe. If not, see .
#endregion
-using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
-using System.Threading;
using OpenTK;
using OpenTK.Graphics;
using System;
-using System.Collections.Generic;
-using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
@@ -41,7 +37,6 @@ using DepthFunction = OpenTK.Graphics.OpenGL.DepthFunction;
using EnableCap = OpenTK.Graphics.OpenGL.EnableCap;
using GL = OpenTK.Graphics.OpenGL.GL;
using GenerateMipmapTarget = OpenTK.Graphics.OpenGL.GenerateMipmapTarget;
-using KeyPressEventArgs = System.Windows.Forms.KeyPressEventArgs;
using MatrixMode = OpenTK.Graphics.OpenGL.MatrixMode;
using PixelFormat = OpenTK.Graphics.OpenGL.PixelFormat;
using PixelInternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat;
@@ -54,29 +49,46 @@ using TextureTarget = OpenTK.Graphics.OpenGL.TextureTarget;
namespace Vocaluxe.Lib.Draw
{
- class CFormHook : Form, CDrawBaseWindows.IFormHook
+ class CFormHook : Form, IFormHook
{
- public CDrawBaseWindows.MessageEventHandler OnMessage { private get; set; }
+ public MessageEventHandler OnMessage { private get; set; }
protected override void WndProc(ref Message m)
{
- if (OnMessage(ref m))
+ if (OnMessage == null || OnMessage(ref m))
base.WndProc(ref m);
}
}
- class COpenGL : CDrawBaseWindows, IDraw
+ class CGLTexture : IDisposable
+ {
+ public int PBO;
+ //The texture "name" according to the specs
+ public readonly int Name;
+
+ public CGLTexture(int name)
+ {
+ Name = name;
+ }
+
+ private bool _IsDisposed;
+
+ public void Dispose()
+ {
+ if (_IsDisposed)
+ throw new ObjectDisposedException(GetType().Name);
+ _IsDisposed = true;
+ GL.DeleteTexture(Name);
+ if (PBO > 0)
+ GL.DeleteBuffers(1, ref PBO);
+ }
+ }
+
+ class COpenGL : CDrawBaseWindows, IDraw
{
#region private vars
- private readonly CKeys _Keys;
- private readonly CMouse _Mouse;
- private bool _Run;
-
private readonly GLControl _Control;
- private readonly Dictionary _Textures = new Dictionary();
- private readonly Queue _TexturesToLoad = new Queue();
-
private int _H = 1;
private int _W = 1;
private int _Y;
@@ -112,18 +124,11 @@ namespace Vocaluxe.Lib.Draw
_Form.Controls.Add(_Control);
+ _Control.KeyDown += _OnKeyDown;
+ _Control.PreviewKeyDown += _OnPreviewKeyDown;
+ _Control.KeyPress += _OnKeyPress;
+ _Control.KeyUp += _OnKeyUp;
- _Keys = new CKeys();
- _Form.Closing += _OnClosingEvent;
- _Form.Load += _OnLoad;
- _Form.Resize += _OnResize;
-
- _Control.KeyDown += _OnKeyDownEvent;
- _Control.PreviewKeyDown += _OnPreviewKeyDownEvent;
- _Control.KeyPress += _OnKeyPressEvent;
- _Control.KeyUp += _OnKeyUpEvent;
-
- _Mouse = new CMouse();
_Control.MouseMove += _OnMouseMove;
_Control.MouseWheel += _OnMouseWheel;
_Control.MouseDown += _OnMouseDown;
@@ -139,7 +144,7 @@ namespace Vocaluxe.Lib.Draw
}
#region Helpers
- private int _CheckAntiAliasingMode(int setValue)
+ private static int _CheckAntiAliasingMode(int setValue)
{
int samples = 0;
@@ -201,79 +206,13 @@ namespace Vocaluxe.Lib.Draw
#endregion Helpers
#region form events
- private void _OnClosingEvent(object sender, CancelEventArgs e)
- {
- _Run = false;
- }
-
- private static void _OnLoad(object sender, EventArgs e)
- {
- GL.ClearColor(Color.Black);
- }
-
- private void _OnResize(object sender, EventArgs e)
+ protected override void _OnResize(object sender, EventArgs e)
{
_Control.ClientSize = _Form.ClientSize;
- _DoResize();
+ base._OnResize(sender, e);
}
#endregion form events
- #region mouse event handlers
- private void _OnMouseMove(object sender, MouseEventArgs e)
- {
- _Mouse.MouseMove(e);
- }
-
- private void _OnMouseWheel(object sender, MouseEventArgs e)
- {
- _Mouse.MouseWheel(e);
- }
-
- private void _OnMouseDown(object sender, MouseEventArgs e)
- {
- _Mouse.MouseDown(e);
- }
-
- private void _OnMouseUp(object sender, MouseEventArgs e)
- {
- _Mouse.MouseUp(e);
- }
-
- private void _OnMouseLeave(object sender, EventArgs e)
- {
- _Mouse.Visible = false;
- Cursor.Show();
- }
-
- private void _OnMouseEnter(object sender, EventArgs e)
- {
- Cursor.Hide();
- _Mouse.Visible = true;
- }
- #endregion
-
- #region keyboard event handlers
- private void _OnPreviewKeyDownEvent(object sender, PreviewKeyDownEventArgs e)
- {
- _OnKeyDownEvent(sender, new KeyEventArgs(e.KeyData));
- }
-
- private void _OnKeyDownEvent(object sender, KeyEventArgs e)
- {
- _Keys.KeyDown(e);
- }
-
- private void _OnKeyPressEvent(object sender, KeyPressEventArgs e)
- {
- _Keys.KeyPress(e);
- }
-
- private void _OnKeyUpEvent(object sender, KeyEventArgs e)
- {
- _Keys.KeyUp(e);
- }
- #endregion keyboard event handlers
-
protected override void _DoResize()
{
_H = _Control.Height;
@@ -316,59 +255,19 @@ namespace Vocaluxe.Lib.Draw
GL.DepthRange(CSettings.ZFar, CSettings.ZNear);
GL.DepthFunc(DepthFunction.Lequal);
GL.Enable(EnableCap.DepthTest);
+ GL.ClearColor(Color.Black);
return true;
}
- public void MainLoop()
+ protected override void _OnBeforeDraw()
{
- _Run = true;
- int delay = 0;
- _Form.Show();
-
- if (CConfig.FullScreen == EOffOn.TR_CONFIG_ON)
- _EnterFullScreen();
-
- while (_Run)
- {
- ClearScreen();
- if (!CGraphics.Draw())
- _Run = false;
- if (!CGraphics.UpdateGameLogic(_Keys, _Mouse))
- _Run = false;
-
- _Control.SwapBuffers();
-
- if ((CConfig.FullScreen == EOffOn.TR_CONFIG_ON) != _Fullscreen)
- _ToggleFullScreen();
-
- _CheckQueue();
-
- if (CTime.IsRunning())
- delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds());
-
- if (delay >= 1 && CConfig.VSync == EOffOn.TR_CONFIG_OFF)
- Thread.Sleep(delay);
-
- CTime.CalculateFPS();
- CTime.Restart();
-
- Application.DoEvents();
- }
- _Form.Close();
+ //Nothing to do
}
- public void Unload()
+ protected override void _OnAfterDraw()
{
- try
- {
- _Form.Close();
- }
- catch {}
- var textures = new CTexture[_Textures.Count];
- _Textures.Values.CopyTo(textures, 0);
- for (int i = 0; i < _Textures.Count; i++)
- RemoveTexture(ref textures[i]);
+ _Control.SwapBuffers();
}
public int GetScreenWidth()
@@ -383,17 +282,22 @@ namespace Vocaluxe.Lib.Draw
#endregion main stuff
#region Basic Draw Methods
- public void ClearScreen()
+ public override void ClearScreen()
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
}
+ protected override void _AdjustNewBorders()
+ {
+ //TODO: Implement!!!
+ }
+
public CTexture CopyScreen()
{
- CTexture texture = GetNewTexture(_W, _H);
+ CTexture texture = _GetNewTextureRef(_W, _H);
- texture.Name = GL.GenTexture();
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+ CGLTexture t = new CGLTexture(GL.GenTexture());
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture.W2, texture.H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, _X, _Y, _W, _H);
@@ -406,7 +310,7 @@ namespace Vocaluxe.Lib.Draw
// Add to Texture List
lock (_Textures)
{
- _Textures[texture.ID] = texture;
+ _Textures[texture.ID] = t;
}
return texture;
@@ -422,7 +326,7 @@ namespace Vocaluxe.Lib.Draw
}
else
{
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+ GL.BindTexture(TextureTarget.Texture2D, _Textures[texture.ID].Name);
GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, 0, 0, GetScreenWidth(), GetScreenHeight());
@@ -532,149 +436,46 @@ namespace Vocaluxe.Lib.Draw
#region Textures
#region adding
- public CTexture AddTexture(string texturePath)
+ protected override CGLTexture _CreateTexture(CTexture texture, IntPtr data)
{
- if (!File.Exists(texturePath))
- {
- CLog.LogError("Can't find File: " + texturePath);
- return null;
- }
- Bitmap bmp;
- try
- {
- bmp = new Bitmap(texturePath);
- }
- catch (Exception)
- {
- CLog.LogError("Error loading Texture: " + texturePath);
- return null;
- }
- try
- {
- return AddTexture(bmp);
- }
- finally
- {
- bmp.Dispose();
- }
- }
+ CGLTexture t = new CGLTexture(GL.GenTexture());
- public CTexture AddTexture(Bitmap bmp)
- {
- if (bmp.Height == 0 || bmp.Width == 0)
- return null;
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
- int maxSize;
- 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;
- }
-
- int w = Math.Min(bmp.Width, maxSize);
- int h = Math.Min(bmp.Height, maxSize);
-
- CTexture texture = GetNewTexture(w, h);
- texture.Name = GL.GenTexture();
-
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
- Bitmap bmp2 = null;
- try
- {
- if (bmp.Width != w || bmp.Height != h)
- {
- //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));
- }
- bmp = bmp2;
- }
-
- BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture.W2, texture.H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
- GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, bmpData.Width, bmpData.Height, PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0);
- bmp.UnlockBits(bmpData);
- }
- finally
- {
- if (bmp2 != null)
- bmp2.Dispose();
- }
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture.W2, texture.H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
+ GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.DataSize.Width, texture.DataSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
-
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, 0);
- // Add to Texture List
- texture.TexturePath = String.Empty;
-
- lock (_Textures)
- {
- _Textures[texture.ID] = texture;
- }
-
- return texture;
+ return t;
}
- public CTexture AddTexture(int w, int h, byte[] data)
+ protected override CGLTexture _CreateTexture(CTexture texture, byte[] data)
{
- CTexture texture = GetNewTexture(w, h);
+ CGLTexture t = new CGLTexture(GL.GenTexture());
- _CreateTexture(texture, data);
-
- lock (_Textures)
- {
- _Textures[texture.ID] = texture;
- }
-
- return texture;
- }
-
- private void _CreateTexture(CTexture texture, byte[] data)
- {
if (_UsePBO)
{
try
{
- GL.GenBuffers(1, out texture.PBO);
- GL.BindBuffer(BufferTarget.PixelUnpackBuffer, texture.PBO);
+ GL.GenBuffers(1, out t.PBO);
+ GL.BindBuffer(BufferTarget.PixelUnpackBuffer, t.PBO);
GL.BufferData(BufferTarget.PixelUnpackBuffer, (IntPtr)data.Length, IntPtr.Zero, BufferUsageHint.StreamDraw);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
}
- catch (Exception)
+ catch (Exception e)
{
- //throw;
+ CLog.LogError("PBO creation failed. Using fallback solution.", false, false, e);
_UsePBO = false;
}
}
- texture.Name = GL.GenTexture();
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture.W2, texture.H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.OrigSize.Width, texture.OrigSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
@@ -686,27 +487,15 @@ namespace Vocaluxe.Lib.Draw
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, 0);
- }
-
- public CTexture EnqueueTexture(int w, int h, byte[] data)
- {
- CTexture texture = GetNewTexture(w, h);
-
- lock (_Textures)
- {
- var queue = new STextureQueue(texture, data);
- _TexturesToLoad.Enqueue(queue);
- _Textures[texture.ID] = texture;
- }
-
- return texture;
+ return t;
}
#endregion adding
#region updating
- public bool UpdateTexture(CTexture texture, int w, int h, byte[] data)
+ public override bool UpdateTexture(CTexture texture, int w, int h, byte[] data)
{
- if (!_TextureExists(texture))
+ CGLTexture t = _GetTexture(texture);
+ if (t == null)
return false;
if (texture.DataSize.Width != w || texture.DataSize.Height != h)
{
@@ -716,16 +505,17 @@ namespace Vocaluxe.Lib.Draw
return false; // Texture memory to big
texture.DataSize = new Size(w, h);
}
+
if (_UsePBO)
{
- GL.BindBuffer(BufferTarget.PixelUnpackBuffer, texture.PBO);
+ GL.BindBuffer(BufferTarget.PixelUnpackBuffer, t.PBO);
IntPtr buffer = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
Marshal.Copy(data, 0, buffer, data.Length);
GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer);
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
@@ -737,7 +527,7 @@ namespace Vocaluxe.Lib.Draw
return true;
}
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, data);
@@ -747,43 +537,8 @@ namespace Vocaluxe.Lib.Draw
return true;
}
-
- public bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data)
- {
- if (!UpdateTexture(texture, w, h, data))
- {
- RemoveTexture(ref texture);
- texture = AddTexture(w, h, data);
- }
- return true;
- }
#endregion updating
- public void RemoveTexture(ref CTexture texture)
- {
- lock (_Textures)
- {
- if (_TextureExists(texture))
- {
- GL.DeleteTexture(texture.Name);
- if (texture.PBO > 0)
- GL.DeleteBuffers(1, ref texture.PBO);
- }
- _Textures.Remove(texture.ID);
- }
- texture = null;
- }
-
- private bool _TextureExists(CTexture texture)
- {
- lock (_Textures)
- {
- if (texture != null && _Textures.ContainsKey(texture.ID) && texture.Name > 0)
- return true;
- }
- return false;
- }
-
#region drawing
public void DrawTexture(CTexture texture)
{
@@ -806,7 +561,8 @@ namespace Vocaluxe.Lib.Draw
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
{
- if (!_TextureExists(texture))
+ CGLTexture t = _GetTexture(texture);
+ if (t == null)
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 ||
@@ -819,7 +575,7 @@ namespace Vocaluxe.Lib.Draw
if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y)
return;
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio;
@@ -914,9 +670,11 @@ namespace Vocaluxe.Lib.Draw
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, float begin, float end)
{
- if (!_TextureExists(texture))
+ CGLTexture t = _GetTexture(texture);
+ if (t == null)
return;
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
GL.Enable(EnableCap.Blend);
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
@@ -945,7 +703,8 @@ namespace Vocaluxe.Lib.Draw
public void DrawTextureReflection(CTexture texture, SRectF rect, SColorF color, SRectF bounds, float space, float height)
{
- if (!_TextureExists(texture))
+ CGLTexture t = _GetTexture(texture);
+ if (t == null)
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 ||
@@ -961,7 +720,7 @@ namespace Vocaluxe.Lib.Draw
if (height > bounds.H)
height = bounds.H;
- GL.BindTexture(TextureTarget.Texture2D, texture.Name);
+ GL.BindTexture(TextureTarget.Texture2D, t.Name);
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio;
@@ -1039,25 +798,6 @@ namespace Vocaluxe.Lib.Draw
}
#endregion drawing
- public int GetTextureCount()
- {
- return _Textures.Count;
- }
-
- private void _CheckQueue()
- {
- lock (_Textures)
- {
- while (_TexturesToLoad.Count > 0)
- {
- STextureQueue q = _TexturesToLoad.Dequeue();
- if (!_Textures.ContainsKey(q.Texture.ID))
- continue;
-
- _CreateTexture(q.Texture, q.Data);
- }
- }
- }
#endregion Textures
#endregion implementation
diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj
index 5585782e..aed2508e 100644
--- a/Vocaluxe/Vocaluxe.csproj
+++ b/Vocaluxe/Vocaluxe.csproj
@@ -225,6 +225,7 @@
+
diff --git a/VocaluxeLib/Draw/CTexture.cs b/VocaluxeLib/Draw/CTexture.cs
index e228a4a3..dda82f9c 100644
--- a/VocaluxeLib/Draw/CTexture.cs
+++ b/VocaluxeLib/Draw/CTexture.cs
@@ -19,12 +19,12 @@ using System.Drawing;
namespace VocaluxeLib.Draw
{
+ ///
+ /// Reference to a texture in the drawing driver
+ ///
public class CTexture
{
public readonly int ID;
- public int PBO;
- //Only used by OpenGL (the texture "name" according to the specs)
- public int Name = -1;
public string TexturePath = "";
@@ -117,8 +117,8 @@ namespace VocaluxeLib.Draw
private void _CalcRatios()
{
- WidthRatio = (float)_DataSize.Width / _W2;
- HeightRatio = (float)_DataSize.Height / _H2;
+ WidthRatio = (float)_DataSize.Width / _W2;
+ HeightRatio = (float)_DataSize.Height / _H2;
}
}
}
\ No newline at end of file
diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs
index 0583e189..ade82b4c 100644
--- a/VocaluxeLib/IBasic.cs
+++ b/VocaluxeLib/IBasic.cs
@@ -136,7 +136,6 @@ namespace VocaluxeLib
void LoadPreview(CSong song, float start = 0f);
void PlayPreview(float start = -1f);
void StopPreview();
-
}
public interface IDrawing
@@ -338,6 +337,5 @@ namespace VocaluxeLib
CTexture GetVideoTexture();
bool IsPlaying();
float GetLength();
-
}
}
\ No newline at end of file