Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/application
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-30 04:34:10 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-30 04:34:10 +1000
commitd5fbd2001b0ad3591a7f969dfd75c809ab55b40e (patch)
treeb6b9361bfa854daf3e6be45d572407508340d12d /source/application
parent47a527ebbff91cf530cb8758828679ef0e3334f2 (diff)
RenderPrimitive micro-optimizations
Diffstat (limited to 'source/application')
-rw-r--r--source/application/StarRenderer.cpp95
-rw-r--r--source/application/StarRenderer.hpp27
-rw-r--r--source/application/StarRenderer_opengl20.cpp15
-rw-r--r--source/application/StarRenderer_opengl20.hpp3
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;