Faster rendering (most draw calls are without bounds)

Fix for D3D
This commit is contained in:
Flamefire committed 2014-09-13 16:19:25 +02:00
1 parent 128abf61b9
commit 9fce9fe962
4 files changed
+198 -105

No files matched your search

+106 -65
View File
@@ -69,7 +69,8 @@ namespace Vocaluxe.Lib.Draw
/// </summary>
public CDirect3D()
{
_Form = new CRenderFormHook();
_Form = new CRenderFormHook {ClientSize = new Size(CConfig.ScreenW, CConfig.ScreenH)};
try
{
_D3D = new Direct3D();
@@ -184,37 +185,45 @@ namespace Vocaluxe.Lib.Draw
// The window was minimized, so restore it to the last known size
if (_Form.ClientSize.Width == 0 || _Form.ClientSize.Height == 0)
_Form.ClientSize = _SizeBeforeMinimize;
if (!_Run)
return;
_H = _Form.ClientSize.Height;
_W = _Form.ClientSize.Width;
int newH = _Form.ClientSize.Height;
int newW = _Form.ClientSize.Width;
_Y = 0;
_X = 0;
if (_W / (float)_H > CSettings.GetRenderAspect())
if (newW / (float)newH > CSettings.GetRenderAspect())
{
//The windows width is too big
_W = (int)Math.Round(_H * CSettings.GetRenderAspect());
_X = (_Form.ClientSize.Width - _W) / 2;
newW = (int)Math.Round(newH * CSettings.GetRenderAspect());
_X = (_Form.ClientSize.Width - newW) / 2;
}
else
{
//The windows height is too big
_H = (int)Math.Round(_W / CSettings.GetRenderAspect());
_Y = (_Form.ClientSize.Height - _H) / 2;
newH = (int)Math.Round(newW / CSettings.GetRenderAspect());
_Y = (_Form.ClientSize.Height - newH) / 2;
}
if (_H == newH && _W == newW)
return;
_H = newH;
_W = newW;
//Apply the new sizes to the PresentParameters
_PresentParameters.BackBufferWidth = _Form.ClientSize.Width;
_PresentParameters.BackBufferHeight = _Form.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();
if (_Run)
{
ClearScreen();
//To set new PresentParameters the device has to be resetted
_Reset();
//All configurations got flushed due to Reset(), so apply them again
_InitDevice();
//Set the new Viewport
_Device.Viewport = new Viewport(_X, _Y, _W, _H);
}
//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 = _Form.ClientSize;
}
@@ -249,6 +258,21 @@ namespace Vocaluxe.Lib.Draw
if (_Device.Disposed)
return false;
_InitDevice();
//This creates a new white texture and adds it to the texture pool
//This texture is used for the DrawRect method
using (var blankMap = new Bitmap(1, 1))
using (Graphics g = Graphics.FromImage(blankMap))
{
g.Clear(Color.White);
_BlankTexture = AddTexture(blankMap);
}
return true;
}
private void _InitDevice()
{
_AdjustNewBorders();
_VertexBuffer = new VertexBuffer(_Device, CSettings.VertexBufferElements * (4 * Marshal.SizeOf(typeof(STexturedColoredVertex))), Usage.WriteOnly | Usage.Dynamic,
@@ -304,17 +328,6 @@ namespace Vocaluxe.Lib.Draw
stream.WriteRange(indices);
_IndexBuffer.Unlock();
_Device.Indices = _IndexBuffer;
//This creates a new white texture and adds it to the texture pool
//This texture is used for the DrawRect method
using (var blankMap = new Bitmap(1, 1))
{
Graphics g = Graphics.FromImage(blankMap);
g.Clear(Color.White);
g.Dispose();
_BlankTexture = AddTexture(blankMap);
}
return true;
}
protected override void _OnBeforeDraw()
@@ -342,7 +355,7 @@ namespace Vocaluxe.Lib.Draw
if (_Device.TestCooperativeLevel() == ResultCode.DeviceNotReset)
{
_Reset();
Init();
_InitDevice();
}
}
Application.DoEvents();
@@ -382,7 +395,7 @@ namespace Vocaluxe.Lib.Draw
public override void Unload()
{
base.Unload();
STexturedColoredVertex.GetDeclaration(_Device).Dispose();
STexturedColoredVertex.DisposeDeclaration();
_VertexBuffer.Dispose();
_IndexBuffer.Dispose();
_Device.Dispose();
@@ -572,7 +585,6 @@ namespace Vocaluxe.Lib.Draw
#endregion Basic Draw Methods
#region Textures
protected override Texture _CreateTexture(CTexture texture, byte[] data)
{
//Create a new texture in the managed pool, which does not need to be recreated on a lost device
@@ -661,7 +673,40 @@ namespace Vocaluxe.Lib.Draw
/// <param name="mirrored">True if the texture should be mirrored</param>
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, bool mirrored = false)
{
DrawTexture(texture, rect, color, new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, rect.Z), mirrored);
if (rect.W < 1 || rect.H < 1)
return;
Texture t = _GetTexture(texture);
if (t == null)
return;
//Calculate the position
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)
{
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, t, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
}
/// <summary>
@@ -674,9 +719,18 @@ namespace Vocaluxe.Lib.Draw
/// <param name="mirrored">True if the texture should be mirrored</param>
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
{
if (!_TextureExists(texture))
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)
return;
if (_Textures[texture.ID] == null)
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;
Texture t = _GetTexture(texture);
if (t == null)
return;
//Calculate the position
@@ -715,43 +769,21 @@ namespace Vocaluxe.Lib.Draw
if (ry2 > bounds.Y + bounds.H)
ry2 = bounds.Y + bounds.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;
if (color.A > 1)
color.A = 1;
if (color.R > 1)
color.R = 1;
if (color.G > 1)
color.G = 1;
if (color.B > 1)
color.B = 1;
Color c = color.AsColor();
if (!mirrored)
if (mirrored)
{
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, _Textures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
}
else
{
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, _Textures[texture.ID], _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
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, t, _CalculateRotationMatrix(rect.Rotation, rx1, rx2, ry1, ry2));
}
/// <summary>
@@ -941,6 +973,15 @@ namespace Vocaluxe.Lib.Draw
return _Declaration;
}
public static void DisposeDeclaration()
{
if (_Declaration != null && !_Declaration.Disposed)
{
_Declaration.Dispose();
_Declaration = null;
}
}
}
}
}
+9 -2
View File
@@ -148,7 +148,7 @@ namespace Vocaluxe.Lib.Draw
CTexture s;
try
{
s = AddTexture(bmp);
s = AddTexture(bmp, texturePath);
}
finally
{
@@ -157,12 +157,18 @@ namespace Vocaluxe.Lib.Draw
return s;
}
public CTexture AddTexture(Bitmap bmp)
{
return AddTexture(bmp, "");
}
/// <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>
/// <param name="texturePath"></param>
/// <returns>A STexture object containing the added texture</returns>
public CTexture AddTexture(Bitmap bmp)
public CTexture AddTexture(Bitmap bmp, string texturePath)
{
if (bmp.Height == 0 || bmp.Width == 0)
return null;
@@ -194,6 +200,7 @@ namespace Vocaluxe.Lib.Draw
int h = Math.Min(bmp.Height, maxSize);
CTexture texture = _GetNewTextureRef(bmp.Width, bmp.Height, w, h);
texture.TexturePath = texturePath;
Bitmap bmp2 = null;
try
-1
View File
@@ -180,7 +180,6 @@ namespace Vocaluxe.Lib.Draw
_Form.Resize += _OnResize;
_Form.Load += _OnLoad;
_Form.ClientSize = new Size(CConfig.ScreenW, CConfig.ScreenH);
_SizeBeforeMinimize = _Form.ClientSize;
_CenterToScreen();
+83 -37
View File
@@ -99,7 +99,8 @@ namespace Vocaluxe.Lib.Draw
public COpenGL()
{
_Form = new CFormHook();
_Form = new CFormHook {ClientSize = new Size(CConfig.ScreenW, CConfig.ScreenH)};
//Check AA Mode
CConfig.AAMode = (EAntiAliasingModes)_CheckAntiAliasingMode((int)CConfig.AAMode);
@@ -440,11 +441,12 @@ namespace Vocaluxe.Lib.Draw
GL.BindTexture(TextureTarget.Texture2D, t.Name);
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture.W2, texture.H2, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture.DataSize.Width, texture.DataSize.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
@@ -478,8 +480,8 @@ namespace Vocaluxe.Lib.Draw
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.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
@@ -554,7 +556,65 @@ namespace Vocaluxe.Lib.Draw
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, bool mirrored = false)
{
DrawTexture(texture, rect, color, new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, rect.Z), mirrored);
CGLTexture t = _GetTexture(texture);
if (t == null)
return;
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(color.A) < 0.01)
return;
GL.BindTexture(TextureTarget.Texture2D, t.Name);
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 = ry2;
ry2 = ry1;
ry1 = 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);
}
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
@@ -563,8 +623,8 @@ namespace Vocaluxe.Lib.Draw
if (t == null)
return;
if (Math.Abs(rect.W) < float.Epsilon || Math.Abs(rect.H) < float.Epsilon || Math.Abs(bounds.H) < float.Epsilon || Math.Abs(bounds.W) < float.Epsilon ||
Math.Abs(color.A) < float.Epsilon)
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)
return;
if (bounds.X > rect.X + rect.W || bounds.X + bounds.W < rect.X)
@@ -623,42 +683,28 @@ namespace Vocaluxe.Lib.Draw
GL.Translate(-0.5f, -0.5f, 0);
}
if (!mirrored)
if (mirrored)
{
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();
float tmp = ry2;
ry2 = ry1;
ry1 = tmp;
}
else
{
GL.Begin(BeginMode.Quads);
GL.TexCoord2(x2, y2);
GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(x2, y1);
GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset);
GL.TexCoord2(x1, y1);
GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset);
GL.TexCoord2(x1, y1);
GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset);
GL.TexCoord2(x1, y2);
GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset);
GL.TexCoord2(x1, y2);
GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset);
GL.TexCoord2(x2, y2);
GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset);
GL.End();
}
GL.TexCoord2(x2, y1);
GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset);
GL.End();
GL.PopMatrix();