Handle drawing with bounds in one place
Also reduces drawing code a lot...
This commit is contained in:
1 parent
19f81943d6
commit
b48cfa8e77
4 files changed
+268
-431
No files matched your search
+59
-180
@@ -15,6 +15,7 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using SlimDX;
|
||||
using SlimDX.Direct3D9;
|
||||
using System;
|
||||
@@ -420,13 +421,41 @@ namespace Vocaluxe.Lib.Draw
|
||||
return _Device.Viewport.Height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a texture to the vertext buffer
|
||||
/// </summary>
|
||||
/// <param name="texture">Texture to draw</param>
|
||||
/// <param name="dc">Coordinates to draw on</param>
|
||||
/// <param name="color">Color to use</param>
|
||||
/// <param name="isReflection">If true, then color is faded out in y direction</param>
|
||||
private void _DrawTexture(CD3DTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false)
|
||||
{
|
||||
color.A *= CGraphics.GlobalAlpha;
|
||||
int c = color.AsColor().ToArgb();
|
||||
int c2;
|
||||
if (isReflection)
|
||||
{
|
||||
color.A = 0;
|
||||
c2 = color.AsColor().ToArgb();
|
||||
}
|
||||
else
|
||||
c2 = c;
|
||||
|
||||
var vert = new STexturedColoredVertex[4];
|
||||
vert[0] = new STexturedColoredVertex(new Vector3(dc.Wx1, -dc.Wy1, dc.Wz), new Vector2(dc.Tx1, dc.Ty1), c);
|
||||
vert[1] = new STexturedColoredVertex(new Vector3(dc.Wx1, -dc.Wy2, dc.Wz), new Vector2(dc.Tx1, dc.Ty2), c2);
|
||||
vert[2] = new STexturedColoredVertex(new Vector3(dc.Wx2, -dc.Wy2, dc.Wz), new Vector2(dc.Tx2, dc.Ty2), c2);
|
||||
vert[3] = new STexturedColoredVertex(new Vector3(dc.Wx2, -dc.Wy1, dc.Wz), new Vector2(dc.Tx2, dc.Ty1), c);
|
||||
_DrawTexture(vert, texture.D3DTexture, _CalculateRotationMatrix(dc.Rotation, dc.Wx1, dc.Wx2, dc.Wy1, dc.Wy2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a quad a list which will be added and rendered to the vertexbuffer when calling RenderToVertexBuffer to reduce vertexbuffer calls each frame to a minimum
|
||||
/// </summary>
|
||||
/// <param name="vertices">A TexturedColoredVertex array containg 4 vertices</param>
|
||||
/// <param name="tex">The texture the vertex should be textured with</param>
|
||||
/// <param name="rotation">The vertices' rotation</param>
|
||||
private void _AddToVertexBuffer(STexturedColoredVertex[] vertices, Texture tex, Matrix rotation)
|
||||
private void _DrawTexture(STexturedColoredVertex[] vertices, Texture tex, Matrix rotation)
|
||||
{
|
||||
//The vertexbuffer is full, so we need to flush it before we can continue
|
||||
if (_Vertices.Count >= CSettings.VertexBufferElements)
|
||||
@@ -593,41 +622,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <param name="mirrored">True if the texture should be mirrored</param>
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false)
|
||||
{
|
||||
if (rect.W < 1 || rect.H < 1)
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
return;
|
||||
|
||||
SDrawCoords dc;
|
||||
CD3DTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
return;
|
||||
if (!_CalcDrawCoords(texture, rect, out dc, mirrored))
|
||||
return;
|
||||
|
||||
//Calculate the position
|
||||
const float x1 = 0;
|
||||
float x2 = texture.WidthRatio;
|
||||
float y1 = 0;
|
||||
float y2 = texture.HeightRatio;
|
||||
|
||||
//Calculate the size
|
||||
float rx1 = rect.X;
|
||||
float rx2 = rect.X + rect.W;
|
||||
float ry1 = rect.Y;
|
||||
float ry2 = rect.Y + rect.H;
|
||||
|
||||
color.A *= CGraphics.GlobalAlpha;
|
||||
|
||||
Color c = color.AsColor();
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
float tmp = y2;
|
||||
y2 = y1;
|
||||
y1 = tmp;
|
||||
}
|
||||
var vert = new STexturedColoredVertex[4];
|
||||
vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), 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[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb());
|
||||
_AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -640,71 +644,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <param name="mirrored">True if the texture should be mirrored</param>
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
|
||||
{
|
||||
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(bounds.H) < 1 || Math.Abs(bounds.W) < 1 ||
|
||||
Math.Abs(color.A) < 0.01)
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
return;
|
||||
|
||||
if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X)
|
||||
return;
|
||||
|
||||
if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y)
|
||||
return;
|
||||
|
||||
SDrawCoords dc;
|
||||
CD3DTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
return;
|
||||
if (!_CalcDrawCoords(texture, rect, bounds, out dc))
|
||||
return;
|
||||
|
||||
//Calculate the position
|
||||
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
|
||||
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio;
|
||||
float y1 = (bounds.Y - rect.Y) / rect.H * texture.HeightRatio;
|
||||
float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio;
|
||||
|
||||
if (x1 < 0)
|
||||
x1 = 0f;
|
||||
|
||||
if (x2 > texture.WidthRatio)
|
||||
x2 = texture.WidthRatio;
|
||||
|
||||
if (y1 < 0)
|
||||
y1 = 0f;
|
||||
|
||||
if (y2 > texture.HeightRatio)
|
||||
y2 = texture.HeightRatio;
|
||||
|
||||
//Calculate the size
|
||||
float rx1 = rect.X;
|
||||
float rx2 = rect.X + rect.W;
|
||||
float ry1 = rect.Y;
|
||||
float ry2 = rect.Y + rect.H;
|
||||
|
||||
if (rx1 < bounds.X)
|
||||
rx1 = bounds.X;
|
||||
|
||||
if (rx2 > bounds.X + bounds.W)
|
||||
rx2 = bounds.X + bounds.W;
|
||||
|
||||
if (ry1 < bounds.Y)
|
||||
ry1 = bounds.Y;
|
||||
|
||||
if (ry2 > bounds.Y + bounds.H)
|
||||
ry2 = bounds.Y + bounds.H;
|
||||
|
||||
color.A *= CGraphics.GlobalAlpha;
|
||||
|
||||
Color c = color.AsColor();
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
y1 = -y1;
|
||||
y2 = -y2;
|
||||
}
|
||||
var vert = new STexturedColoredVertex[4];
|
||||
vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), 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[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb());
|
||||
_AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -717,36 +666,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <param name="end">A Value ranging from 0 to 1 containing the ending of the texture</param>
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end)
|
||||
{
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
return;
|
||||
SDrawCoords dc;
|
||||
CD3DTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
return;
|
||||
if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end))
|
||||
return;
|
||||
|
||||
float x1 = 0f + begin * texture.WidthRatio;
|
||||
float x2 = texture.WidthRatio * end;
|
||||
const float y1 = 0f;
|
||||
float y2 = texture.HeightRatio;
|
||||
|
||||
float rx1 = rect.X + begin * rect.W;
|
||||
float rx2 = rect.X + end * rect.W;
|
||||
float ry1 = rect.Y;
|
||||
float ry2 = rect.Y + rect.H;
|
||||
|
||||
//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.A *= CGraphics.GlobalAlpha;
|
||||
|
||||
Color c = color.AsColor();
|
||||
|
||||
var vert = new STexturedColoredVertex[4];
|
||||
vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), 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[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb());
|
||||
_AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -760,75 +689,25 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <param name="height">The height of the reflection</param>
|
||||
public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height)
|
||||
{
|
||||
Debug.Assert(height >= 0);
|
||||
|
||||
if (Math.Abs(color.A) < 0.01 || height < 1)
|
||||
return;
|
||||
SDrawCoords dc;
|
||||
CD3DTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
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 ||
|
||||
Math.Abs(color.A) < float.Epsilon || height <= 0f)
|
||||
if (!_CalcDrawCoords(texture, rect, bounds, out dc, true))
|
||||
return;
|
||||
|
||||
if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X)
|
||||
return;
|
||||
if (height > rect.H)
|
||||
height = rect.H;
|
||||
|
||||
if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y)
|
||||
return;
|
||||
|
||||
if (height > bounds.H)
|
||||
height = bounds.H;
|
||||
|
||||
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
|
||||
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio;
|
||||
float y1 = (bounds.Y - rect.Y + rect.H - height) / rect.H * texture.HeightRatio;
|
||||
float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio;
|
||||
|
||||
if (x1 < 0)
|
||||
x1 = 0f;
|
||||
|
||||
if (x2 > texture.WidthRatio)
|
||||
x2 = texture.WidthRatio;
|
||||
|
||||
if (y1 < 0)
|
||||
y1 = 0f;
|
||||
|
||||
if (y2 > texture.HeightRatio)
|
||||
y2 = texture.HeightRatio;
|
||||
|
||||
|
||||
float rx1 = rect.X;
|
||||
float rx2 = rect.X + rect.W;
|
||||
float ry1 = rect.Y + rect.H + space;
|
||||
float ry2 = rect.Y + rect.H + space + height;
|
||||
|
||||
if (rx1 < bounds.X)
|
||||
rx1 = bounds.X;
|
||||
|
||||
if (rx2 > bounds.X + bounds.W)
|
||||
rx2 = bounds.X + bounds.W;
|
||||
|
||||
if (ry1 < bounds.Y + space)
|
||||
ry1 = bounds.Y + space;
|
||||
|
||||
if (ry2 > bounds.Y + bounds.H + space + height)
|
||||
ry2 = bounds.Y + bounds.H + space + height;
|
||||
|
||||
//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.A *= CGraphics.GlobalAlpha;
|
||||
Color c = color.AsColor();
|
||||
color.A = 0;
|
||||
Color transparent = color.AsColor();
|
||||
|
||||
var vert = new STexturedColoredVertex[4];
|
||||
vert[0] = new STexturedColoredVertex(new Vector3(rx1, -ry1, 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, y1), transparent.ToArgb());
|
||||
vert[2] = new STexturedColoredVertex(new Vector3(rx2, -ry2, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), transparent.ToArgb());
|
||||
vert[3] = new STexturedColoredVertex(new Vector3(rx2, -ry1, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb());
|
||||
_AddToVertexBuffer(vert, texture.D3DTexture, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
|
||||
dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing
|
||||
dc.Wy2 += space + height; // Move from end of rect
|
||||
dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2)
|
||||
if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something
|
||||
_DrawTexture(texture, dc, color, true);
|
||||
}
|
||||
#endregion drawing
|
||||
|
||||
|
||||
@@ -213,6 +213,116 @@ namespace Vocaluxe.Lib.Draw
|
||||
#region Textures
|
||||
|
||||
#region private/protected
|
||||
/// <summary>
|
||||
/// Struct that contains texture and world coordinates for drawing
|
||||
/// </summary>
|
||||
protected struct SDrawCoords
|
||||
{
|
||||
/// <summary>
|
||||
/// Texture coordinates
|
||||
/// </summary>
|
||||
public float Tx1, Tx2, Ty1, Ty2;
|
||||
/// <summary>
|
||||
/// World coordinates
|
||||
/// </summary>
|
||||
public float Wx1, Wx2, Wy1, Wy2, Wz;
|
||||
public float Rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the texture and world coordinates for drawing the texture in the rect cropping at the the bounds
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="rect">Rect to draw the texture (might stretch the texture)</param>
|
||||
/// <param name="bounds">Rect to stay in (might crop the texture)</param>
|
||||
/// <param name="drawCoords">Struct for the coordinates</param>
|
||||
/// <param name="mirrored">Mirror on y-axis</param>
|
||||
/// <returns>True if anything will be dawn</returns>
|
||||
protected bool _CalcDrawCoords(TTextureType texture, SRectF rect, SRectF bounds, out SDrawCoords drawCoords, bool mirrored = false)
|
||||
{
|
||||
drawCoords = new SDrawCoords();
|
||||
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(bounds.H) < 1 || Math.Abs(bounds.W) < 1)
|
||||
return false;
|
||||
|
||||
if (bounds.X >= rect.Right || bounds.Right <= rect.X)
|
||||
return false;
|
||||
|
||||
if (bounds.Y >= rect.Bottom || bounds.Bottom <= rect.Y)
|
||||
return false;
|
||||
|
||||
drawCoords.Tx1 = Math.Max(0, (bounds.X - rect.X) / rect.W * texture.WidthRatio);
|
||||
drawCoords.Wx1 = Math.Max(rect.X, bounds.X);
|
||||
drawCoords.Tx2 = Math.Min(1, (bounds.Right - rect.X) / rect.W) * texture.WidthRatio;
|
||||
drawCoords.Wx2 = Math.Min(rect.Right, bounds.Right);
|
||||
|
||||
drawCoords.Ty1 = Math.Max(0, (bounds.Y - rect.Y) / rect.H * texture.HeightRatio);
|
||||
drawCoords.Wy1 = Math.Max(rect.Y, bounds.Y);
|
||||
drawCoords.Ty2 = Math.Min(1, (bounds.Bottom - rect.Y) / rect.H) * texture.HeightRatio;
|
||||
drawCoords.Wy2 = Math.Min(rect.Bottom, bounds.Bottom);
|
||||
|
||||
//TODO: Check this:
|
||||
/*//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;*/
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
float tmp = drawCoords.Ty1;
|
||||
drawCoords.Ty1 = drawCoords.Ty2;
|
||||
drawCoords.Ty2 = tmp;
|
||||
}
|
||||
|
||||
drawCoords.Wz = rect.Z + CGraphics.ZOffset;
|
||||
drawCoords.Rotation = rect.Rotation;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the texture and world coordinates for drawing (a part of) the texture in the rect
|
||||
/// </summary>
|
||||
/// <param name="texture">Texture to draw</param>
|
||||
/// <param name="rect">Rect to draw in (might stretch the texture)</param>
|
||||
/// <param name="drawCoords">Struct for the coordinates</param>
|
||||
/// <param name="mirrored">Mirror on y axis</param>
|
||||
/// <param name="begin">Position of the texture to begin drawing (0 <=x<=1)</param>
|
||||
/// <param name="end">Position of the texture to end drawing (0 <=x<=1)</param>
|
||||
/// <returns>True if anything will be dawn</returns>
|
||||
protected bool _CalcDrawCoords(TTextureType texture, SRectF rect, out SDrawCoords drawCoords, bool mirrored = false, float begin = 0, float end = 1)
|
||||
{
|
||||
drawCoords = new SDrawCoords();
|
||||
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1)
|
||||
return false;
|
||||
if (begin >= 1 || begin >= end)
|
||||
return false;
|
||||
|
||||
Debug.Assert(begin.IsInRange(0, 1) && end.IsInRange(0, 1));
|
||||
|
||||
drawCoords.Tx1 = begin * texture.WidthRatio;
|
||||
drawCoords.Wx1 = rect.X + begin * rect.W;
|
||||
drawCoords.Tx2 = end * texture.WidthRatio;
|
||||
drawCoords.Wx2 = rect.X + end * rect.W;
|
||||
|
||||
drawCoords.Ty1 = 0;
|
||||
drawCoords.Wy1 = rect.Y;
|
||||
drawCoords.Ty2 = texture.HeightRatio;
|
||||
drawCoords.Wy2 = rect.Bottom;
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
float tmp = drawCoords.Ty1;
|
||||
drawCoords.Ty1 = drawCoords.Ty2;
|
||||
drawCoords.Ty2 = tmp;
|
||||
}
|
||||
|
||||
drawCoords.Wz = rect.Z + CGraphics.ZOffset;
|
||||
drawCoords.Rotation = rect.Rotation;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum area allowed for a texture based on the current quality
|
||||
/// </summary>
|
||||
|
||||
+98
-250
@@ -15,6 +15,7 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
@@ -437,290 +438,137 @@ namespace Vocaluxe.Lib.Draw
|
||||
}
|
||||
|
||||
#region drawing
|
||||
private static void _DrawTexture(COGLTexture texture, SDrawCoords dc, SColorF color, bool isReflection = false)
|
||||
{
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
|
||||
GL.MatrixMode(MatrixMode.Texture);
|
||||
GL.PushMatrix();
|
||||
|
||||
if (Math.Abs(dc.Rotation) > float.Epsilon)
|
||||
{
|
||||
GL.Translate(0.5f, 0.5f, 0);
|
||||
GL.Rotate(-dc.Rotation, 0f, 0f, 1f);
|
||||
GL.Translate(-0.5f, -0.5f, 0);
|
||||
}
|
||||
|
||||
GL.Begin(BeginMode.Quads);
|
||||
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
GL.TexCoord2(dc.Tx1, dc.Ty1);
|
||||
GL.Vertex3(dc.Wx1, dc.Wy1, dc.Wz);
|
||||
|
||||
if (isReflection)
|
||||
GL.Color4(color.R, color.G, color.B, 0);
|
||||
GL.TexCoord2(dc.Tx1, dc.Ty2);
|
||||
GL.Vertex3(dc.Wx1, dc.Wy2, dc.Wz);
|
||||
|
||||
GL.TexCoord2(dc.Tx2, dc.Ty2);
|
||||
GL.Vertex3(dc.Wx2, dc.Wy2, dc.Wz);
|
||||
|
||||
if (isReflection)
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
GL.TexCoord2(dc.Tx2, dc.Ty1);
|
||||
GL.Vertex3(dc.Wx2, dc.Wy1, dc.Wz);
|
||||
|
||||
GL.End();
|
||||
|
||||
GL.PopMatrix();
|
||||
|
||||
GL.Disable(EnableCap.Blend);
|
||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||
}
|
||||
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false)
|
||||
{
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
return;
|
||||
SDrawCoords dc;
|
||||
COGLTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
return;
|
||||
|
||||
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(color.A) < 0.01)
|
||||
if (!_CalcDrawCoords(texture, rect, out dc, mirrored))
|
||||
return;
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
||||
|
||||
const float x1 = 0;
|
||||
float x2 = texture.WidthRatio;
|
||||
float y1 = 0;
|
||||
float y2 = texture.HeightRatio;
|
||||
|
||||
float rx1 = rect.X;
|
||||
float rx2 = rect.X + rect.W;
|
||||
float ry1 = rect.Y;
|
||||
float ry2 = rect.Y + rect.H;
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
|
||||
GL.MatrixMode(MatrixMode.Texture);
|
||||
GL.PushMatrix();
|
||||
|
||||
if (Math.Abs(rect.Rotation) > float.Epsilon)
|
||||
{
|
||||
GL.Translate(0.5f, 0.5f, 0);
|
||||
GL.Rotate(-rect.Rotation, 0f, 0f, 1f);
|
||||
GL.Translate(-0.5f, -0.5f, 0);
|
||||
}
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
float tmp = y2;
|
||||
y2 = y1;
|
||||
y1 = tmp;
|
||||
}
|
||||
|
||||
GL.Begin(BeginMode.Quads);
|
||||
|
||||
GL.TexCoord2(x1, y1);
|
||||
GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(x1, y2);
|
||||
GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(x2, y2);
|
||||
GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(x2, y1);
|
||||
GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.End();
|
||||
|
||||
GL.PopMatrix();
|
||||
|
||||
GL.Disable(EnableCap.Blend);
|
||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a texture
|
||||
/// </summary>
|
||||
/// <param name="textureRef">The texture to be drawn</param>
|
||||
/// <param name="rect">A SRectF struct containing the destination coordinates</param>
|
||||
/// <param name="color">A SColorF struct containing a color which the texture will be colored in</param>
|
||||
/// <param name="bounds">A SRectF struct containing which part of the texture should be drawn</param>
|
||||
/// <param name="mirrored">True if the texture should be mirrored</param>
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
|
||||
{
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
return;
|
||||
SDrawCoords dc;
|
||||
COGLTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
return;
|
||||
|
||||
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(bounds.H) < 1 || Math.Abs(bounds.W) < 1 ||
|
||||
Math.Abs(color.A) < 0.01)
|
||||
if (!_CalcDrawCoords(texture, rect, bounds, out dc))
|
||||
return;
|
||||
|
||||
if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X)
|
||||
return;
|
||||
|
||||
if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y)
|
||||
return;
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
||||
|
||||
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
|
||||
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio;
|
||||
float y1 = (bounds.Y - rect.Y) / rect.H * texture.HeightRatio;
|
||||
float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio;
|
||||
|
||||
if (x1 < 0)
|
||||
x1 = 0f;
|
||||
|
||||
if (x2 > texture.WidthRatio)
|
||||
x2 = texture.WidthRatio;
|
||||
|
||||
if (y1 < 0)
|
||||
y1 = 0f;
|
||||
|
||||
if (y2 > texture.HeightRatio)
|
||||
y2 = texture.HeightRatio;
|
||||
|
||||
|
||||
float rx1 = rect.X;
|
||||
float rx2 = rect.X + rect.W;
|
||||
float ry1 = rect.Y;
|
||||
float ry2 = rect.Y + rect.H;
|
||||
|
||||
if (rx1 < bounds.X)
|
||||
rx1 = bounds.X;
|
||||
|
||||
if (rx2 > bounds.X + bounds.W)
|
||||
rx2 = bounds.X + bounds.W;
|
||||
|
||||
if (ry1 < bounds.Y)
|
||||
ry1 = bounds.Y;
|
||||
|
||||
if (ry2 > bounds.Y + bounds.H)
|
||||
ry2 = bounds.Y + bounds.H;
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
|
||||
GL.MatrixMode(MatrixMode.Texture);
|
||||
GL.PushMatrix();
|
||||
|
||||
if (Math.Abs(rect.Rotation) > float.Epsilon)
|
||||
{
|
||||
GL.Translate(0.5f, 0.5f, 0);
|
||||
GL.Rotate(-rect.Rotation, 0f, 0f, 1f);
|
||||
GL.Translate(-0.5f, -0.5f, 0);
|
||||
}
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
float tmp = y2;
|
||||
y2 = y1;
|
||||
y1 = tmp;
|
||||
}
|
||||
|
||||
GL.Begin(BeginMode.Quads);
|
||||
|
||||
GL.TexCoord2(x1, y1);
|
||||
GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(x1, y2);
|
||||
GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(x2, y2);
|
||||
GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(x2, y1);
|
||||
GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.End();
|
||||
|
||||
GL.PopMatrix();
|
||||
|
||||
GL.Disable(EnableCap.Blend);
|
||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a texture
|
||||
/// </summary>
|
||||
/// <param name="textureRef">The texture to be drawn</param>
|
||||
/// <param name="rect">A SRectF struct containing the destination coordinates</param>
|
||||
/// <param name="color">A SColorF struct containing a color which the texture will be colored in</param>
|
||||
/// <param name="begin">A Value ranging from 0 to 1 containing the beginning of the texture</param>
|
||||
/// <param name="end">A Value ranging from 0 to 1 containing the ending of the texture</param>
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end)
|
||||
{
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
return;
|
||||
SDrawCoords dc;
|
||||
COGLTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
return;
|
||||
if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end))
|
||||
return;
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
|
||||
|
||||
GL.Begin(BeginMode.Quads);
|
||||
|
||||
GL.TexCoord2(0f + begin * texture.WidthRatio, 0f);
|
||||
GL.Vertex3(rect.X + begin * rect.W, rect.Y, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(0f + begin * texture.WidthRatio, texture.HeightRatio);
|
||||
GL.Vertex3(rect.X + begin * rect.W, rect.Y + rect.H, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(texture.WidthRatio * end, texture.HeightRatio);
|
||||
GL.Vertex3(rect.X + end * rect.W, rect.Y + rect.H, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.TexCoord2(texture.WidthRatio * end, 0f);
|
||||
GL.Vertex3(rect.X + end * rect.W, rect.Y, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.End();
|
||||
|
||||
GL.Disable(EnableCap.Blend);
|
||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a reflection of a texture
|
||||
/// </summary>
|
||||
/// <param name="textureRef">The texture of which a reflection should be drawn</param>
|
||||
/// <param name="rect">A SRectF struct containing the destination coordinates</param>
|
||||
/// <param name="color">A SColorF struct containing a color which the texture will be colored in</param>
|
||||
/// <param name="bounds">A SRectF struct containing which part of the texture should be drawn</param>
|
||||
/// <param name="space">The space between the texture and the reflection</param>
|
||||
/// <param name="height">The height of the reflection</param>
|
||||
public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height)
|
||||
{
|
||||
Debug.Assert(height >= 0);
|
||||
|
||||
if (Math.Abs(color.A) < 0.01 || height < 1)
|
||||
return;
|
||||
SDrawCoords dc;
|
||||
COGLTexture texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
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 ||
|
||||
Math.Abs(color.A) < float.Epsilon || height <= float.Epsilon)
|
||||
if (!_CalcDrawCoords(texture, rect, bounds, out dc, true))
|
||||
return;
|
||||
|
||||
if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X)
|
||||
return;
|
||||
if (height > rect.H)
|
||||
height = rect.H;
|
||||
|
||||
if (bounds.Y > rect.Y + rect.H || bounds.Y + bounds.H < rect.Y)
|
||||
return;
|
||||
|
||||
if (height > bounds.H)
|
||||
height = bounds.H;
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
||||
|
||||
float x1 = (bounds.X - rect.X) / rect.W * texture.WidthRatio;
|
||||
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * texture.WidthRatio;
|
||||
float y1 = (bounds.Y - rect.Y + rect.H - height) / rect.H * texture.HeightRatio;
|
||||
float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * texture.HeightRatio;
|
||||
|
||||
if (x1 < 0)
|
||||
x1 = 0f;
|
||||
|
||||
if (x2 > texture.WidthRatio)
|
||||
x2 = texture.WidthRatio;
|
||||
|
||||
if (y1 < 0)
|
||||
y1 = 0f;
|
||||
|
||||
if (y2 > texture.HeightRatio)
|
||||
y2 = texture.HeightRatio;
|
||||
|
||||
|
||||
float rx1 = rect.X;
|
||||
float rx2 = rect.X + rect.W;
|
||||
float ry1 = rect.Y + rect.H + space;
|
||||
float ry2 = rect.Y + rect.H + space + height;
|
||||
|
||||
if (rx1 < bounds.X)
|
||||
rx1 = bounds.X;
|
||||
|
||||
if (rx2 > bounds.X + bounds.W)
|
||||
rx2 = bounds.X + bounds.W;
|
||||
|
||||
if (ry1 < bounds.Y + space)
|
||||
ry1 = bounds.Y + space;
|
||||
|
||||
if (ry2 > bounds.Y + bounds.H + space + height)
|
||||
ry2 = bounds.Y + bounds.H + space + height;
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
|
||||
GL.MatrixMode(MatrixMode.Texture);
|
||||
GL.PushMatrix();
|
||||
|
||||
if (Math.Abs(rect.Rotation) > float.Epsilon)
|
||||
{
|
||||
GL.Translate(0.5f, 0.5f, 0);
|
||||
GL.Rotate(-rect.Rotation, 0f, 0f, 1f);
|
||||
GL.Translate(-0.5f, -0.5f, 0);
|
||||
}
|
||||
|
||||
|
||||
GL.Begin(BeginMode.Quads);
|
||||
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
GL.TexCoord2(x2, y2);
|
||||
GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.Color4(color.R, color.G, color.B, 0f);
|
||||
GL.TexCoord2(x2, y1);
|
||||
GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.Color4(color.R, color.G, color.B, 0f);
|
||||
GL.TexCoord2(x1, y1);
|
||||
GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
GL.TexCoord2(x1, y2);
|
||||
GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset);
|
||||
|
||||
GL.End();
|
||||
|
||||
|
||||
GL.PopMatrix();
|
||||
|
||||
GL.Disable(EnableCap.Blend);
|
||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||
dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing
|
||||
dc.Wy2 += space + height; // Move from end of rect
|
||||
dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2)
|
||||
if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something
|
||||
_DrawTexture(texture, dc, color, true);
|
||||
}
|
||||
#endregion drawing
|
||||
|
||||
|
||||
@@ -62,11 +62,11 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
private void _CalcRatios()
|
||||
{
|
||||
// OpenGL has a problem with partial (NPOT) textures, so we remove 1 pixel
|
||||
if (_DataSize.Width == W2)
|
||||
WidthRatio = 1f;
|
||||
else
|
||||
{
|
||||
// OpenGL has a problem with partial (NPOT) textures, so we remove 1 pixel
|
||||
int mod = 0;
|
||||
if (_DataSize.Width > 1)
|
||||
mod = -1;
|
||||
|
||||
Reference in new issue
Block a user