From fef58589555270d8142ad73cb369d0d8ba890a74 Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Fri, 1 Jul 2016 13:17:56 +0300 Subject: [PATCH] optimize OpenGL backend -- use batch drawing; part 5 for #271 --- src/dlangui/core/types.d | 7 +++ src/dlangui/graphics/gldrawbuf.d | 2 +- src/dlangui/graphics/glsupport.d | 96 ++++++++++++++++++++++---------- 3 files changed, 74 insertions(+), 31 deletions(-) diff --git a/src/dlangui/core/types.d b/src/dlangui/core/types.d index 7d9fc1cc..fe91a8e2 100644 --- a/src/dlangui/core/types.d +++ b/src/dlangui/core/types.d @@ -116,6 +116,13 @@ struct Rect { right = x1; bottom = y1; } + /// constructs rectangle using two points - (left, top), (right, bottom) coordinates + this(Point pt0, Point pt1) { + left = pt0.x; + top = pt0.y; + right = pt1.x; + bottom = pt1.y; + } /// returns true if rectangle is empty (right <= left || bottom <= top) @property bool empty() { return right <= left || bottom <= top; diff --git a/src/dlangui/graphics/gldrawbuf.d b/src/dlangui/graphics/gldrawbuf.d index 3e396307..23e775f1 100644 --- a/src/dlangui/graphics/gldrawbuf.d +++ b/src/dlangui/graphics/gldrawbuf.d @@ -713,7 +713,7 @@ public: _color = color; } override void draw() { - glSupport.drawLine(_p1, _p2, _color, _color); + glSupport.drawLines([Rect(_p1, _p2)], [_color, _color]); } } diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index 15e80419..59c8a8cb 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -900,29 +900,64 @@ final class GLSupport { */ } - void drawLine(Point p1, Point p2, uint color1, uint color2) { - Color[2] colors; - FillColor(color1, colors[0..1]); - FillColor(color2, colors[1..2]); - float x0 = cast(float)(p1.x); - float y0 = cast(float)(bufferDy-p1.y); - float x1 = cast(float)(p2.x); - float y1 = cast(float)(bufferDy-p2.y); + /// one rect is one line (left, top) - (right, bottom); for one line there are two color items + void drawLines(Rect[] lines, uint[] vertexColors) { + Color[] colors; + colors.length = vertexColors.length; + for (uint i = 0; i < vertexColors.length; i++) + FillColor(vertexColors[i], colors[i .. i + 1]); - // don't flip for framebuffer - if (currentFBO) { - y0 = cast(float)(p1.y); - y1 = cast(float)(p2.y); + float[] vertexArray; + vertexArray.assumeSafeAppend(); + for (uint i = 0; i < lines.length; i++) { + Rect rc = lines[i]; + + float x0 = cast(float)(rc.left); + float y0 = cast(float)(bufferDy-rc.top); + float x1 = cast(float)(rc.right); + float y1 = cast(float)(bufferDy-rc.bottom); + + // don't flip for framebuffer + if (currentFBO) { + y0 = cast(float)(rc.top); + y1 = cast(float)(rc.bottom); + } + + vertexArray ~= x0; + vertexArray ~= y0; + vertexArray ~= Z_2D; + vertexArray ~= x1; + vertexArray ~= y1; + vertexArray ~= Z_2D; } - float[3 * 2] vertices = [ - x0,y0,Z_2D, - x1,y1,Z_2D - ]; - if (_lineProgram !is null) { - _lineProgram.execute(vertices, cast(float[])colors); - } else - Log.e("No program"); + int[] indexes = makeLineIndexesArray(lines.length); + + if (_legacyMode) { + static if (SUPPORT_LEGACY_OPENGL) { + glColor4f(1,1,1,1); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + checkgl!glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + checkgl!glEnableClientState(GL_VERTEX_ARRAY); + checkgl!glEnableClientState(GL_COLOR_ARRAY); + checkgl!glVertexPointer(3, GL_FLOAT, 0, cast(void*)vertexArray.ptr); + checkgl!glColorPointer(4, GL_FLOAT, 0, cast(void*)colors.ptr); + + checkgl!glDrawElements(GL_LINES, cast(int)indexes.length, GL_UNSIGNED_INT, cast(void*)indexes.ptr); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + } + } else { + if (_lineProgram !is null) { + _lineProgram.execute(vertexArray, cast(float[])colors, indexes); + } else + Log.e("No program"); + } } static immutable float Z_2D = -2.0f; @@ -942,6 +977,17 @@ final class GLSupport { return indexes; } + /// make indexes for LINES + protected int[] makeLineIndexesArray(size_t lineCount) { + int[] indexes; + indexes.assumeSafeAppend(); + for (uint i = 0; i < lineCount; i++) { + indexes ~= i * 2 + 0; + indexes ~= i * 2 + 1; + } + return indexes; + } + void drawSolidFillRects(Rect[] rects, uint[] vertexColors) { Color[] colors; colors.length = vertexColors.length; @@ -985,16 +1031,11 @@ final class GLSupport { checkgl!glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); checkgl!glEnableClientState(GL_VERTEX_ARRAY); checkgl!glEnableClientState(GL_COLOR_ARRAY); - //checkgl!glEnableClientState(GL_INDEX_ARRAY); checkgl!glVertexPointer(3, GL_FLOAT, 0, cast(void*)vertexArray.ptr); checkgl!glColorPointer(4, GL_FLOAT, 0, cast(void*)colors.ptr); - //checkgl!glIndexPointer(GL_INT, 0, cast(void*)indexes.ptr); - //checkgl!glDrawArrays(GL_TRIANGLES, 0, cast(int)indexes.length); - //checkgl!glDrawElements(GL_TRIANGLES, cast(int)indexes.length, GL_UNSIGNED_INT, cast(void*)null); checkgl!glDrawElements(GL_TRIANGLES, cast(int)indexes.length, GL_UNSIGNED_INT, cast(void*)indexes.ptr); - //glDisableClientState(GL_INDEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_ALPHA_TEST); @@ -1066,17 +1107,12 @@ final class GLSupport { checkgl!glEnableClientState(GL_COLOR_ARRAY); checkgl!glEnableClientState(GL_VERTEX_ARRAY); checkgl!glEnableClientState(GL_TEXTURE_COORD_ARRAY); - //checkgl!glEnableClientState(GL_INDEX_ARRAY); checkgl!glVertexPointer(3, GL_FLOAT, 0, cast(void*)vertexArray.ptr); checkgl!glTexCoordPointer(2, GL_FLOAT, 0, cast(void*)txcoordArray.ptr); checkgl!glColorPointer(4, GL_FLOAT, 0, cast(void*)colors.ptr); - //checkgl!glIndexPointer(GL_INT, 0, cast(void*)indexes.ptr); - //checkgl!glDrawArrays(GL_TRIANGLES, 0, cast(int)indexes.length); - //checkgl!glDrawElements(GL_TRIANGLES, cast(int)indexes.length, GL_UNSIGNED_INT, cast(void*)null); checkgl!glDrawElements(GL_TRIANGLES, cast(int)indexes.length, GL_UNSIGNED_INT, cast(void*)indexes.ptr); - //glDisableClientState(GL_INDEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY);