fna-workbench

fna-workbench Commit Details


Date:2016-02-04 01:02:41 (9 years 7 months ago)
Author:Ethan Lee
Branch:master
Commit:7dc36b46290b5aefb0e19159daa8ff6cf26d5fdd
Parents: 0c96a8193a9784fb5177183faa9c5169065710ea
Message:ARB_draw_elements_base_vertex, optimize SpriteBatch accordingly

Changes:

File differences

src/Graphics/OpenGLDevice.cs
473473
474474
475475
476
476477
477478
478479
......
11261127
11271128
11281129
1129
1130
11301131
11311132
11321133
......
11341135
11351136
11361137
1137
1138
1139
11381140
11391141
11401142
......
11571159
11581160
11591161
1160
1162
11611163
11621164
11631165
11641166
11651167
11661168
1167
1169
1170
11681171
11691172
11701173
......
19061909
19071910
19081911
1912
1913
1914
1915
1916
19091917
19101918
19111919
private bool supportsMultisampling;
private bool supportsFauxBackbuffer;
private bool supportsBaseVertex;
#endregion
BindIndexBuffer(indices.buffer);
// Draw!
glDrawRangeElements(
glDrawRangeElementsBaseVertex(
XNAToGL.Primitive[(int) primitiveType],
minVertexIndex,
minVertexIndex + numVertices - 1,
shortIndices ?
GLenum.GL_UNSIGNED_SHORT :
GLenum.GL_UNSIGNED_INT,
(IntPtr) (startIndex * (shortIndices ? 2 : 4))
(IntPtr) (startIndex * (shortIndices ? 2 : 4)),
baseVertex
);
}
bool shortIndices = indices.IndexElementSize == IndexElementSize.SixteenBits;
// Draw!
glDrawElementsInstanced(
glDrawElementsInstancedBaseVertex(
XNAToGL.Primitive[(int) primitiveType],
XNAToGL.PrimitiveVerts(primitiveType, primitiveCount),
shortIndices ?
GLenum.GL_UNSIGNED_SHORT :
GLenum.GL_UNSIGNED_INT,
(IntPtr) (startIndex * (shortIndices ? 2 : 4)),
instanceCount
instanceCount,
baseVertex
);
}
bool bindingsUpdated,
int baseVertex
) {
if (supportsBaseVertex)
{
baseVertex = 0;
}
if (bindingsUpdated ||
baseVertex != ldBaseVertex ||
currentEffect != ldEffect ||
src/Graphics/OpenGLDevice_GL.cs
720720
721721
722722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
723744
724745
725746
......
10451066
10461067
10471068
1048
1049
1050
1069
1070
1071
1072
10511073
1052
1074
10531075
1054
1076
10551077
10561078
10571079
10581080
1059
1060
1081
1082
1083
10611084
1062
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
10631103
1064
1065
1066
1067
1068
10691104
10701105
10711106
......
12941329
12951330
12961331
1297
1298
1299
1300
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
13011348
13021349
13031350
......
14331480
14341481
14351482
1436
1483
14371484
14381485
14391486
14401487
14411488
1442
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
14431510
14441511
14451512
......
14491516
14501517
14511518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
14521536
14531537
14541538
);
private DrawRangeElements glDrawRangeElements;
private delegate void DrawElementsInstancedBaseVertex(
GLenum mode,
int count,
GLenum type,
IntPtr indices,
int instanceCount,
int baseVertex
);
private DrawElementsInstancedBaseVertex glDrawElementsInstancedBaseVertex;
private delegate void DrawRangeElementsBaseVertex(
GLenum mode,
int start,
int end,
int count,
GLenum type,
IntPtr indices,
int baseVertex
);
private DrawRangeElementsBaseVertex glDrawRangeElementsBaseVertex;
private delegate void DrawElements(
GLenum mode,
int count,
throw new NoSuitableGraphicsDeviceException(baseErrorString);
}
/* DrawRangeElements is better, but some ES2 targets don't have it. */
IntPtr ep = SDL.SDL_GL_GetProcAddress("glDrawRangeElements");
if (ep != IntPtr.Zero)
/* ARB_draw_elements_base_vertex is ideal! */
IntPtr ep = SDL.SDL_GL_GetProcAddress("glDrawRangeElementsBaseVertex");
supportsBaseVertex = ep != IntPtr.Zero;
if (supportsBaseVertex)
{
glDrawRangeElements = (DrawRangeElements) Marshal.GetDelegateForFunctionPointer(
glDrawRangeElementsBaseVertex = (DrawRangeElementsBaseVertex) Marshal.GetDelegateForFunctionPointer(
ep,
typeof(DrawRangeElements)
typeof(DrawRangeElementsBaseVertex)
);
}
else
{
ep = SDL.SDL_GL_GetProcAddress("glDrawElements");
if (ep == IntPtr.Zero)
/* DrawRangeElements is better, but some ES2 targets don't have it. */
ep = SDL.SDL_GL_GetProcAddress("glDrawRangeElements");
if (ep != IntPtr.Zero)
{
throw new NoSuitableGraphicsDeviceException(baseErrorString);
glDrawRangeElements = (DrawRangeElements) Marshal.GetDelegateForFunctionPointer(
ep,
typeof(DrawRangeElements)
);
glDrawRangeElementsBaseVertex = DrawRangeElementsNoBase;
}
else
{
ep = SDL.SDL_GL_GetProcAddress("glDrawElements");
if (ep == IntPtr.Zero)
{
throw new NoSuitableGraphicsDeviceException(baseErrorString);
}
glDrawElements = (DrawElements) Marshal.GetDelegateForFunctionPointer(
ep,
typeof(DrawElements)
);
glDrawRangeElementsBaseVertex = DrawRangeElementsNoBaseUnchecked;
}
glDrawElements = (DrawElements) Marshal.GetDelegateForFunctionPointer(
ep,
typeof(DrawElements)
);
glDrawRangeElements = DrawRangeElementsUnchecked;
}
/* These functions are NOT supported in ES.
SDL.SDL_GL_GetProcAddress("glVertexAttribDivisor"),
typeof(VertexAttribDivisor)
);
glDrawElementsInstanced = (DrawElementsInstanced) Marshal.GetDelegateForFunctionPointer(
SDL.SDL_GL_GetProcAddress("glDrawElementsInstanced"),
typeof(DrawElementsInstanced)
);
/* The likelihood of someone having BaseVertex but not Instanced is 0...? */
if (supportsBaseVertex)
{
glDrawElementsInstancedBaseVertex = (DrawElementsInstancedBaseVertex) Marshal.GetDelegateForFunctionPointer(
SDL.SDL_GL_GetProcAddress("glDrawElementsInstancedBaseVertex"),
typeof(DrawElementsInstancedBaseVertex)
);
}
else
{
glDrawElementsInstanced = (DrawElementsInstanced) Marshal.GetDelegateForFunctionPointer(
SDL.SDL_GL_GetProcAddress("glDrawElementsInstanced"),
typeof(DrawElementsInstanced)
);
glDrawElementsInstancedBaseVertex = DrawElementsInstancedNoBase;
}
}
catch
{
return result;
}
private void DrawRangeElementsUnchecked(
private void DrawRangeElementsNoBase(
GLenum mode,
int start,
int end,
int count,
GLenum type,
IntPtr indices
IntPtr indices,
int baseVertex
) {
glDrawRangeElements(
mode,
start,
end,
count,
type,
indices
);
}
private void DrawRangeElementsNoBaseUnchecked(
GLenum mode,
int start,
int end,
int count,
GLenum type,
IntPtr indices,
int baseVertex
) {
glDrawElements(
mode,
);
}
private void DrawElementsInstancedNoBase(
GLenum mode,
int count,
GLenum type,
IntPtr indices,
int instanceCount,
int baseVertex
) {
glDrawElementsInstanced(
mode,
count,
type,
indices,
instanceCount
);
}
private void DepthRangeFloat(double near, double far)
{
glDepthRangef((float) near, (float) far);
src/Graphics/SpriteBatch.cs
849849
850850
851851
852
852853
853854
854
855
856
857
858
855
856
857
859858
860859
861860
862
861
863862
864
865
863
866864
867865
868866
......
872870
873871
874872
875
873
876874
877875
878876
......
901899
902900
903901
904
905
902
903
906904
907905
908906
......
917915
918916
919917
920
921
918
919
922920
923921
924922
......
974972
975973
976974
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
975
1005976
1006977
1007978
......
10461017
10471018
10481019
1020
1021
1022
10491023
10501024
10511025
10521026
1053
1054
1055
1056
1027
10571028
10581029
10591030
10601031
1061
1032
10621033
10631034
10641035
......
11051076
11061077
11071078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
11081110
11091111
11101112
spriteData[numSprites].depth = depth;
spriteData[numSprites].effects = effects;
numSprites += 1;
if (sortMode == SpriteSortMode.Immediate)
{
RenderBatch(0, 1);
}
else
{
numSprites += 1;
PushVertices();
DrawPrimitives(texture, 0, 1);
numSprites = 0;
}
}
private void RenderBatch(int offset, int batchSize)
private void PushVertices()
{
GraphicsDevice.Textures[0] = spriteData[offset].texture;
for (int i = 0; i < batchSize; i += 1)
for (int i = 0; i < numSprites; i += 1)
{
/* FIXME: OPTIMIZATION POINT: This method
* allocates like fuck right now! In general,
*/
// Current sprite being calculated
SpriteInfo info = spriteData[i + offset];
SpriteInfo info = spriteData[i];
// Calculate initial sprite information
Vector2 source = new Vector2(
// Calculations performed with inverse texture size
Vector2 inverseTexSize = new Vector2(
(1.0f / (float) spriteData[offset].texture.Width),
(1.0f / (float) spriteData[offset].texture.Height)
(1.0f / (float) info.texture.Width),
(1.0f / (float) info.texture.Height)
);
if ((info.effects & SpriteInfo.SourceInTexels) == SpriteInfo.SourceInTexels)
{
// Calculations done with texture size
if ((info.effects & SpriteInfo.DestSizeInPixels) != SpriteInfo.DestSizeInPixels)
{
destinationSize.X *= spriteData[offset].texture.Width;
destinationSize.Y *= spriteData[offset].texture.Height;
destinationSize.X *= info.texture.Width;
destinationSize.Y *= info.texture.Height;
}
// Calculations performed with rotation
);
}
}
vertexBuffer.SetData(vertexInfo, 0, batchSize * 4, SetDataOptions.None);
if (customEffect != null)
{
foreach (EffectPass pass in customEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
0,
0,
batchSize * 4,
0,
batchSize * 2
);
}
}
else
{
GraphicsDevice.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
0,
0,
batchSize * 4,
0,
batchSize * 2
);
}
vertexBuffer.SetData(vertexInfo, 0, numSprites * 4, SetDataOptions.None);
}
private void FlushBatch()
);
}
PushVertices();
curTexture = spriteData[0].texture;
for (int i = 0; i < numSprites; i += 1)
{
if (spriteData[i].texture != curTexture)
{
if (i > offset)
{
RenderBatch(offset, i - offset);
}
DrawPrimitives(curTexture, offset, i - offset);
curTexture = spriteData[i].texture;
offset = i;
}
}
RenderBatch(offset, numSprites - offset);
DrawPrimitives(curTexture, offset, numSprites - offset);
numSprites = 0;
}
spriteEffectPass.Apply();
}
private void DrawPrimitives(Texture texture, int baseSprite, int batchSize)
{
GraphicsDevice.Textures[0] = texture;
if (customEffect != null)
{
foreach (EffectPass pass in customEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
baseSprite * 4,
0,
batchSize * 4,
0,
batchSize * 2
);
}
}
else
{
GraphicsDevice.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
baseSprite * 4,
0,
batchSize * 4,
0,
batchSize * 2
);
}
}
[System.Diagnostics.Conditional("DEBUG")]
private void CheckBegin(string method)
{

Archive Download the corresponding diff file

Branches

Number of commits:
Page rendered in 0.80370s using 13 queries.