Unify as much of D3D and OpenGL as possible
This commit is contained in:
1 parent
46acaf092a
commit
76ededf9f3
7 files changed
+710
-866
No files matched your search
+64
-417
@@ -15,13 +15,10 @@
|
|||||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Threading;
|
|
||||||
using SlimDX;
|
using SlimDX;
|
||||||
using SlimDX.Direct3D9;
|
using SlimDX.Direct3D9;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -34,33 +31,26 @@ using VocaluxeLib.Draw;
|
|||||||
|
|
||||||
namespace Vocaluxe.Lib.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)
|
protected override void WndProc(ref Message m)
|
||||||
{
|
{
|
||||||
if (OnMessage(ref m))
|
if (OnMessage == null || OnMessage(ref m))
|
||||||
base.WndProc(ref m);
|
base.WndProc(ref m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CDirect3D : CDrawBaseWindows, IDraw
|
class CDirect3D : CDrawBaseWindows<Texture>, IDraw
|
||||||
{
|
{
|
||||||
#region private vars
|
#region private vars
|
||||||
private readonly CKeys _Keys;
|
|
||||||
private readonly CMouse _Mouse;
|
|
||||||
private bool _Run;
|
|
||||||
|
|
||||||
private readonly Direct3D _D3D;
|
private readonly Direct3D _D3D;
|
||||||
private readonly Device _Device;
|
private readonly Device _Device;
|
||||||
private readonly PresentParameters _PresentParameters;
|
private readonly PresentParameters _PresentParameters;
|
||||||
|
|
||||||
private Size _SizeBeforeMinimize;
|
private Size _SizeBeforeMinimize;
|
||||||
|
|
||||||
private readonly Dictionary<int, Texture> _D3DTextures = new Dictionary<int, Texture>();
|
|
||||||
private readonly Queue<STextureQueue> _TexturesToLoad = new Queue<STextureQueue>();
|
|
||||||
|
|
||||||
private VertexBuffer _VertexBuffer;
|
private VertexBuffer _VertexBuffer;
|
||||||
private IndexBuffer _IndexBuffer;
|
private IndexBuffer _IndexBuffer;
|
||||||
|
|
||||||
@@ -69,16 +59,11 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
private int _Y;
|
private int _Y;
|
||||||
private int _X;
|
private int _X;
|
||||||
|
|
||||||
private int _BorderLeft;
|
|
||||||
private int _BorderRight;
|
|
||||||
private int _BorderTop;
|
|
||||||
private int _BorderBottom;
|
|
||||||
|
|
||||||
private CTexture _BlankTexture;
|
private CTexture _BlankTexture;
|
||||||
|
|
||||||
private readonly Queue<STexturedColoredVertex> _Vertices = new Queue<STexturedColoredVertex>();
|
private readonly Queue<STexturedColoredVertex> _Vertices = new Queue<STexturedColoredVertex>();
|
||||||
private readonly Queue<Texture> _VerticesTextures = new Queue<Texture>();
|
private readonly Queue<Texture> _VerticesTextures = new Queue<Texture>();
|
||||||
private readonly Queue<SlimDX.Matrix> _VerticesRotationMatrices = new Queue<SlimDX.Matrix>();
|
private readonly Queue<Matrix> _VerticesRotationMatrices = new Queue<Matrix>();
|
||||||
#endregion private vars
|
#endregion private vars
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -87,7 +72,6 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
public CDirect3D()
|
public CDirect3D()
|
||||||
{
|
{
|
||||||
_Form = new CRenderFormHook();
|
_Form = new CRenderFormHook();
|
||||||
_Keys = new CKeys();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_D3D = new Direct3D();
|
_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);
|
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.KeyDown += _OnKeyDown;
|
||||||
_Form.PreviewKeyDown += _OnPreviewKeyDown;
|
_Form.PreviewKeyDown += _OnPreviewKeyDown;
|
||||||
_Form.KeyPress += _OnKeyPress;
|
_Form.KeyPress += _OnKeyPress;
|
||||||
_Form.KeyUp += _OnKeyUp;
|
_Form.KeyUp += _OnKeyUp;
|
||||||
|
|
||||||
_Mouse = new CMouse();
|
|
||||||
_Form.MouseMove += _OnMouseMove;
|
_Form.MouseMove += _OnMouseMove;
|
||||||
_Form.MouseWheel += _OnMouseWheel;
|
_Form.MouseWheel += _OnMouseWheel;
|
||||||
_Form.MouseDown += _OnMouseDown;
|
_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);
|
_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
|
finally
|
||||||
{
|
{
|
||||||
if (_Device == null || _Device.Disposed)
|
if (_Device == null || _Device.Disposed)
|
||||||
@@ -198,20 +180,6 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region form events
|
#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
|
#endregion form events
|
||||||
|
|
||||||
#region resize
|
#region resize
|
||||||
@@ -273,62 +241,6 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
// ReSharper restore RedundantOverridenMember
|
// ReSharper restore RedundantOverridenMember
|
||||||
#endregion resize
|
#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 implementation
|
||||||
|
|
||||||
#region main stuff
|
#region main stuff
|
||||||
@@ -359,9 +271,9 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
CLog.LogError("Failed to enable alpha blending");
|
CLog.LogError("Failed to enable alpha blending");
|
||||||
if (_Device.SetRenderState(RenderState.Lighting, false).IsFailure)
|
if (_Device.SetRenderState(RenderState.Lighting, false).IsFailure)
|
||||||
CLog.LogError("Failed to disable lighting");
|
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");
|
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");
|
CLog.LogError("Failed to set source blend");
|
||||||
if (_PresentParameters.Multisample != MultisampleType.None)
|
if (_PresentParameters.Multisample != MultisampleType.None)
|
||||||
{
|
{
|
||||||
@@ -412,84 +324,35 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
protected override void _OnBeforeDraw()
|
||||||
/// Starts the rendering
|
|
||||||
/// </summary>
|
|
||||||
public void MainLoop()
|
|
||||||
{
|
{
|
||||||
_Run = true;
|
if (_Device.BeginScene().IsFailure)
|
||||||
int delay = 0;
|
CLog.LogError("Failed to begin scene");
|
||||||
_Form.Show();
|
}
|
||||||
|
|
||||||
if (CConfig.FullScreen == EOffOn.TR_CONFIG_ON)
|
protected override void _OnAfterDraw()
|
||||||
_EnterFullScreen();
|
{
|
||||||
|
_RenderVertexBuffer();
|
||||||
//Resize window if aspect ratio is incorrect
|
if (_Device.EndScene().IsFailure)
|
||||||
if (Math.Abs(_W / (float)_H - CSettings.GetRenderAspect()) > 0.01)
|
CLog.LogError("Failed to end scene");
|
||||||
_DoResize();
|
try
|
||||||
|
|
||||||
while (_Run)
|
|
||||||
{
|
{
|
||||||
Application.DoEvents();
|
//Now push the frame to the Viewport
|
||||||
//Clear the previous Frame
|
_Device.Present();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
_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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -505,10 +368,10 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
CLog.LogError("Failed to reset the device");
|
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));
|
Matrix translate = Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0));
|
||||||
SlimDX.Matrix projection = SlimDX.Matrix.OrthoOffCenterLH(
|
Matrix projection = Matrix.OrthoOffCenterLH(
|
||||||
-(float)CSettings.RenderW / 2 - _BorderLeft, (float)CSettings.RenderW / 2 + _BorderRight,
|
-(float)CSettings.RenderW / 2 - _BorderLeft, (float)CSettings.RenderW / 2 + _BorderRight,
|
||||||
-(float)CSettings.RenderH / 2 - _BorderBottom, (float)CSettings.RenderH / 2 + _BorderTop,
|
-(float)CSettings.RenderH / 2 - _BorderBottom, (float)CSettings.RenderH / 2 + _BorderTop,
|
||||||
CSettings.ZNear, CSettings.ZFar);
|
CSettings.ZNear, CSettings.ZFar);
|
||||||
@@ -523,20 +386,9 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
/// Unloads all Textures and other objects used by Direct3D for rendering
|
/// Unloads all Textures and other objects used by Direct3D for rendering
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void Unload()
|
public override void Unload()
|
||||||
{
|
{
|
||||||
try
|
base.Unload();
|
||||||
{
|
|
||||||
_Form.Close();
|
|
||||||
}
|
|
||||||
catch {}
|
|
||||||
//Dispose all textures
|
|
||||||
foreach (Texture texture in _D3DTextures.Values)
|
|
||||||
{
|
|
||||||
if (texture != null)
|
|
||||||
texture.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
STexturedColoredVertex.GetDeclaration(_Device).Dispose();
|
STexturedColoredVertex.GetDeclaration(_Device).Dispose();
|
||||||
_VertexBuffer.Dispose();
|
_VertexBuffer.Dispose();
|
||||||
_IndexBuffer.Dispose();
|
_IndexBuffer.Dispose();
|
||||||
@@ -568,7 +420,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
/// <param name="vertices">A TexturedColoredVertex array containg 4 vertices</param>
|
/// <param name="vertices">A TexturedColoredVertex array containg 4 vertices</param>
|
||||||
/// <param name="tex">The texture the vertex should be textured with</param>
|
/// <param name="tex">The texture the vertex should be textured with</param>
|
||||||
/// <param name="rotation">The vertices' rotation</param>
|
/// <param name="rotation">The vertices' rotation</param>
|
||||||
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
|
//The vertexbuffer is full, so we need to flush it before we can continue
|
||||||
if (_Vertices.Count >= CSettings.VertexBufferElements)
|
if (_Vertices.Count >= CSettings.VertexBufferElements)
|
||||||
@@ -617,7 +469,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes all textures from the screen
|
/// Removes all textures from the screen
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ClearScreen()
|
public override void ClearScreen()
|
||||||
{
|
{
|
||||||
if (_Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0).IsFailure)
|
if (_Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0).IsFailure)
|
||||||
CLog.LogError("Failed to clear the backbuffer");
|
CLog.LogError("Failed to clear the backbuffer");
|
||||||
@@ -629,16 +481,16 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public CTexture CopyScreen()
|
public CTexture CopyScreen()
|
||||||
{
|
{
|
||||||
CTexture texture = GetNewTexture(_W, _H);
|
CTexture texture = _GetNewTextureRef(_W, _H);
|
||||||
|
|
||||||
Surface backbufferSurface = _Device.GetBackBuffer(0, 0);
|
Surface backbufferSurface = _Device.GetBackBuffer(0, 0);
|
||||||
var tex = new Texture(_Device, texture.W2, texture.H2, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed);
|
var tex = new Texture(_Device, texture.W2, texture.H2, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed);
|
||||||
Surface textureSurface = tex.GetSurfaceLevel(0);
|
Surface textureSurface = tex.GetSurfaceLevel(0);
|
||||||
Surface.FromSurface(textureSurface, backbufferSurface, Filter.Default, 0, new Rectangle(0, 0, _W, _H), new Rectangle(0, 0, _W, _H));
|
Surface.FromSurface(textureSurface, backbufferSurface, Filter.Default, 0, new Rectangle(0, 0, _W, _H), new Rectangle(0, 0, _W, _H));
|
||||||
backbufferSurface.Dispose();
|
backbufferSurface.Dispose();
|
||||||
lock (_D3DTextures)
|
lock (_Textures)
|
||||||
{
|
{
|
||||||
_D3DTextures.Add(texture.ID, tex);
|
_Textures.Add(texture.ID, tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
@@ -658,7 +510,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Surface backbufferSurface = _Device.GetBackBuffer(0, 0);
|
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);
|
Surface.FromSurface(textureSurface, backbufferSurface, Filter.Default, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -729,132 +581,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
#region Textures
|
#region Textures
|
||||||
|
|
||||||
#region adding
|
#region adding
|
||||||
/// <summary>
|
protected override Texture _CreateTexture(CTexture texture, byte[] data)
|
||||||
/// Adds a texture and stores it in the VRam
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="texturePath">The texture's filepath</param>
|
|
||||||
/// <returns>A STexture object containing the added texture</returns>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a texture and stores it in the Vram
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bmp">The Bitmap of which the texure will be created from</param>
|
|
||||||
/// <returns>A STexture object containing the added texture</returns>
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
//Create a new texture in the managed pool, which does not need to be recreated on a lost device
|
//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
|
//because a copy of the texture is hold in the Ram
|
||||||
@@ -881,18 +608,6 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
}
|
}
|
||||||
t.UnlockRectangle(0);
|
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
|
#endregion adding
|
||||||
|
|
||||||
#region updating
|
#region updating
|
||||||
@@ -904,7 +619,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
/// <param name="h"></param>
|
/// <param name="h"></param>
|
||||||
/// <param name="data">A byte array containing the new texture's data</param>
|
/// <param name="data">A byte array containing the new texture's data</param>
|
||||||
/// <returns>True if succeeded</returns>
|
/// <returns>True if succeeded</returns>
|
||||||
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))
|
if (!_TextureExists(texture))
|
||||||
return false;
|
return false;
|
||||||
@@ -916,58 +631,14 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
return false; // Texture memory to big
|
return false; // Texture memory to big
|
||||||
texture.DataSize = new Size(w, h);
|
texture.DataSize = new Size(w, h);
|
||||||
}
|
}
|
||||||
lock (_D3DTextures)
|
lock (_Textures)
|
||||||
{
|
{
|
||||||
_WriteDataToTexture(_D3DTextures[texture.ID], w, data);
|
_WriteDataToTexture(_Textures[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);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endregion updating
|
#endregion updating
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a texture exists
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="texture">The texture to check</param>
|
|
||||||
/// <returns>True if the texture exists</returns>
|
|
||||||
private bool _TextureExists(CTexture texture)
|
|
||||||
{
|
|
||||||
lock (_D3DTextures)
|
|
||||||
{
|
|
||||||
return texture != null && _D3DTextures.ContainsKey(texture.ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a texture from the Vram
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="texture">The texture to be removed</param>
|
|
||||||
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
|
#region drawing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Draws a texture
|
/// Draws a texture
|
||||||
@@ -1016,7 +687,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
{
|
{
|
||||||
if (!_TextureExists(texture))
|
if (!_TextureExists(texture))
|
||||||
return;
|
return;
|
||||||
if (_D3DTextures[texture.ID] == null)
|
if (_Textures[texture.ID] == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Calculate the position
|
//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[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[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());
|
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
|
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[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[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());
|
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))
|
if (!_TextureExists(texture))
|
||||||
return;
|
return;
|
||||||
if (_D3DTextures[texture.ID] == null)
|
if (_Textures[texture.ID] == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float x1 = 0f + begin * texture.WidthRatio;
|
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[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[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());
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1150,7 +821,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
{
|
{
|
||||||
if (!_TextureExists(texture))
|
if (!_TextureExists(texture))
|
||||||
return;
|
return;
|
||||||
if (_D3DTextures[texture.ID] == null)
|
if (_Textures[texture.ID] == null)
|
||||||
return;
|
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 ||
|
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[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[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());
|
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
|
#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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the count of current textures
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The amount of textures</returns>
|
|
||||||
public int GetTextureCount()
|
|
||||||
{
|
|
||||||
return _D3DTextures.Count;
|
|
||||||
}
|
|
||||||
#endregion Textures
|
#endregion Textures
|
||||||
|
|
||||||
#endregion implementation
|
#endregion implementation
|
||||||
|
|
||||||
#region utility
|
#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)
|
if (Math.Abs(rot) > float.Epsilon)
|
||||||
{
|
{
|
||||||
float rotation = rot * (float)Math.PI / 180;
|
float rotation = rot * (float)Math.PI / 180;
|
||||||
float centerX = (rx1 + rx2) / 2f;
|
float centerX = (rx1 + rx2) / 2f;
|
||||||
float centerY = -(ry1 + ry2) / 2f;
|
float centerY = -(ry1 + ry2) / 2f;
|
||||||
|
|
||||||
SlimDX.Matrix translationA = SlimDX.Matrix.Translation(-centerX, -centerY, 0);
|
Matrix translationA = Matrix.Translation(-centerX, -centerY, 0);
|
||||||
SlimDX.Matrix rotationMat = SlimDX.Matrix.RotationZ(-rotation);
|
Matrix rotationMat = Matrix.RotationZ(-rotation);
|
||||||
SlimDX.Matrix translationB = SlimDX.Matrix.Translation(centerX, centerY, 0);
|
Matrix translationB = Matrix.Translation(centerX, centerY, 0);
|
||||||
|
|
||||||
//Multiplicate the matrices to get the real world matrix,
|
//Multiplicate the matrices to get the real world matrix,
|
||||||
//First shift the texture into the center
|
//First shift the texture into the center
|
||||||
//Rotate it and shift it back to the origin position
|
//Rotate it and shift it back to the origin position
|
||||||
//Apply the originTranslation after
|
//Apply the originTranslation after
|
||||||
SlimDX.Matrix result = translationA * rotationMat * translationB * originTranslation;
|
Matrix result = translationA * rotationMat * translationB * originTranslation;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return originTranslation;
|
return originTranslation;
|
||||||
|
|||||||
+366
-100
@@ -1,20 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
using Vocaluxe.Base;
|
using Vocaluxe.Base;
|
||||||
|
using VocaluxeLib;
|
||||||
using VocaluxeLib.Draw;
|
using VocaluxeLib.Draw;
|
||||||
|
|
||||||
namespace Vocaluxe.Lib.Draw
|
namespace Vocaluxe.Lib.Draw
|
||||||
{
|
{
|
||||||
struct SClientRect
|
|
||||||
{
|
|
||||||
public Point Location;
|
|
||||||
public int Width;
|
|
||||||
public int Height;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct STextureQueue
|
struct STextureQueue
|
||||||
{
|
{
|
||||||
public readonly CTexture Texture;
|
public readonly CTexture Texture;
|
||||||
@@ -27,104 +25,53 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CDrawBaseWindows : CDrawBase
|
abstract class CDrawBase<TTextureType> where TTextureType : class, IDisposable
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
protected bool _NonPowerOf2TextureSupported;
|
protected bool _NonPowerOf2TextureSupported;
|
||||||
protected bool _Fullscreen;
|
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 readonly Object _MutexID = new object();
|
||||||
private int _NextID;
|
private int _NextID;
|
||||||
|
|
||||||
|
protected readonly Dictionary<int, TTextureType> _Textures = new Dictionary<int, TTextureType>();
|
||||||
|
private readonly Queue<STextureQueue> _TexturesToLoad = new Queue<STextureQueue>();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the next power of two if the device has the POW2 flag set
|
/// Calculates the next power of two if the device has the POW2 flag set
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -139,7 +86,30 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
return (int)Math.Pow(2, Math.Ceiling(Math.Log(n, 2)));
|
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
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the texture specified by the reference and fills it with the given data
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texture"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract TTextureType _CreateTexture(CTexture texture, byte[] data);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the texture specified by the reference and fills it with the given data<br />
|
||||||
|
/// Data has to be a pointer to an array of size W*H with 4 Byte values for each pixel (e.g. bmpData.Scan0)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texture"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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(origWidth > 0 && origHeight > 0);
|
||||||
Debug.Assert(dataWidth > 0 || dataHeight <= 0);
|
Debug.Assert(dataWidth > 0 || dataHeight <= 0);
|
||||||
@@ -152,5 +122,301 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
Size dataSize = (dataHeight > 0) ? new Size(dataWidth, dataHeight) : origSize;
|
Size dataSize = (dataHeight > 0) ? new Size(dataWidth, dataHeight) : origSize;
|
||||||
return new CTexture(id, origSize, dataSize, _CheckForNextPowerOf2(dataSize.Width), _CheckForNextPowerOf2(dataSize.Height));
|
return new CTexture(id, origSize, dataSize, _CheckForNextPowerOf2(dataSize.Width), _CheckForNextPowerOf2(dataSize.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a texture and stores it in the VRam
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texturePath">The texture's filepath</param>
|
||||||
|
/// <returns>A STexture object containing the added texture</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a texture and stores it in the Vram
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bmp">The Bitmap of which the texure will be created from</param>
|
||||||
|
/// <returns>A STexture object containing the added texture</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the data of a texture
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texture">The texture to update</param>
|
||||||
|
/// <param name="w"></param>
|
||||||
|
/// <param name="h"></param>
|
||||||
|
/// <param name="data">A byte array containing the new texture's data</param>
|
||||||
|
/// <returns>True if succeeded</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a texture exists
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texture">The texture to check</param>
|
||||||
|
/// <returns>True if the texture exists</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a texture from the Vram
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texture">The texture to be removed</param>
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the rendering
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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<TTextureType> : CDrawBase<TTextureType> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+82
-342
@@ -15,14 +15,10 @@
|
|||||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Threading;
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -41,7 +37,6 @@ using DepthFunction = OpenTK.Graphics.OpenGL.DepthFunction;
|
|||||||
using EnableCap = OpenTK.Graphics.OpenGL.EnableCap;
|
using EnableCap = OpenTK.Graphics.OpenGL.EnableCap;
|
||||||
using GL = OpenTK.Graphics.OpenGL.GL;
|
using GL = OpenTK.Graphics.OpenGL.GL;
|
||||||
using GenerateMipmapTarget = OpenTK.Graphics.OpenGL.GenerateMipmapTarget;
|
using GenerateMipmapTarget = OpenTK.Graphics.OpenGL.GenerateMipmapTarget;
|
||||||
using KeyPressEventArgs = System.Windows.Forms.KeyPressEventArgs;
|
|
||||||
using MatrixMode = OpenTK.Graphics.OpenGL.MatrixMode;
|
using MatrixMode = OpenTK.Graphics.OpenGL.MatrixMode;
|
||||||
using PixelFormat = OpenTK.Graphics.OpenGL.PixelFormat;
|
using PixelFormat = OpenTK.Graphics.OpenGL.PixelFormat;
|
||||||
using PixelInternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat;
|
using PixelInternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat;
|
||||||
@@ -54,29 +49,46 @@ using TextureTarget = OpenTK.Graphics.OpenGL.TextureTarget;
|
|||||||
|
|
||||||
namespace Vocaluxe.Lib.Draw
|
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)
|
protected override void WndProc(ref Message m)
|
||||||
{
|
{
|
||||||
if (OnMessage(ref m))
|
if (OnMessage == null || OnMessage(ref m))
|
||||||
base.WndProc(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<CGLTexture>, IDraw
|
||||||
{
|
{
|
||||||
#region private vars
|
#region private vars
|
||||||
private readonly CKeys _Keys;
|
|
||||||
private readonly CMouse _Mouse;
|
|
||||||
private bool _Run;
|
|
||||||
|
|
||||||
private readonly GLControl _Control;
|
private readonly GLControl _Control;
|
||||||
|
|
||||||
private readonly Dictionary<int, CTexture> _Textures = new Dictionary<int, CTexture>();
|
|
||||||
private readonly Queue<STextureQueue> _TexturesToLoad = new Queue<STextureQueue>();
|
|
||||||
|
|
||||||
private int _H = 1;
|
private int _H = 1;
|
||||||
private int _W = 1;
|
private int _W = 1;
|
||||||
private int _Y;
|
private int _Y;
|
||||||
@@ -112,18 +124,11 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
|
|
||||||
_Form.Controls.Add(_Control);
|
_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.MouseMove += _OnMouseMove;
|
||||||
_Control.MouseWheel += _OnMouseWheel;
|
_Control.MouseWheel += _OnMouseWheel;
|
||||||
_Control.MouseDown += _OnMouseDown;
|
_Control.MouseDown += _OnMouseDown;
|
||||||
@@ -139,7 +144,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
private int _CheckAntiAliasingMode(int setValue)
|
private static int _CheckAntiAliasingMode(int setValue)
|
||||||
{
|
{
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
|
|
||||||
@@ -201,79 +206,13 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
#endregion Helpers
|
#endregion Helpers
|
||||||
|
|
||||||
#region form events
|
#region form events
|
||||||
private void _OnClosingEvent(object sender, CancelEventArgs e)
|
protected override void _OnResize(object sender, EventArgs e)
|
||||||
{
|
|
||||||
_Run = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void _OnLoad(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
GL.ClearColor(Color.Black);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _OnResize(object sender, EventArgs e)
|
|
||||||
{
|
{
|
||||||
_Control.ClientSize = _Form.ClientSize;
|
_Control.ClientSize = _Form.ClientSize;
|
||||||
_DoResize();
|
base._OnResize(sender, e);
|
||||||
}
|
}
|
||||||
#endregion form events
|
#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()
|
protected override void _DoResize()
|
||||||
{
|
{
|
||||||
_H = _Control.Height;
|
_H = _Control.Height;
|
||||||
@@ -316,59 +255,19 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
GL.DepthRange(CSettings.ZFar, CSettings.ZNear);
|
GL.DepthRange(CSettings.ZFar, CSettings.ZNear);
|
||||||
GL.DepthFunc(DepthFunction.Lequal);
|
GL.DepthFunc(DepthFunction.Lequal);
|
||||||
GL.Enable(EnableCap.DepthTest);
|
GL.Enable(EnableCap.DepthTest);
|
||||||
|
GL.ClearColor(Color.Black);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MainLoop()
|
protected override void _OnBeforeDraw()
|
||||||
{
|
{
|
||||||
_Run = true;
|
//Nothing to do
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unload()
|
protected override void _OnAfterDraw()
|
||||||
{
|
{
|
||||||
try
|
_Control.SwapBuffers();
|
||||||
{
|
|
||||||
_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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetScreenWidth()
|
public int GetScreenWidth()
|
||||||
@@ -383,17 +282,22 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
#endregion main stuff
|
#endregion main stuff
|
||||||
|
|
||||||
#region Basic Draw Methods
|
#region Basic Draw Methods
|
||||||
public void ClearScreen()
|
public override void ClearScreen()
|
||||||
{
|
{
|
||||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void _AdjustNewBorders()
|
||||||
|
{
|
||||||
|
//TODO: Implement!!!
|
||||||
|
}
|
||||||
|
|
||||||
public CTexture CopyScreen()
|
public CTexture CopyScreen()
|
||||||
{
|
{
|
||||||
CTexture texture = GetNewTexture(_W, _H);
|
CTexture texture = _GetNewTextureRef(_W, _H);
|
||||||
|
|
||||||
texture.Name = GL.GenTexture();
|
CGLTexture t = new CGLTexture(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.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);
|
GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, _X, _Y, _W, _H);
|
||||||
@@ -406,7 +310,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
// Add to Texture List
|
// Add to Texture List
|
||||||
lock (_Textures)
|
lock (_Textures)
|
||||||
{
|
{
|
||||||
_Textures[texture.ID] = texture;
|
_Textures[texture.ID] = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
@@ -422,7 +326,7 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
}
|
}
|
||||||
else
|
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());
|
GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, 0, 0, GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
@@ -532,149 +436,46 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
#region Textures
|
#region Textures
|
||||||
|
|
||||||
#region adding
|
#region adding
|
||||||
public CTexture AddTexture(string texturePath)
|
protected override CGLTexture _CreateTexture(CTexture texture, IntPtr data)
|
||||||
{
|
{
|
||||||
if (!File.Exists(texturePath))
|
CGLTexture t = new CGLTexture(GL.GenTexture());
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CTexture AddTexture(Bitmap bmp)
|
GL.BindTexture(TextureTarget.Texture2D, t.Name);
|
||||||
{
|
|
||||||
if (bmp.Height == 0 || bmp.Width == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
int maxSize;
|
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture.W2, texture.H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
|
||||||
switch (CConfig.TextureQuality)
|
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.DataSize.Width, texture.DataSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
|
||||||
{
|
|
||||||
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.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (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.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
|
||||||
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
|
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
|
||||||
|
|
||||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||||
// Add to Texture List
|
return t;
|
||||||
texture.TexturePath = String.Empty;
|
|
||||||
|
|
||||||
lock (_Textures)
|
|
||||||
{
|
|
||||||
_Textures[texture.ID] = texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
if (_UsePBO)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GL.GenBuffers(1, out texture.PBO);
|
GL.GenBuffers(1, out t.PBO);
|
||||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, texture.PBO);
|
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, t.PBO);
|
||||||
GL.BufferData(BufferTarget.PixelUnpackBuffer, (IntPtr)data.Length, IntPtr.Zero, BufferUsageHint.StreamDraw);
|
GL.BufferData(BufferTarget.PixelUnpackBuffer, (IntPtr)data.Length, IntPtr.Zero, BufferUsageHint.StreamDraw);
|
||||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
|
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
//throw;
|
CLog.LogError("PBO creation failed. Using fallback solution.", false, false, e);
|
||||||
_UsePBO = false;
|
_UsePBO = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
texture.Name = GL.GenTexture();
|
GL.BindTexture(TextureTarget.Texture2D, t.Name);
|
||||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
|
||||||
|
|
||||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture.W2, texture.H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
|
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);
|
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.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
|
||||||
|
|
||||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||||
}
|
return t;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endregion adding
|
#endregion adding
|
||||||
|
|
||||||
#region updating
|
#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;
|
return false;
|
||||||
if (texture.DataSize.Width != w || texture.DataSize.Height != h)
|
if (texture.DataSize.Width != w || texture.DataSize.Height != h)
|
||||||
{
|
{
|
||||||
@@ -716,16 +505,17 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
return false; // Texture memory to big
|
return false; // Texture memory to big
|
||||||
texture.DataSize = new Size(w, h);
|
texture.DataSize = new Size(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_UsePBO)
|
if (_UsePBO)
|
||||||
{
|
{
|
||||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, texture.PBO);
|
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, t.PBO);
|
||||||
|
|
||||||
IntPtr buffer = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
|
IntPtr buffer = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
|
||||||
Marshal.Copy(data, 0, buffer, data.Length);
|
Marshal.Copy(data, 0, buffer, data.Length);
|
||||||
|
|
||||||
GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer);
|
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);
|
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;
|
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);
|
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, data);
|
||||||
|
|
||||||
@@ -747,43 +537,8 @@ namespace Vocaluxe.Lib.Draw
|
|||||||
|
|
||||||
return true;
|
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
|
#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
|
#region drawing
|
||||||
public void DrawTexture(CTexture texture)
|
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)
|
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;
|
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 ||
|
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)
|
if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
GL.BindTexture(TextureTarget.Texture2D, t.Name);
|
||||||
|
|
||||||
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
|
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
|
||||||
float x2 = (bounds.X + bounds.W - 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)
|
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, float begin, float end)
|
||||||
{
|
{
|
||||||
if (!_TextureExists(texture))
|
CGLTexture t = _GetTexture(texture);
|
||||||
|
if (t == null)
|
||||||
return;
|
return;
|
||||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
|
||||||
|
GL.BindTexture(TextureTarget.Texture2D, t.Name);
|
||||||
|
|
||||||
GL.Enable(EnableCap.Blend);
|
GL.Enable(EnableCap.Blend);
|
||||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
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)
|
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;
|
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 ||
|
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)
|
if (height > bounds.H)
|
||||||
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 x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
|
||||||
float x2 = (bounds.X + bounds.W - 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
|
#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 Textures
|
||||||
|
|
||||||
#endregion implementation
|
#endregion implementation
|
||||||
|
|||||||
@@ -225,6 +225,7 @@
|
|||||||
<Compile Include="Lib\Database\CHighscoreDB.cs" />
|
<Compile Include="Lib\Database\CHighscoreDB.cs" />
|
||||||
<Compile Include="Lib\Database\CResourceDB.cs" />
|
<Compile Include="Lib\Database\CResourceDB.cs" />
|
||||||
<Compile Include="Lib\Draw\CDrawBase.cs" />
|
<Compile Include="Lib\Draw\CDrawBase.cs" />
|
||||||
|
<Compile Include="Lib\Draw\CDrawBaseWindows.cs" />
|
||||||
<Compile Include="Lib\Sound\Playback\CAudioStreamBase.cs" />
|
<Compile Include="Lib\Sound\Playback\CAudioStreamBase.cs" />
|
||||||
<Compile Include="Lib\Sound\Playback\CPlaybackBase.cs" />
|
<Compile Include="Lib\Sound\Playback\CPlaybackBase.cs" />
|
||||||
<Compile Include="Lib\Sound\Playback\CRingBuffer.cs" />
|
<Compile Include="Lib\Sound\Playback\CRingBuffer.cs" />
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ using System.Drawing;
|
|||||||
|
|
||||||
namespace VocaluxeLib.Draw
|
namespace VocaluxeLib.Draw
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Reference to a texture in the drawing driver
|
||||||
|
/// </summary>
|
||||||
public class CTexture
|
public class CTexture
|
||||||
{
|
{
|
||||||
public readonly int ID;
|
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 = "";
|
public string TexturePath = "";
|
||||||
|
|
||||||
@@ -117,8 +117,8 @@ namespace VocaluxeLib.Draw
|
|||||||
|
|
||||||
private void _CalcRatios()
|
private void _CalcRatios()
|
||||||
{
|
{
|
||||||
WidthRatio = (float)_DataSize.Width / _W2;
|
WidthRatio = (float)_DataSize.Width / _W2;
|
||||||
HeightRatio = (float)_DataSize.Height / _H2;
|
HeightRatio = (float)_DataSize.Height / _H2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,6 @@ namespace VocaluxeLib
|
|||||||
void LoadPreview(CSong song, float start = 0f);
|
void LoadPreview(CSong song, float start = 0f);
|
||||||
void PlayPreview(float start = -1f);
|
void PlayPreview(float start = -1f);
|
||||||
void StopPreview();
|
void StopPreview();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IDrawing
|
public interface IDrawing
|
||||||
@@ -338,6 +337,5 @@ namespace VocaluxeLib
|
|||||||
CTexture GetVideoTexture();
|
CTexture GetVideoTexture();
|
||||||
bool IsPlaying();
|
bool IsPlaying();
|
||||||
float GetLength();
|
float GetLength();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user