diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-30 04:34:10 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-30 04:34:10 +1000 |
commit | d5fbd2001b0ad3591a7f969dfd75c809ab55b40e (patch) | |
tree | b6b9361bfa854daf3e6be45d572407508340d12d /source/application | |
parent | 47a527ebbff91cf530cb8758828679ef0e3334f2 (diff) |
RenderPrimitive micro-optimizations
Diffstat (limited to 'source/application')
-rw-r--r-- | source/application/StarRenderer.cpp | 95 | ||||
-rw-r--r-- | source/application/StarRenderer.hpp | 27 | ||||
-rw-r--r-- | source/application/StarRenderer_opengl20.cpp | 15 | ||||
-rw-r--r-- | source/application/StarRenderer_opengl20.hpp | 3 |
4 files changed, 98 insertions, 42 deletions
diff --git a/source/application/StarRenderer.cpp b/source/application/StarRenderer.cpp index 51b11c7..f4aa4fe 100644 --- a/source/application/StarRenderer.cpp +++ b/source/application/StarRenderer.cpp @@ -12,49 +12,78 @@ EnumMap<TextureFiltering> const TextureFilteringNames{ {TextureFiltering::Linear, "Linear"} }; -RenderQuad renderTexturedRect(TexturePtr texture, Vec2F minPosition, float textureScale, Vec4B color, float param1) { - if (!texture) - throw RendererException("renderTexturedRect called with null texture"); +RenderQuad::RenderQuad(Vec2F posA, Vec2F posB, Vec2F posC, Vec2F posD, Vec4B color, float param1) : texture() { + a = { posA, { 0, 0 }, color, param1 }; + b = { posB, { 0, 0 }, color, param1 }; + c = { posC, { 0, 0 }, color, param1 }; + d = { posD, { 0, 0 }, color, param1 }; +} - auto textureSize = Vec2F(texture->size()); - return { - move(texture), - RenderVertex{minPosition, Vec2F(0, 0), color, param1}, - RenderVertex{minPosition + Vec2F(textureSize[0], 0) * textureScale, Vec2F(textureSize[0], 0), color, param1}, - RenderVertex{minPosition + Vec2F(textureSize[0], textureSize[1]) * textureScale, Vec2F(textureSize[0], textureSize[1]), color, param1}, - RenderVertex{minPosition + Vec2F(0, textureSize[1]) * textureScale, Vec2F(0, textureSize[1]), color, param1} - }; +RenderQuad::RenderQuad(TexturePtr tex, Vec2F minPosition, float textureScale, Vec4B color, float param1) : texture(move(tex)) { + Vec2F size = Vec2F(texture->size()); + a = { minPosition, { 0, 0 }, color, param1}; + b = { { (minPosition[0] + size[0] * textureScale), minPosition[1] }, { size[0], 0 }, color, param1 }; + c = { { (minPosition[0] + size[0] * textureScale), (minPosition[1] + size[1] * textureScale) }, size, color, param1 }; + d = { { minPosition[0], (minPosition[1] + size[1] * textureScale) }, { 0, size[1] }, color, param1 }; } -RenderQuad renderTexturedRect(TexturePtr texture, RectF const& screenCoords, Vec4B color, float param1) { - if (!texture) - throw RendererException("renderTexturedRect called with null texture"); +RenderQuad::RenderQuad(TexturePtr tex, RectF const& screenCoords, Vec4B color, float param1) : texture(move(tex)) { + Vec2F size = Vec2F(texture->size()); + a = { screenCoords.min(), { 0, 0 }, color, param1 }; + b = { { screenCoords.xMax(), screenCoords.yMin(), }, { size[0], 0.f }, color, param1 }; + c = { screenCoords.max(), size, color, param1}; + d = { { screenCoords.xMin(), screenCoords.yMax(), }, { 0.f, size[1] }, color, param1 }; +} + +RenderQuad::RenderQuad(TexturePtr tex, Vec2F posA, Vec2F uvA, Vec2F posB, Vec2F uvB, Vec2F posC, Vec2F uvC, Vec2F posD, Vec2F uvD, Vec4B color, float param1) : texture(move(tex)) { + a = { posA, uvA, color, param1 }; + b = { posB, uvB, color, param1 }; + c = { posC, uvC, color, param1 }; + d = { posD, uvD, color, param1 }; +} + +RenderQuad::RenderQuad(TexturePtr tex, RenderVertex vA, RenderVertex vB, RenderVertex vC, RenderVertex vD) + : texture(move(tex)), a(move(vA)), b(move(vB)), c(move(vC)), d(move(vD)) {} + +RenderQuad::RenderQuad(RectF const& rect, Vec4B color, float param1) + : a{ rect.min(), {}, color, param1 } + , b{ { rect.xMax(), rect.yMin()}, {}, color, param1 } + , c{ rect.max(), {}, color, param1 } + , d{ { rect.xMin() ,rect.yMax() }, {}, color, param1 } {}; - auto textureSize = Vec2F(texture->size()); - return { - move(texture), - RenderVertex{{screenCoords.xMin(), screenCoords.yMin()}, Vec2F(0, 0), color, param1}, - RenderVertex{{screenCoords.xMax(), screenCoords.yMin()}, Vec2F(textureSize[0], 0), color, param1}, - RenderVertex{{screenCoords.xMax(), screenCoords.yMax()}, Vec2F(textureSize[0], textureSize[1]), color, param1}, - RenderVertex{{screenCoords.xMin(), screenCoords.yMax()}, Vec2F(0, textureSize[1]), color, param1} - }; + +RenderPoly::RenderPoly(List<Vec2F> const& verts, Vec4B color, float param1) { + vertexes.reserve(verts.size()); + for (Vec2F const& v : verts) + vertexes.append({ v, { 0, 0 }, color, param1 }); +} + +RenderTriangle::RenderTriangle(Vec2F posA, Vec2F posB, Vec2F posC, Vec4B color, float param1) : texture() { + a = { posA, { 0, 0 }, color, param1 }; + b = { posB, { 0, 0 }, color, param1 }; + c = { posC, { 0, 0 }, color, param1 }; +} + +RenderTriangle::RenderTriangle(TexturePtr tex, Vec2F posA, Vec2F uvA, Vec2F posB, Vec2F uvB, Vec2F posC, Vec2F uvC, Vec4B color, float param1) : texture(move(tex)) { + a = { posA, uvA, color, param1 }; + b = { posB, uvB, color, param1 }; + c = { posC, uvC, color, param1 }; +} + +RenderQuad renderTexturedRect(TexturePtr texture, Vec2F minPosition, float textureScale, Vec4B color, float param1) { + return RenderQuad(move(texture), minPosition, textureScale, color, param1); +} + +RenderQuad renderTexturedRect(TexturePtr texture, RectF const& screenCoords, Vec4B color, float param1) { + return RenderQuad(move(texture), screenCoords, color, param1); } RenderQuad renderFlatRect(RectF const& rect, Vec4B color, float param1) { - return { - {}, - RenderVertex{{rect.xMin(), rect.yMin()}, {}, color, param1}, - RenderVertex{{rect.xMax(), rect.yMin()}, {}, color, param1}, - RenderVertex{{rect.xMax(), rect.yMax()}, {}, color, param1}, - RenderVertex{{rect.xMin(), rect.yMax()}, {}, color, param1} - }; + return RenderQuad(rect, color, param1); } RenderPoly renderFlatPoly(PolyF const& poly, Vec4B color, float param1) { - RenderPoly renderPoly; - for (auto const& v : poly) - renderPoly.vertexes.append({v, {}, color, param1}); - return renderPoly; + return RenderPoly(poly.vertexes(), color, param1); } } diff --git a/source/application/StarRenderer.hpp b/source/application/StarRenderer.hpp index e12590f..908f121 100644 --- a/source/application/StarRenderer.hpp +++ b/source/application/StarRenderer.hpp @@ -50,17 +50,35 @@ struct RenderVertex { float param1; }; -struct RenderTriangle { +class RenderTriangle { +public: + RenderTriangle() = default; + RenderTriangle(Vec2F posA, Vec2F posB, Vec2F posC, Vec4B color = Vec4B::filled(255), float param1 = 0.0f); + RenderTriangle(TexturePtr tex, Vec2F posA, Vec2F uvA, Vec2F posB, Vec2F uvB, Vec2F posC, Vec2F uvC, Vec4B color = Vec4B::filled(255), float param1 = 0.0f); + TexturePtr texture; RenderVertex a, b, c; }; -struct RenderQuad { +class RenderQuad { +public: + RenderQuad() = default; + RenderQuad(Vec2F posA, Vec2F posB, Vec2F posC, Vec2F posD, Vec4B color = Vec4B::filled(255), float param1 = 0.0f); + RenderQuad(TexturePtr tex, Vec2F minScreen, float textureScale = 1.0f, Vec4B color = Vec4B::filled(255), float param1 = 0.0f); + RenderQuad(TexturePtr tex, RectF const& screenCoords, Vec4B color = Vec4B::filled(255), float param1 = 0.0f); + RenderQuad(TexturePtr tex, Vec2F posA, Vec2F uvA, Vec2F posB, Vec2F uvB, Vec2F posC, Vec2F uvC, Vec2F posD, Vec2F uvD, Vec4B color = Vec4B::filled(255), float param1 = 0.0f); + RenderQuad(TexturePtr tex, RenderVertex vA, RenderVertex vB, RenderVertex vC, RenderVertex vD); + RenderQuad(RectF const& rect, Vec4B color = Vec4B::filled(255), float param1 = 0.0f); + TexturePtr texture; RenderVertex a, b, c, d; }; -struct RenderPoly { +class RenderPoly { +public: + RenderPoly() = default; + RenderPoly(List<Vec2F> const& verts, Vec4B color, float param1 = 0.0f); + TexturePtr texture; List<RenderVertex> vertexes; }; @@ -100,7 +118,7 @@ public: // Transforms the given primitives into a form suitable for the underlying // graphics system and stores it for fast replaying. - virtual void set(List<RenderPrimitive> primitives) = 0; + virtual void set(List<RenderPrimitive>& primitives) = 0; }; typedef Variant<bool, int, float, Vec2F, Vec3F, Vec4F> RenderEffectParameter; @@ -136,6 +154,7 @@ public: virtual TextureGroupPtr createTextureGroup(TextureGroupSize size = TextureGroupSize::Medium, TextureFiltering filtering = TextureFiltering::Nearest) = 0; virtual RenderBufferPtr createRenderBuffer() = 0; + virtual List<RenderPrimitive>& immediatePrimitives() = 0; virtual void render(RenderPrimitive primitive) = 0; virtual void renderBuffer(RenderBufferPtr const& renderBuffer, Mat3F const& transformation = Mat3F::identity()) = 0; diff --git a/source/application/StarRenderer_opengl20.cpp b/source/application/StarRenderer_opengl20.cpp index 82d4845..375149e 100644 --- a/source/application/StarRenderer_opengl20.cpp +++ b/source/application/StarRenderer_opengl20.cpp @@ -366,6 +366,10 @@ RenderBufferPtr OpenGl20Renderer::createRenderBuffer() { return createGlRenderBuffer(); } +List<RenderPrimitive>& OpenGl20Renderer::immediatePrimitives() { + return m_immediatePrimitives; +} + void OpenGl20Renderer::render(RenderPrimitive primitive) { m_immediatePrimitives.append(move(primitive)); } @@ -399,7 +403,8 @@ void OpenGl20Renderer::finishFrame() { flushImmediatePrimitives(); // Make sure that the immediate render buffer doesn't needlessly lock texutres // from being compressed. - m_immediateRenderBuffer->set({}); + List<RenderPrimitive> empty; + m_immediateRenderBuffer->set(empty); filter(m_liveTextureGroups, [](auto const& p) { unsigned const CompressionsPerFrame = 1; @@ -569,7 +574,7 @@ OpenGl20Renderer::GlRenderBuffer::~GlRenderBuffer() { glDeleteBuffers(1, &vb.vertexBuffer); } -void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive> primitives) { +void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive>& primitives) { for (auto const& texture : usedTextures) { if (auto gt = as<GlGroupedTexture>(texture.get())) gt->decrementBufferUseCount(); @@ -637,7 +642,7 @@ void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive> primitives) { return {float(textureIndex), Vec2F(glTexture->glTextureCoordinateOffset())}; }; - auto appendBufferVertex = [&](RenderVertex v, float textureIndex, Vec2F textureCoordinateOffset) { + auto appendBufferVertex = [&](RenderVertex const& v, float textureIndex, Vec2F textureCoordinateOffset) { GlRenderVertex glv { v.screenCoordinate, v.textureCoordinate + textureCoordinateOffset, @@ -682,6 +687,7 @@ void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive> primitives) { } } + vertexBuffers.reserve(primitives.size() * 6); finishCurrentBuffer(); for (auto const& vb : oldVertexBuffers) @@ -733,7 +739,8 @@ void OpenGl20Renderer::flushImmediatePrimitives() { if (m_immediatePrimitives.empty()) return; - m_immediateRenderBuffer->set(take(m_immediatePrimitives)); + m_immediateRenderBuffer->set(m_immediatePrimitives); + m_immediatePrimitives.resize(0); renderGlBuffer(*m_immediateRenderBuffer, Mat3F::identity()); } diff --git a/source/application/StarRenderer_opengl20.hpp b/source/application/StarRenderer_opengl20.hpp index dfab534..ff82d3a 100644 --- a/source/application/StarRenderer_opengl20.hpp +++ b/source/application/StarRenderer_opengl20.hpp @@ -32,6 +32,7 @@ public: TextureGroupPtr createTextureGroup(TextureGroupSize size, TextureFiltering filtering) override; RenderBufferPtr createRenderBuffer() override; + List<RenderPrimitive>& immediatePrimitives() override; void render(RenderPrimitive primitive) override; void renderBuffer(RenderBufferPtr const& renderBuffer, Mat3F const& transformation) override; @@ -128,7 +129,7 @@ private: ~GlRenderBuffer(); - void set(List<RenderPrimitive> primitives) override; + void set(List<RenderPrimitive>& primitives) override; RefPtr<GlTexture> whiteTexture; ByteArray accumulationBuffer; |