diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs
index d685857d..2d9e26db 100644
--- a/Vocaluxe/Lib/Draw/CDirect3D.cs
+++ b/Vocaluxe/Lib/Draw/CDirect3D.cs
@@ -49,6 +49,9 @@ namespace Vocaluxe.Lib.Draw
#endregion private vars
+ ///
+ /// Creates a new Instance of the CDirect3D Class
+ ///
public CDirect3D()
{
this.Icon = new System.Drawing.Icon(Path.Combine(System.Environment.CurrentDirectory, CSettings.sIcon));
@@ -86,6 +89,8 @@ namespace Vocaluxe.Lib.Draw
_PresentParameters.Multisample = MultisampleType.None;
_PresentParameters.MultisampleQuality = 0;
+ //Apply antialiasing and check if antialiasing mode is supported
+ #region Antialiasing
int quality = 0;
if (CConfig.AAMode == EAntiAliasingModes.x0)
{
@@ -132,12 +137,15 @@ namespace Vocaluxe.Lib.Draw
else
CLog.LogError("[Direct3D] This AAMode is not supported by this device or driver, fallback to no AA");
}
+ #endregion Antialiasing
- if(CConfig.VSync == EOffOn.TR_CONFIG_ON)
+ //Apply the VSync configuration
+ if (CConfig.VSync == EOffOn.TR_CONFIG_ON)
_PresentParameters.PresentationInterval = PresentInterval.Default;
else
_PresentParameters.PresentationInterval = PresentInterval.Immediate;
-
+
+ //GMA 950 graphics devices can only process vertices in software mode
Capabilities caps = _D3D.GetDeviceCaps(_D3D.Adapters.DefaultAdapter.Adapter, DeviceType.Hardware);
CreateFlags flags = CreateFlags.None;
if ((caps.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
@@ -147,12 +155,15 @@ namespace Vocaluxe.Lib.Draw
_Device = new Device(_D3D, _D3D.Adapters.DefaultAdapter.Adapter, DeviceType.Hardware, Handle, flags, _PresentParameters);
this.CenterToScreen();
-
- blankMap = new Bitmap(1, 1); //Quick and Dirty, used for DrawColor
+
+ //This creates a new white texture and adds it to the texture pool
+ //This texture is used for the DrawRect method
+ blankMap = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(blankMap);
g.Clear(Color.White);
g.Dispose();
blankTexture = AddTexture(blankMap);
+
h = ClientSize.Height;
w = ClientSize.Width;
blankMap.Dispose();
@@ -186,9 +197,12 @@ namespace Vocaluxe.Lib.Draw
RResize();
}
#endregion form events
-
+ ///
+ /// Resizes the viewport
+ ///
private void RResize()
{
+ // The window was minimized, so restore it to the last known size
if (ClientSize.Width == 0 || ClientSize.Height == 0)
{
ClientSize = _SizeBeforeMinimize;
@@ -202,28 +216,41 @@ namespace Vocaluxe.Lib.Draw
if ((float)w / (float)h > CSettings.GetRenderAspect())
{
+ //The windows's width is too big
w = (int)Math.Round((float)h * CSettings.GetRenderAspect());
x = (ClientSize.Width - w) / 2;
}
else
{
+ //The windows's height is too big
h = (int)Math.Round((float)w / CSettings.GetRenderAspect());
y = (ClientSize.Height - h) / 2;
}
+ //Apply the new sizes to the PresentParameters
_PresentParameters.BackBufferWidth = ClientSize.Width;
_PresentParameters.BackBufferHeight = ClientSize.Height;
ClearScreen();
+ //To set new PresentParameters the device has to be resetted
Reset();
+ //All configurations got flushed due to Reset(), so apply them again
Init();
+ //Set the new Viewport
_Device.Viewport = new Viewport(x, y, w, h);
+ //Store size so it can get restored after the window gets minimized
_SizeBeforeMinimize = ClientSize;
}
}
+ ///
+ /// Triggers the Fullscreen mode
+ ///
private void EnterFullScreen()
{
+ //This currently not using real fullscreen mode but a borderless window
+ //Real fullscreen could be gained setting _PresentParameters.Windowed = true
+ //And calling Reset() and Init() after
_OldSize = this.ClientSize;
this.ClientSize = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
this.FormBorderStyle = FormBorderStyle.None;
@@ -237,7 +264,9 @@ namespace Vocaluxe.Lib.Draw
CConfig.SaveConfig();
}
-
+ ///
+ /// Triggers the windowed mode
+ ///
private void LeaveFullScreen()
{
this.ClientSize = _OldSize;
@@ -312,34 +341,45 @@ namespace Vocaluxe.Lib.Draw
#region implementation
+ ///
+ /// Inits the Device
+ ///
+ /// True if it succeeded else false
public bool Init()
{
- this.Text = CSettings.GetFullVersionText();
- Matrix translate = Matrix.Translation(new Vector3(-CSettings.iRenderW / 2, CSettings.iRenderH / 2, 0));
- Matrix projection = Matrix.OrthoOffCenterLH(-CSettings.iRenderW / 2, CSettings.iRenderW / 2, -CSettings.iRenderH / 2, CSettings.iRenderH / 2, CSettings.zNear, CSettings.zFar);
- _VertexBuffer = new VertexBuffer(_Device, 4 * Marshal.SizeOf(typeof(TexturedColoredVertex)), Usage.WriteOnly | Usage.Dynamic, VertexFormat.Position | VertexFormat.Texture1 | VertexFormat.Diffuse, Pool.Default);
- _Device.SetStreamSource(0, _VertexBuffer, 0, Marshal.SizeOf(typeof(TexturedColoredVertex)));
- _Device.VertexDeclaration = TexturedColoredVertex.GetDeclaration(_Device);
- _Device.SetTransform(TransformState.Projection, projection);
- _Device.SetTransform(TransformState.World, translate);
- _Device.SetRenderState(RenderState.CullMode, Cull.None);
- _Device.SetRenderState(RenderState.AlphaBlendEnable, true);
- _Device.SetRenderState(RenderState.Lighting, false);
- _Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
- _Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
- if(_PresentParameters.Multisample != MultisampleType.None)
- _Device.SetRenderState(RenderState.MultisampleAntialias, true);
- _Device.SetSamplerState(0, SamplerState.MinFilter, TextureFilter.Linear);
- _Device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Linear);
- _Device.SetSamplerState(0, SamplerState.MipFilter, TextureFilter.Linear);
- _Device.SetSamplerState(0, SamplerState.AddressU, TextureAddress.Clamp);
- _Device.SetSamplerState(0, SamplerState.AddressV, TextureAddress.Clamp);
- _Device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
- _Device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse);
- _Device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate);
- return true;
+ if (!_Device.Disposed)
+ {
+ this.Text = CSettings.GetFullVersionText();
+ Matrix translate = Matrix.Translation(new Vector3(-CSettings.iRenderW / 2, CSettings.iRenderH / 2, 0));
+ Matrix projection = Matrix.OrthoOffCenterLH(-CSettings.iRenderW / 2, CSettings.iRenderW / 2, -CSettings.iRenderH / 2, CSettings.iRenderH / 2, CSettings.zNear, CSettings.zFar);
+ _VertexBuffer = new VertexBuffer(_Device, 4 * Marshal.SizeOf(typeof(TexturedColoredVertex)), Usage.WriteOnly | Usage.Dynamic, VertexFormat.Position | VertexFormat.Texture1 | VertexFormat.Diffuse, Pool.Default);
+ _Device.SetStreamSource(0, _VertexBuffer, 0, Marshal.SizeOf(typeof(TexturedColoredVertex)));
+ _Device.VertexDeclaration = TexturedColoredVertex.GetDeclaration(_Device);
+ _Device.SetTransform(TransformState.Projection, projection);
+ _Device.SetTransform(TransformState.World, translate);
+ _Device.SetRenderState(RenderState.CullMode, Cull.None);
+ _Device.SetRenderState(RenderState.AlphaBlendEnable, true);
+ _Device.SetRenderState(RenderState.Lighting, false);
+ _Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
+ _Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
+ if (_PresentParameters.Multisample != MultisampleType.None)
+ _Device.SetRenderState(RenderState.MultisampleAntialias, true);
+ _Device.SetSamplerState(0, SamplerState.MinFilter, TextureFilter.Linear);
+ _Device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Linear);
+ _Device.SetSamplerState(0, SamplerState.MipFilter, TextureFilter.Linear);
+ _Device.SetSamplerState(0, SamplerState.AddressU, TextureAddress.Clamp);
+ _Device.SetSamplerState(0, SamplerState.AddressV, TextureAddress.Clamp);
+ _Device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
+ _Device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse);
+ _Device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate);
+ return true;
+ }
+ else
+ return false;
}
-
+ ///
+ /// Starts the rendering
+ ///
public void MainLoop()
{
_Run = true;
@@ -358,36 +398,45 @@ namespace Vocaluxe.Lib.Draw
if (_Run)
{
+ //Clear the previous Frame
ClearScreen();
+ //We want to begin drawing
_Device.BeginScene();
_Run = _Run && CGraphics.Draw();
- _Run = CGraphics.UpdateGameLogic(_Keys, _Mouse);
+ //We finished drawing the frame
_Device.EndScene();
+ _Run = CGraphics.UpdateGameLogic(_Keys, _Mouse);
try
{
+ //Now push the frame to the Viewport
_Device.Present();
}
catch (Direct3D9Exception)
{
- if (_Device.TestCooperativeLevel() == ResultCode.DeviceNotReset) //Do only reset when the device in a resetable state!
+ //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 ((CSettings.bFullScreen && !_fullscreen) || (!CSettings.bFullScreen && _fullscreen))
{
if (!_fullscreen)
EnterFullScreen();
else
- LeaveFullScreen();
+ LeaveFullScreen();
}
if (CTime.IsRunning())
delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds());
if (delay >= 1)
System.Threading.Thread.Sleep(delay);
-
+ //Calculate the FPS Rate and restart the timer after a frame
CTime.CalculateFPS();
CTime.Restart();
}
@@ -396,19 +445,27 @@ namespace Vocaluxe.Lib.Draw
}
}
+ ///
+ /// Resets the device, all objects in the Direct3D default pool get flushed and need to be recreated
+ ///
public void Reset()
{
+ //Dispose all objects in the default pool, those need to be recreated
TexturedColoredVertex.GetDeclaration(_Device).Dispose();
_VertexBuffer.Dispose();
_Device.Reset(_PresentParameters);
}
+ ///
+ /// Unloads all Textures and other objects used by Direct3D for rendering
+ ///
+ ///
public bool Unload()
{
+ //Dispose all textures
for (int i = 0; i < _D3DTextures.Count; i++)
{
_D3DTextures[i].Dispose();
-
}
TexturedColoredVertex.GetDeclaration(_Device).Dispose();
_VertexBuffer.Dispose();
@@ -417,21 +474,40 @@ namespace Vocaluxe.Lib.Draw
return true;
}
+ ///
+ /// Gets the current viewport width
+ ///
+ /// The current viewport width
public int GetScreenWidth()
{
return _Device.Viewport.Width;
}
+ ///
+ /// Gets the current viewport height
+ ///
+ /// The current viewport height
public int GetScreenHeight()
{
return _Device.Viewport.Height;
}
+ ///
+ /// Calculates the bounds for a CText object
+ ///
+ /// The CText object of which the bounds should be calculated for
+ /// RectangleF object containing the bounds
public RectangleF GetTextBounds(CText text)
{
return GetTextBounds(text, text.Height);
}
+ ///
+ /// Calculates the bounds for a CText object
+ ///
+ /// The CText object of which the bounds should be calculated for
+ /// The height of the CText object
+ /// RectangleF object containing the bounds
public RectangleF GetTextBounds(CText text, float Height)
{
CFonts.Height = Height;
@@ -442,21 +518,38 @@ namespace Vocaluxe.Lib.Draw
#region Basic Draw Methods
+ ///
+ /// Removes all textures from the screen
+ ///
public void ClearScreen()
{
_Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
}
+
+ ///
+ /// Not implemented yet
+ ///
+ ///
public STexture CopyScreen()
{
+ //FIXME
STexture texture = new STexture(-1);
return texture;
}
+ ///
+ /// Not implemented yet
+ ///
+ ///
public void CopyScreen(ref STexture Texture)
{
+ //FIXME
return;
}
+ ///
+ /// Creates a Screenshot of the current frame
+ ///
public void MakeScreenShot()
{
string file = "Screenshot_";
@@ -466,6 +559,7 @@ namespace Vocaluxe.Lib.Draw
while (File.Exists(Path.Combine(path, file + i.ToString("00000") + ".bmp")))
i++;
+ //create a surface of the frame
using (Surface surface = _Device.GetBackBuffer(0, 0))
{
Bitmap screen = new Bitmap(Surface.ToStream(surface, ImageFileFormat.Bmp));
@@ -476,22 +570,54 @@ namespace Vocaluxe.Lib.Draw
_Mouse.Visible = true;
}
+ ///
+ /// Draws a line
+ ///
+ /// The alpha value from 0-255
+ /// The red value from 0-255
+ /// The red value from 0-255
+ /// The red value from 0-255
+ /// The width of the line
+ /// The start x-value
+ /// The start y-value
+ /// The end x-value
+ /// The end y-value
public void DrawLine(int a, int r, int g, int b, int w, int x1, int y1, int x2, int y2)
{
SColorF color = new SColorF(a / 255, g / 255, b / 255, a / 255);
DrawTexture(blankTexture, new SRectF(x1, y1, x2, y2, 1), color);
}
+ ///
+ /// Draws a text string
+ ///
+ /// The text to be drawn
+ /// The text's x-position
+ /// The text's y-position
+ /// The text's height
public void DrawText(string Text, int x, int y, int h)
{
DrawText(Text, x, y, h, 0f);
}
+ ///
+ /// Draws a text string
+ ///
+ /// The text to be drawn
+ /// The text's x-position
+ /// The text's y-position
+ /// The text's height
+ /// The text's x-position
public void DrawText(string Text, int x, int y, float h, float z)
{
CFonts.DrawText(Text, h, x, y, z, new SColorF(1f, 1f, 1f, 1f));
}
+ ///
+ /// Draws a colored rectangle
+ ///
+ /// The color in which the rectangle will be drawn in
+ /// The coordinates in a SRectF struct
public void DrawColor(SColorF color, SRectF rect)
{
DrawTexture(blankTexture, rect, color);
@@ -499,6 +625,11 @@ namespace Vocaluxe.Lib.Draw
#endregion Basic Draw Methods
#region Textures
+ ///
+ /// Adds a texture and stores it in the VRam
+ ///
+ /// The texture's filepath
+ /// A STexture object containing the added texture
public STexture AddTexture(string TexturePath)
{
if (System.IO.File.Exists(TexturePath))
@@ -519,18 +650,30 @@ namespace Vocaluxe.Lib.Draw
return new STexture(-1);
}
+ ///
+ /// Calculates the next power of two
+ ///
+ /// The value of which the next power of two will be calculated
+ /// The next power of two
private static float NextPowerOfTwo(float n)
{
if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
return (float)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
}
+ ///
+ /// Adds a texture and stores it in the Vram
+ ///
+ /// The Bitmap of which the texute will be created from
+ /// The path to the texture
+ /// A STexture object containing the added texture
public STexture AddTexture(Bitmap bmp, string TexturePath)
{
STexture texture = new STexture(-1);
if (bmp.Height == 0 || bmp.Width == 0)
return texture;
int MaxSize;
+ //Apply the right max size
switch (CConfig.TextureQuality)
{
case ETextureQuality.TR_CONFIG_TEXTURE_LOWEST:
@@ -571,10 +714,13 @@ namespace Vocaluxe.Lib.Draw
texture.width = w;
texture.height = h;
+ //Older graphics card can only handle textures with sizes being powers of two
texture.w2 = (float)NextPowerOfTwo(w);
texture.h2 = (float)NextPowerOfTwo(h);
+ //Create a new Bitmap with the new sizes
Bitmap bmp2 = new Bitmap((int)texture.w2, (int)texture.h2);
+ //Scale the texture
Graphics g = Graphics.FromImage(bmp2);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
@@ -583,13 +729,17 @@ namespace Vocaluxe.Lib.Draw
texture.width_ratio = 1f;
texture.height_ratio = 1f;
-
+
+ //Fill the new Bitmap with the texture data
BitmapData bmp_data = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
byte[] Data = new byte[4 * bmp2.Width * bmp2.Height];
Marshal.Copy(bmp_data.Scan0, Data, 0, Data.Length);
bmp2.UnlockBits(bmp_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
Texture t = new Texture(_Device, (int)texture.w2, (int)texture.h2, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed);
+ //Lock the texture and fill it with the data
DataRectangle rect = t.LockRectangle(0, LockFlags.None);
for (int i = 0; i < Data.Length; )
{
@@ -609,10 +759,15 @@ namespace Vocaluxe.Lib.Draw
texture.rect = new SRectF(0f, 0f, texture.width, texture.height, 0f);
texture.TexturePath = String.Empty;
_Textures.Add(texture);
-
+
return texture;
}
+ ///
+ /// Adds a texture and stores it in the Vram
+ ///
+ /// The Bitmap of which the texute will be created from
+ /// A STexture object containing the added texture
public STexture AddTexture(Bitmap bmp)
{
return AddTexture(bmp, String.Empty);
@@ -622,7 +777,7 @@ namespace Vocaluxe.Lib.Draw
{
byte[] PointerData = new Byte[4 * W * H];
Marshal.Copy(Data, PointerData, 0, PointerData.Length);
- return AddTexture(W, H , ref PointerData);
+ return AddTexture(W, H, ref PointerData);
}
public STexture AddTexture(int W, int H, ref byte[] Data)
@@ -655,6 +810,12 @@ namespace Vocaluxe.Lib.Draw
return texture;
}
+ ///
+ /// Updates the data of a texture
+ ///
+ /// The texture to update
+ /// A Pointer containing the data of which the texture should be updated
+ /// True if succeeded
public bool UpdateTexture(ref STexture Texture, IntPtr Data)
{
byte[] PointerData = new Byte[4 * (int)Texture.width * (int)Texture.height];
@@ -663,6 +824,12 @@ namespace Vocaluxe.Lib.Draw
return UpdateTexture(ref Texture, ref PointerData);
}
+ ///
+ /// Updates the data of a texture
+ ///
+ /// The texture to update
+ /// A byte array containing the new texture's data
+ /// True if succeeded
public bool UpdateTexture(ref STexture Texture, ref byte[] Data)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
@@ -679,10 +846,17 @@ namespace Vocaluxe.Lib.Draw
Texture.height_ratio = Texture.height / NextPowerOfTwo(Texture.height);
Texture.width_ratio = Texture.width / NextPowerOfTwo(Texture.width);
+ return true;
}
- return true;
+ else
+ return false;
}
+ ///
+ /// Checks if a texture exists
+ ///
+ /// The texture to check
+ /// True if the texture exists
private bool _TextureExists(STexture Texture)
{
if ((Texture.index > 0) && (_Textures.Count > 0))
@@ -698,17 +872,22 @@ namespace Vocaluxe.Lib.Draw
return false;
}
+ ///
+ /// Removes a texture from the Vram
+ ///
+ /// The texture to be removed
public void RemoveTexture(ref STexture Texture)
{
if ((Texture.index >= 0) && (_Textures.Count > 0))
{
for (int i = 0; i < _Textures.Count; i++)
{
- if (_Textures[i].index == Texture.index)
+ if (_Textures[i].index == Texture.index)
{
_D3DTextures[Texture.index].Dispose();
_Textures.RemoveAt(i);
Texture.index = -1;
+ //Calling the garbage collector to get rid of all unused objects
GC.Collect();
break;
}
@@ -716,40 +895,78 @@ namespace Vocaluxe.Lib.Draw
}
}
+ ///
+ /// Draws a texture
+ ///
+ /// The texture to be drawn
public void DrawTexture(STexture Texture)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
DrawTexture(Texture, Texture.rect, Texture.color);
}
+ ///
+ /// Draws a texture
+ ///
+ /// The texture to be drawn
+ /// A SRectF struct containing the destination coordinates
public void DrawTexture(STexture Texture, SRectF rect)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
DrawTexture(Texture, rect, Texture.color, false);
}
+ ///
+ /// Draws a texture
+ ///
+ /// The texture to be drawn
+ /// A SRectF struct containing the destination coordinates
+ /// A SColorF struct containing a color which the texture will be colored in
public void DrawTexture(STexture Texture, SRectF rect, SColorF color)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
DrawTexture(Texture, rect, color, false);
}
+ ///
+ /// Draws a texture
+ ///
+ /// The texture to be drawn
+ /// A SRectF struct containing the destination coordinates
+ /// A SColorF struct containing a color which the texture will be colored in
+ /// A SRectF struct containing which part of the texture should be drawn
public void DrawTexture(STexture Texture, SRectF rect, SColorF color, SRectF bounds)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
DrawTexture(Texture, rect, color, bounds, false);
}
+ ///
+ /// Draws a texture
+ ///
+ /// The texture to be drawn
+ /// A SRectF struct containing the destination coordinates
+ /// A SColorF struct containing a color which the texture will be colored in
+ /// True if the texture should be mirrored
public void DrawTexture(STexture Texture, SRectF rect, SColorF color, bool mirrored)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
DrawTexture(Texture, rect, color, new SRectF(0, 0, CSettings.iRenderW, CSettings.iRenderH, rect.Z), mirrored);
}
+ ///
+ /// Draws a texture
+ ///
+ /// The texture to be drawn
+ /// A SRectF struct containing the destination coordinates
+ /// A SColorF struct containing a color which the texture will be colored in
+ /// A SRectF struct containing which part of the texture should be drawn
+ /// True if the texture should be mirrored
public void DrawTexture(STexture Texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
{
+ //Calculate the position
float x1 = (bounds.X - rect.X) / rect.W * Texture.width_ratio;
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * Texture.width_ratio;
float y1 = (bounds.Y - rect.Y) / rect.H * Texture.height_ratio;
@@ -767,6 +984,7 @@ namespace Vocaluxe.Lib.Draw
if (y2 > Texture.height_ratio)
y2 = Texture.height_ratio;
+ //Calculate the size
float rx1 = rect.X;
float rx2 = rect.X + rect.W;
float ry1 = rect.Y;
@@ -784,7 +1002,8 @@ namespace Vocaluxe.Lib.Draw
if (ry2 > bounds.Y + bounds.H)
ry2 = bounds.Y + bounds.H;
- rx1 -= 0.5f; // Align pixels
+ //Align the pixels because Direct3D expects the pixels to be the left top corner
+ rx1 -= 0.5f;
ry1 -= 0.5f;
rx2 -= 0.5f;
ry2 -= 0.5f;
@@ -796,6 +1015,8 @@ namespace Vocaluxe.Lib.Draw
if (color.G >= 1f)
color.G = 1f;
+ //Apply rotation
+ //FIXME: Rotated textures get distorted when they hit the border of the window
if (rect.Rotation != 0)
{
rect.Rotation = rect.Rotation * (float)Math.PI / 180;
@@ -807,12 +1028,18 @@ namespace Vocaluxe.Lib.Draw
Matrix rotation = Matrix.RotationZ(-rect.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
Matrix result = translationA * rotation * translationB * originTranslation;
_Device.SetTransform(TransformState.World, result);
}
Color c = Color.FromArgb((int)(color.A * 255 * CGraphics.GlobalAlpha), (int)(color.R * 255), (int)(color.G * 255), (int)(color.B * 255));
+
+ //Create new vertices and write them into a vertexbuffer
DataStream stream = _VertexBuffer.Lock(0, 0, LockFlags.Discard);
if (!mirrored)
{
@@ -834,9 +1061,12 @@ namespace Vocaluxe.Lib.Draw
}
_VertexBuffer.Unlock();
stream.Dispose();
+ //Set the texture
_Device.SetTexture(0, _D3DTextures[Texture.index]);
+ //Draw 2 triangles to build a quad
_Device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
+ //Reapply old matrices if the texture was rotated
if (rect.Rotation != 0)
{
Matrix originTranslation = Matrix.Translation(new Vector3(-CSettings.iRenderW / 2, CSettings.iRenderH / 2, 0));
@@ -845,38 +1075,89 @@ namespace Vocaluxe.Lib.Draw
}
}
+ ///
+ /// Draws a texture
+ ///
+ /// The texture to be drawn
+ /// A SRectF struct containing the destination coordinates
+ /// A SColorF struct containing a color which the texture will be colored in
+ /// A Value ranging from 0 to 1 containing the beginning of the texture
+ /// A Value ranging from 0 to 1 containing the ending of the texture
+
public void DrawTexture(STexture Texture, SRectF rect, SColorF color, float begin, float end)
{
-
float x1 = 0f + begin * Texture.width_ratio;
float x2 = Texture.width_ratio * end;
float y1 = 0f;
float y2 = Texture.height_ratio;
- float rx1 = rect.X + begin* rect.W;
+ float rx1 = rect.X + begin * rect.W;
float rx2 = rect.X + end * rect.W;
float ry1 = rect.Y;
float ry2 = rect.Y + rect.H;
- rx1 -= 0.5f; // Align pixels
+ //Align the pixels because Direct3D expects the pixels to be the left top corner
+ rx1 -= 0.5f;
ry1 -= 0.5f;
rx2 -= 0.5f;
ry2 -= 0.5f;
Color c = Color.FromArgb((int)(color.A * 255 * CGraphics.GlobalAlpha), (int)(color.R * 255), (int)(color.G * 255), (int)(color.B * 255));
+
+ //Apply rotation
+ //FIXME: Rotated textures get distorted when they hit the border of the window
+ if (rect.Rotation != 0)
+ {
+ rect.Rotation = rect.Rotation * (float)Math.PI / 180;
+ float centerX = (rx1 + rx2) / 2f;
+ float centerY = -(ry1 + ry2) / 2f;
+
+ Matrix originTranslation = _Device.GetTransform(TransformState.World);
+ Matrix translationA = Matrix.Translation(-centerX, -centerY, 0);
+ Matrix rotation = Matrix.RotationZ(-rect.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
+ Matrix result = translationA * rotation * translationB * originTranslation;
+
+ _Device.SetTransform(TransformState.World, result);
+ }
+
+ //Create new vertices and write them into a vertexbuffer
DataStream stream = _VertexBuffer.Lock(0, 0, LockFlags.Discard);
stream.WriteRange(new[] {
- new TexturedColoredVertex(new Vector3(rx1, ry1*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), c.ToArgb()),
- new TexturedColoredVertex(new Vector3(rx1, ry2*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()),
- new TexturedColoredVertex(new Vector3(rx2, ry2*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()),
- new TexturedColoredVertex(new Vector3(rx2, ry1*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb()),
+ new TexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), c.ToArgb()),
+ new TexturedColoredVertex(new Vector3(rx1, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()),
+ new TexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()),
+ new TexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb()),
});
_VertexBuffer.Unlock();
stream.Dispose();
+ //Set the texture
_Device.SetTexture(0, _D3DTextures[Texture.index]);
+ //Draw 2 triangles to build a quad
_Device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
+
+ //Reapply old matrices if the texture was rotated
+ if (rect.Rotation != 0)
+ {
+ Matrix originTranslation = Matrix.Translation(new Vector3(-CSettings.iRenderW / 2, CSettings.iRenderH / 2, 0));
+ _Device.SetTransform(TransformState.World, originTranslation);
+ }
}
+ ///
+ /// Draws a reflection of a texture
+ ///
+ /// The texture of which a reflection should be drawn
+ /// A SRectF struct containing the destination coordinates
+ /// A SColorF struct containing a color which the texture will be colored in
+ /// A SRectF struct containing which part of the texture should be drawn
+ /// The space between the texture and the reflection
+ /// The height of the reflection
public void DrawTextureReflection(STexture Texture, SRectF rect, SColorF color, SRectF bounds, float space, float height)
{
if (rect.W == 0f || rect.H == 0f || bounds.H == 0f || bounds.W == 0f || color.A == 0f || height <= 0f)
@@ -928,29 +1209,65 @@ namespace Vocaluxe.Lib.Draw
if (ry2 > bounds.Y + bounds.H + space + height)
ry2 = bounds.Y + bounds.H + space + height;
- rx1 -= 0.5f; // Align pixels
+ //Align the pixels because Direct3D expects the pixels to be the left top corner
+ rx1 -= 0.5f;
ry1 -= 0.5f;
rx2 -= 0.5f;
ry2 -= 0.5f;
- DataStream stream = _VertexBuffer.Lock(0, 0, LockFlags.Discard);
+ //Apply rotation
+ //FIXME: Rotated textures get distorted when they hit the border of the window
+ if (rect.Rotation != 0)
+ {
+ rect.Rotation = rect.Rotation * (float)Math.PI / 180;
+ float centerX = (rx1 + rx2) / 2f;
+ float centerY = -(ry1 + ry2) / 2f;
+
+ Matrix originTranslation = _Device.GetTransform(TransformState.World);
+ Matrix translationA = Matrix.Translation(-centerX, -centerY, 0);
+ Matrix rotation = Matrix.RotationZ(-rect.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
+ Matrix result = translationA * rotation * translationB * originTranslation;
+
+ _Device.SetTransform(TransformState.World, result);
+ }
Color c = Color.FromArgb((int)(color.A * 255 * CGraphics.GlobalAlpha), (int)(color.R * 255), (int)(color.G * 255), (int)(color.B * 255));
- Color t = Color.FromArgb(0, (int)(color.R * 255), (int)(color.G * 255), (int)(color.B * 255));
+ Color transparent = Color.FromArgb(0, (int)(color.R * 255), (int)(color.G * 255), (int)(color.B * 255));
+ //Create new vertices and write them into a vertexbuffer
+ DataStream stream = _VertexBuffer.Lock(0, 0, LockFlags.Discard);
stream.WriteRange(new[] {
new TexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()),
- new TexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), t.ToArgb()),
- new TexturedColoredVertex(new Vector3(rx1, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), t.ToArgb()),
+ new TexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), transparent.ToArgb()),
+ new TexturedColoredVertex(new Vector3(rx1, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), transparent.ToArgb()),
new TexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()),
});
_VertexBuffer.Unlock();
stream.Dispose();
+ //Set the texture
_Device.SetTexture(0, _D3DTextures[Texture.index]);
+ //Draw 2 triangles to build a quad
_Device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
+
+ //Reapply old matrices if the texture was rotated
+ if (rect.Rotation != 0)
+ {
+ Matrix originTranslation = Matrix.Translation(new Vector3(-CSettings.iRenderW / 2, CSettings.iRenderH / 2, 0));
+ _Device.SetTransform(TransformState.World, originTranslation);
+ }
}
}
+ ///
+ /// Gets the count of current textures
+ ///
+ /// The amount of textures
public int TextureCount()
{
return _Textures.Count;
@@ -963,12 +1280,12 @@ namespace Vocaluxe.Lib.Draw
{
private static VertexDeclaration sDeclaration;
public static VertexElement[] Elements =
- {
- new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
- new VertexElement(0, sizeof(float) *3, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
- new VertexElement(0, sizeof(float) * 3 + sizeof(float)*2, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
- VertexElement.VertexDeclarationEnd
- };
+ {
+ new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
+ new VertexElement(0, sizeof(float) *3, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
+ new VertexElement(0, sizeof(float) * 3 + sizeof(float)*2, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
+ VertexElement.VertexDeclarationEnd
+ };
public Vector3 Position;
public Vector2 Texture;