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

summaryrefslogtreecommitdiff
path: root/source/rendering
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/rendering
parent47a527ebbff91cf530cb8758828679ef0e3334f2 (diff)
RenderPrimitive micro-optimizations
Diffstat (limited to 'source/rendering')
-rw-r--r--source/rendering/StarDrawablePainter.cpp35
-rw-r--r--source/rendering/StarEnvironmentPainter.cpp99
-rw-r--r--source/rendering/StarTextPainter.cpp5
-rw-r--r--source/rendering/StarTilePainter.cpp75
-rw-r--r--source/rendering/StarWorldPainter.cpp17
5 files changed, 128 insertions, 103 deletions
diff --git a/source/rendering/StarDrawablePainter.cpp b/source/rendering/StarDrawablePainter.cpp
index 647d209..8c50b2b 100644
--- a/source/rendering/StarDrawablePainter.cpp
+++ b/source/rendering/StarDrawablePainter.cpp
@@ -9,24 +9,25 @@ DrawablePainter::DrawablePainter(RendererPtr renderer, AssetTextureGroupPtr text
void DrawablePainter::drawDrawable(Drawable const& drawable) {
Vec4B color = drawable.color.toRgba();
+ auto& primitives = m_renderer->immediatePrimitives();
if (auto linePart = drawable.part.ptr<Drawable::LinePart>()) {
auto line = linePart->line;
line.translate(drawable.position);
-
Vec2F left = Vec2F(vnorm(line.diff())).rot90() * linePart->width / 2.0f;
- m_renderer->render(RenderQuad{{},
- RenderVertex{Vec2F(line.min()) + left, Vec2F(), color, drawable.fullbright ? 0.0f : 1.0f},
- RenderVertex{Vec2F(line.min()) - left, Vec2F(), color, drawable.fullbright ? 0.0f : 1.0f},
- RenderVertex{Vec2F(line.max()) - left, Vec2F(), color, drawable.fullbright ? 0.0f : 1.0f},
- RenderVertex{Vec2F(line.max()) + left, Vec2F(), color, drawable.fullbright ? 0.0f : 1.0f}
- });
-
+
+ float fullbright = drawable.fullbright ? 0.0f : 1.0f;
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(),
+ line.min() + left,
+ line.min() - left,
+ line.max() - left,
+ line.max() + left,
+ color, fullbright);
} else if (auto polyPart = drawable.part.ptr<Drawable::PolyPart>()) {
- auto poly = polyPart->poly;
+ PolyF poly = polyPart->poly;
poly.translate(drawable.position);
- m_renderer->render(renderFlatPoly(poly, color, 0.0f));
+ primitives.emplace_back(std::in_place_type_t<RenderPoly>(), poly.vertexes(), color, 0.0f);
} else if (auto imagePart = drawable.part.ptr<Drawable::ImagePart>()) {
TexturePtr texture = m_textureGroup->loadTexture(imagePart->image);
@@ -41,12 +42,14 @@ void DrawablePainter::drawDrawable(Drawable const& drawable) {
Vec2F upperRight = transformation.transformVec2(Vec2F(imageRect.xMax(), imageRect.yMax()));
Vec2F upperLeft = transformation.transformVec2(Vec2F(imageRect.xMin(), imageRect.yMax()));
- m_renderer->render(RenderQuad{move(texture),
- {lowerLeft, {0, 0}, color, drawable.fullbright ? 0.0f : 1.0f},
- {lowerRight, {textureSize[0], 0}, color, drawable.fullbright ? 0.0f : 1.0f},
- {upperRight, {textureSize[0], textureSize[1]}, color, drawable.fullbright ? 0.0f : 1.0f},
- {upperLeft, {0, textureSize[1]}, color, drawable.fullbright ? 0.0f : 1.0f}
- });
+ float param1 = drawable.fullbright ? 0.0f : 1.0f;
+
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(), move(texture),
+ lowerLeft, Vec2F{0, 0},
+ lowerRight, Vec2F{textureSize[0], 0},
+ upperRight, Vec2F{textureSize[0], textureSize[1]},
+ upperLeft, Vec2F{0, textureSize[1]},
+ color, param1);
}
}
diff --git a/source/rendering/StarEnvironmentPainter.cpp b/source/rendering/StarEnvironmentPainter.cpp
index 9d3e45a..94bf364 100644
--- a/source/rendering/StarEnvironmentPainter.cpp
+++ b/source/rendering/StarEnvironmentPainter.cpp
@@ -3,6 +3,8 @@
#include "StarTime.hpp"
#include "StarXXHash.hpp"
#include "StarJsonExtra.hpp"
+#include "StarLogging.hpp"
+#include "StarMathCommon.hpp"
namespace Star {
@@ -80,12 +82,14 @@ void EnvironmentPainter::renderStars(float pixelRatio, Vec2F const& screenSize,
RectF viewRect = RectF::withSize(Vec2F(), viewSize).padded(screenBuffer);
+ auto& primitives = m_renderer->immediatePrimitives();
+
for (auto& star : stars) {
Vec2F screenPos = transform.transformVec2(star.first);
if (viewRect.contains(screenPos)) {
size_t starFrame = (size_t)(sky.epochTime + star.second.second) % sky.starFrames;
auto const& texture = m_starTextures[star.second.first * sky.starFrames + starFrame];
- m_renderer->render(renderTexturedRect(texture, screenPos * pixelRatio - Vec2F(texture->size()) / 2, 1.0, color, 0.0f));
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(), texture, screenPos * pixelRatio - Vec2F(texture->size()) / 2, 1.0, color, 0.0f);
}
}
@@ -99,7 +103,6 @@ void EnvironmentPainter::renderDebrisFields(float pixelRatio, Vec2F const& scree
if (sky.type == SkyType::Orbital || sky.type == SkyType::Warp) {
Vec2F viewSize = screenSize / pixelRatio;
Vec2F viewCenter = viewSize / 2;
- Vec2F viewMin = sky.starOffset - viewCenter;
Mat3F rotMatrix = Mat3F::rotation(sky.starRotation, viewCenter);
@@ -114,23 +117,29 @@ void EnvironmentPainter::renderDebrisFields(float pixelRatio, Vec2F const& scree
// Translate the entire field to make the debris seem as though they are moving
Vec2F velocityOffset = -Vec2F(debrisXVel, debrisYVel) * sky.epochTime;
- float screenBuffer = debrisField.queryFloat("screenBuffer");
- PolyF field = PolyF(RectF::withSize(viewMin, viewSize).padded(screenBuffer).translated(velocityOffset));
+ JsonArray imageOptions = debrisField.query("list").toArray();
+ Vec2U biggest = Vec2U();
+ for (Json const& json : imageOptions) {
+ TexturePtr texture = m_textureGroup->loadTexture(*json.stringPtr());
+ biggest = biggest.piecewiseMax(texture->size());
+ }
+
+ float screenBuffer = ceil((float)biggest.max() * (float)Constants::sqrt2) * 2.0f;
+ PolyF field = PolyF(RectF::withSize(sky.starOffset, viewSize).padded(screenBuffer).translated(velocityOffset));
Vec2F debrisAngularVelocityRange = jsonToVec2F(debrisField.query("angularVelocityRange"));
- JsonArray imageOptions = debrisField.query("list").toArray();
auto debrisItems = m_debrisGenerators[i]->generate(field,
[&](RandomSource& rand) {
- String debrisImage = rand.randFrom(imageOptions).toString();
+ StringView debrisImage = *rand.randFrom(imageOptions).stringPtr();
float debrisAngularVelocity = rand.randf(debrisAngularVelocityRange[0], debrisAngularVelocityRange[1]);
- return pair<String, float>(debrisImage, debrisAngularVelocity);
+ return pair<StringView, float>(debrisImage, debrisAngularVelocity);
});
- Vec2F debrisPositionOffset = -(sky.starOffset + velocityOffset + viewCenter);
+ Vec2F debrisPositionOffset = -(sky.starOffset + velocityOffset);
- for (auto debrisItem : debrisItems) {
+ for (auto& debrisItem : debrisItems) {
Vec2F debrisPosition = rotMatrix.transformVec2(debrisItem.first + debrisPositionOffset);
float debrisAngle = fmod(Constants::deg2rad * debrisItem.second.second * sky.epochTime, Constants::pi * 2) + sky.starRotation;
drawOrbiter(pixelRatio, screenSize, sky, {SkyOrbiterType::SpaceDebris, 1.0f, debrisAngle, debrisItem.second.first, debrisPosition});
@@ -166,6 +175,8 @@ void EnvironmentPainter::renderPlanetHorizon(float pixelRatio, Vec2F const& scre
float planetPixelRatio = pixelRatio * planetHorizon.scale;
Vec2F center = planetHorizon.center * pixelRatio;
+ auto& primitives = m_renderer->immediatePrimitives();
+
for (auto const& layer : planetHorizon.layers) {
TexturePtr leftTexture = m_textureGroup->loadTexture(layer.first);
Vec2F leftTextureSize(leftTexture->size());
@@ -182,17 +193,17 @@ void EnvironmentPainter::renderPlanetHorizon(float pixelRatio, Vec2F const& scre
PolyF rightImage = PolyF(rightRect);
rightImage.rotate(planetHorizon.rotation, center);
- m_renderer->render(RenderQuad{move(leftTexture),
- {leftImage[0], Vec2F(0, 0), {255, 255, 255, 255}, 0.0f},
- {leftImage[1], Vec2F(leftTextureSize[0], 0), {255, 255, 255, 255}, 0.0f},
- {leftImage[2], Vec2F(leftTextureSize[0], leftTextureSize[1]), {255, 255, 255, 255}, 0.0f},
- {leftImage[3], Vec2F(0, leftTextureSize[1]), {255, 255, 255, 255}, 0.0f}});
-
- m_renderer->render(RenderQuad{move(rightTexture),
- {rightImage[0], Vec2F(0, 0), {255, 255, 255, 255}, 0.0f},
- {rightImage[1], Vec2F(rightTextureSize[0], 0), {255, 255, 255, 255}, 0.0f},
- {rightImage[2], Vec2F(rightTextureSize[0], rightTextureSize[1]), {255, 255, 255, 255}, 0.0f},
- {rightImage[3], Vec2F(0, rightTextureSize[1]), {255, 255, 255, 255}, 0.0f}});
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(), move(leftTexture),
+ leftImage[0], Vec2F(0, 0),
+ leftImage[1], Vec2F(leftTextureSize[0], 0),
+ leftImage[2], Vec2F(leftTextureSize[0], leftTextureSize[1]),
+ leftImage[3], Vec2F(0, leftTextureSize[1]), Vec4B::filled(255), 0.0f);
+
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(), move(rightTexture),
+ rightImage[0], Vec2F(0, 0),
+ rightImage[1], Vec2F(rightTextureSize[0], 0),
+ rightImage[2], Vec2F(rightTextureSize[0], rightTextureSize[1]),
+ rightImage[3], Vec2F(0, rightTextureSize[1]), Vec4B::filled(255), 0.0f);
}
m_renderer->flush();
@@ -206,15 +217,16 @@ void EnvironmentPainter::renderFrontOrbiters(float pixelRatio, Vec2F const& scre
}
void EnvironmentPainter::renderSky(Vec2F const& screenSize, SkyRenderData const& sky) {
- m_renderer->render(RenderQuad{{},
- {Vec2F(0, 0), Vec2F(), sky.bottomRectColor.toRgba(), 0.0f},
- {Vec2F(screenSize[0], 0), Vec2F(), sky.bottomRectColor.toRgba(), 0.0f},
- {screenSize, Vec2F(), sky.topRectColor.toRgba(), 0.0f},
- {Vec2F(0, screenSize[1]), Vec2F(), sky.topRectColor.toRgba(), 0.0f}});
+ auto& primitives = m_renderer->immediatePrimitives();
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(), TexturePtr(),
+ RenderVertex{Vec2F(0, 0), Vec2F(), sky.bottomRectColor.toRgba(), 0.0f},
+ RenderVertex{Vec2F(screenSize[0], 0), Vec2F(), sky.bottomRectColor.toRgba(), 0.0f},
+ RenderVertex{screenSize, Vec2F(), sky.topRectColor.toRgba(), 0.0f},
+ RenderVertex{Vec2F(0, screenSize[1]), Vec2F(), sky.topRectColor.toRgba(), 0.0f});
// Flash overlay for Interstellar travel
Vec4B flashColor = sky.flashColor.toRgba();
- m_renderer->render(renderFlatRect(RectF(Vec2F(), screenSize), flashColor, 0.0f));
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(), RectF(Vec2F(), screenSize), flashColor, 0.0f);
m_renderer->flush();
}
@@ -224,6 +236,8 @@ void EnvironmentPainter::renderParallaxLayers(
// Note: the "parallax space" referenced below is a grid where the scale of each cell is the size of the parallax image
+ auto& primitives = m_renderer->immediatePrimitives();
+
for (auto& layer : layers) {
if (layer.alpha == 0)
continue;
@@ -307,11 +321,11 @@ void EnvironmentPainter::renderParallaxLayers(
withDirectives.directives += layer.directives;
if (auto texture = m_textureGroup->tryTexture(withDirectives)) {
RectF drawRect = RectF::withSize(anchorPoint, subImage.size() * camera.pixelRatio());
- m_renderer->render(RenderQuad{move(texture),
- {{drawRect.xMin(), drawRect.yMin()}, {subImage.xMin(), subImage.yMin()}, drawColor, lightMapMultiplier},
- {{drawRect.xMax(), drawRect.yMin()}, {subImage.xMax(), subImage.yMin()}, drawColor, lightMapMultiplier},
- {{drawRect.xMax(), drawRect.yMax()}, {subImage.xMax(), subImage.yMax()}, drawColor, lightMapMultiplier},
- {{drawRect.xMin(), drawRect.yMax()}, {subImage.xMin(), subImage.yMax()}, drawColor, lightMapMultiplier}});
+ primitives.emplace_back(std::in_place_type_t<RenderQuad>(), move(texture),
+ RenderVertex{drawRect.min(), subImage.min(), drawColor, lightMapMultiplier},
+ RenderVertex{{drawRect.xMax(), drawRect.yMin()}, {subImage.xMax(), subImage.yMin()}, drawColor, lightMapMultiplier},
+ RenderVertex{drawRect.max(), subImage.max(), drawColor, lightMapMultiplier},
+ RenderVertex{{drawRect.xMin(), drawRect.yMax()}, {subImage.xMin(), subImage.yMax()}, drawColor, lightMapMultiplier});
}
}
}
@@ -365,26 +379,27 @@ void EnvironmentPainter::drawRay(float pixelRatio,
// Sum is used to vary the ray intensity based on sky color
// Rays show up more on darker backgrounds, so this scales to remove that
float sum = std::pow((color[0] + color[1]) * RayColorDependenceScale, RayColorDependenceLevel);
- m_renderer->render(RenderQuad{{},
- {start + Vec2F(std::cos(angle + width), std::sin(angle + width)) * length, {}, Vec4B(RayColor, 0), 0.0f},
- {start + Vec2F(std::cos(angle + width), std::sin(angle + width)) * SunRadius * pixelRatio,
+ m_renderer->immediatePrimitives().emplace_back(std::in_place_type_t<RenderQuad>(), TexturePtr(),
+ RenderVertex{start + Vec2F(std::cos(angle + width), std::sin(angle + width)) * length, {}, Vec4B(RayColor, 0), 0.0f},
+ RenderVertex{start + Vec2F(std::cos(angle + width), std::sin(angle + width)) * SunRadius * pixelRatio,
{},
Vec4B(RayColor,
(int)(RayMinUnscaledAlpha + std::abs(m_rayPerlin.get(angle * 896 + time * 30) * RayUnscaledAlphaVariance))
* sum
* alpha), 0.0f},
- {start + Vec2F(std::cos(angle), std::sin(angle)) * SunRadius * pixelRatio,
+ RenderVertex{start + Vec2F(std::cos(angle), std::sin(angle)) * SunRadius * pixelRatio,
{},
Vec4B(RayColor,
(int)(RayMinUnscaledAlpha + std::abs(m_rayPerlin.get(angle * 626 + time * 30) * RayUnscaledAlphaVariance))
* sum
* alpha), 0.0f},
- {start + Vec2F(std::cos(angle), std::sin(angle)) * length, {}, Vec4B(RayColor, 0), 0.0f}});
+ RenderVertex{start + Vec2F(std::cos(angle), std::sin(angle)) * length, {}, Vec4B(RayColor, 0), 0.0f});
}
void EnvironmentPainter::drawOrbiter(float pixelRatio, Vec2F const& screenSize, SkyRenderData const& sky, SkyOrbiter const& orbiter) {
float alpha = 1.0f;
- Vec2F position = orbiter.position * pixelRatio;
+ Vec2F screenCenter = screenSize / 2;
+ Vec2F position = screenCenter + (orbiter.position - screenCenter) * pixelRatio;
if (orbiter.type == SkyOrbiterType::Sun) {
alpha = sky.dayLevel;
@@ -398,11 +413,11 @@ void EnvironmentPainter::drawOrbiter(float pixelRatio, Vec2F const& screenSize,
RectF renderRect = RectF::withCenter(position, texSize * orbiter.scale * pixelRatio);
Vec4B renderColor = Vec4B(255, 255, 255, 255 * alpha);
- m_renderer->render(RenderQuad{move(texture),
- {renderMatrix.transformVec2(renderRect.min()), Vec2F(0, 0), renderColor, 0.0f},
- {renderMatrix.transformVec2(Vec2F{renderRect.xMax(), renderRect.yMin()}), Vec2F(texSize[0], 0), renderColor, 0.0f},
- {renderMatrix.transformVec2(renderRect.max()), Vec2F(texSize[0], texSize[1]), renderColor, 0.0f},
- {renderMatrix.transformVec2(Vec2F{renderRect.xMin(), renderRect.yMax()}), Vec2F(0, texSize[1]), renderColor, 0.0f}});
+ m_renderer->immediatePrimitives().emplace_back(std::in_place_type_t<RenderQuad>(), move(texture),
+ RenderVertex{renderMatrix.transformVec2(renderRect.min()), Vec2F(0, 0), renderColor, 0.0f},
+ RenderVertex{renderMatrix.transformVec2(Vec2F{renderRect.xMax(), renderRect.yMin()}), Vec2F(texSize[0], 0), renderColor, 0.0f},
+ RenderVertex{renderMatrix.transformVec2(renderRect.max()), Vec2F(texSize[0], texSize[1]), renderColor, 0.0f},
+ RenderVertex{renderMatrix.transformVec2(Vec2F{renderRect.xMin(), renderRect.yMax()}), Vec2F(0, texSize[1]), renderColor, 0.0f});
}
uint64_t EnvironmentPainter::starsHash(SkyRenderData const& sky, Vec2F const& viewSize) const {
diff --git a/source/rendering/StarTextPainter.cpp b/source/rendering/StarTextPainter.cpp
index 631000e..ca69fb1 100644
--- a/source/rendering/StarTextPainter.cpp
+++ b/source/rendering/StarTextPainter.cpp
@@ -539,6 +539,7 @@ RectF TextPainter::doRenderLine(StringView text, TextPositioning const& position
RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position, bool reallyRender) {
if (m_nonRenderedCharacters.find(String(c)) != NPos)
return RectF();
+ m_fontTextureGroup.switchFont(m_renderSettings.font);
int width = glyphWidth(c);
// Offset left by width if right anchored.
@@ -581,8 +582,8 @@ void TextPainter::renderGlyph(String::Char c, Vec2F const& screenPos, unsigned f
return;
const FontTextureGroup::GlyphTexture& glyphTexture = m_fontTextureGroup.glyphTexture(c, fontSize, processingDirectives);
- Vec2F offset = glyphTexture.processingOffset * (scale * 0.5f); //Kae: Re-center the glyph if the image scale was changed by the directives (it is positioned from the bottom left)
- m_renderer->render(renderTexturedRect(glyphTexture.texture, Vec2F(screenPos) + offset, scale, color, 0.0f));
+ Vec2F offset = glyphTexture.processingOffset * (scale * 0.5f);
+ m_renderer->immediatePrimitives().emplace_back(std::in_place_type_t<RenderQuad>(), glyphTexture.texture, screenPos + offset, scale, color, 0.0f);
}
}
diff --git a/source/rendering/StarTilePainter.cpp b/source/rendering/StarTilePainter.cpp
index fc115e5..2faf9d5 100644
--- a/source/rendering/StarTilePainter.cpp
+++ b/source/rendering/StarTilePainter.cpp
@@ -55,9 +55,6 @@ void TilePainter::adjustLighting(WorldRenderData& renderData) const {
}
void TilePainter::setup(WorldCamera const& camera, WorldRenderData& renderData) {
- m_pendingTerrainChunks.clear();
- m_pendingLiquidChunks.clear();
-
auto cameraCenter = camera.centerWorldPosition();
if (m_lastCameraCenter)
m_cameraPan = renderData.geometry.diff(cameraCenter, *m_lastCameraCenter);
@@ -66,10 +63,16 @@ void TilePainter::setup(WorldCamera const& camera, WorldRenderData& renderData)
//Kae: Padded by one to fix culling issues with certain tile pieces at chunk borders, such as grass.
RectI chunkRange = RectI::integral(RectF(camera.worldTileRect().padded(1)).scaled(1.0f / RenderChunkSize));
+ size_t chunks = chunkRange.volume();
+ m_pendingTerrainChunks.resize(chunks);
+ m_pendingLiquidChunks.resize(chunks);
+
+ size_t i = 0;
for (int x = chunkRange.xMin(); x < chunkRange.xMax(); ++x) {
for (int y = chunkRange.yMin(); y < chunkRange.yMax(); ++y) {
- m_pendingTerrainChunks.append(getTerrainChunk(renderData, {x, y}));
- m_pendingLiquidChunks.append(getLiquidChunk(renderData, {x, y}));
+ size_t index = i++;
+ m_pendingTerrainChunks[index] = getTerrainChunk(renderData, {x, y});
+ m_pendingLiquidChunks [index] = getLiquidChunk(renderData, {x, y});
}
}
}
@@ -117,7 +120,7 @@ size_t TilePainter::TextureKeyHash::operator()(TextureKey const& key) const {
}
TilePainter::ChunkHash TilePainter::terrainChunkHash(WorldRenderData& renderData, Vec2I chunkIndex) {
- XXHash64 hasher;
+ XXHash3 hasher;
RectI tileRange = RectI::withSize(chunkIndex * RenderChunkSize, Vec2I::filled(RenderChunkSize)).padded(MaterialRenderProfileMaxNeighborDistance);
forEachRenderTile(renderData, tileRange, [&](Vec2I const&, RenderTile const& renderTile) {
@@ -128,7 +131,7 @@ TilePainter::ChunkHash TilePainter::terrainChunkHash(WorldRenderData& renderData
}
TilePainter::ChunkHash TilePainter::liquidChunkHash(WorldRenderData& renderData, Vec2I chunkIndex) {
- XXHash64 hasher;
+ XXHash3 hasher;
RectI tileRange = RectI::withSize(chunkIndex * RenderChunkSize, Vec2I::filled(RenderChunkSize)).padded(MaterialRenderProfileMaxNeighborDistance);
forEachRenderTile(renderData, tileRange, [&](Vec2I const&, RenderTile const& renderTile) {
@@ -334,13 +337,16 @@ bool TilePainter::produceTerrainPrimitives(HashMap<QuadZLevel, List<RenderPrimit
TexturePtr texture = getPieceTexture(material, piecePair.first, materialHue, false);
RectF textureCoords = piecePair.first->variants.get(materialColorVariant).wrap(variance);
RectF worldCoords = RectF::withSize(piecePair.second / TilePixels + Vec2F(pos), textureCoords.size() / TilePixels);
- quadList.append(RenderQuad{
- move(texture),
- RenderVertex{Vec2F(worldCoords.xMin(), worldCoords.yMin()), Vec2F(textureCoords.xMin(), textureCoords.yMin()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMax(), worldCoords.yMin()), Vec2F(textureCoords.xMax(), textureCoords.yMin()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMax(), worldCoords.yMax()), Vec2F(textureCoords.xMax(), textureCoords.yMax()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMin(), worldCoords.yMax()), Vec2F(textureCoords.xMin(), textureCoords.yMax()), color, 1.0f}
- });
+ quadList.emplace_back(std::in_place_type_t<RenderQuad>(), move(texture),
+ worldCoords .min(),
+ textureCoords.min(),
+ Vec2F( worldCoords.xMax(), worldCoords.yMin()),
+ Vec2F(textureCoords.xMax(), textureCoords.yMin()),
+ worldCoords .max(),
+ textureCoords.max(),
+ Vec2F( worldCoords.xMin(), worldCoords.yMax()),
+ Vec2F(textureCoords.xMin(), textureCoords.yMax()),
+ color, 1.0f);
}
}
@@ -354,15 +360,14 @@ bool TilePainter::produceTerrainPrimitives(HashMap<QuadZLevel, List<RenderPrimit
terrainLayer == TerrainLayer::Background ? TileLayer::Background : TileLayer::Foreground, true);
for (auto const& piecePair : pieces) {
auto texture = getPieceTexture(mod, piecePair.first, modHue, true);
- auto textureCoords = piecePair.first->variants.get(modColorVariant).wrap(variance);
+ auto& textureCoords = piecePair.first->variants.get(modColorVariant).wrap(variance);
RectF worldCoords = RectF::withSize(piecePair.second / TilePixels + Vec2F(pos), textureCoords.size() / TilePixels);
- quadList.append(RenderQuad{
- move(texture),
- RenderVertex{Vec2F(worldCoords.xMin(), worldCoords.yMin()), Vec2F(textureCoords.xMin(), textureCoords.yMin()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMax(), worldCoords.yMin()), Vec2F(textureCoords.xMax(), textureCoords.yMin()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMax(), worldCoords.yMax()), Vec2F(textureCoords.xMax(), textureCoords.yMax()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMin(), worldCoords.yMax()), Vec2F(textureCoords.xMin(), textureCoords.yMax()), color, 1.0f}
- });
+ quadList.emplace_back(std::in_place_type_t<RenderQuad>(), move(texture),
+ worldCoords.min(), textureCoords.min(),
+ Vec2F(worldCoords.xMax(), worldCoords.yMin()), Vec2F(textureCoords.xMax(), textureCoords.yMin()),
+ worldCoords.max(), textureCoords.max(),
+ Vec2F(worldCoords.xMin(), worldCoords.yMax()), Vec2F(textureCoords.xMin(), textureCoords.yMax()),
+ color, 1.0f);
}
}
@@ -377,13 +382,12 @@ bool TilePainter::produceTerrainPrimitives(HashMap<QuadZLevel, List<RenderPrimit
RectF textureCoords = RectF::withSize(Vec2F(), textureSize);
RectF worldCoords = RectF::withSize(crackingImage.second / TilePixels + Vec2F(pos), textureCoords.size() / TilePixels);
- quadList.append(RenderQuad{
- move(texture),
- RenderVertex{Vec2F(worldCoords.xMin(), worldCoords.yMin()), Vec2F(textureCoords.xMin(), textureCoords.yMin()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMax(), worldCoords.yMin()), Vec2F(textureCoords.xMax(), textureCoords.yMin()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMax(), worldCoords.yMax()), Vec2F(textureCoords.xMax(), textureCoords.yMax()), color, 1.0f},
- RenderVertex{Vec2F(worldCoords.xMin(), worldCoords.yMax()), Vec2F(textureCoords.xMin(), textureCoords.yMax()), color, 1.0f}
- });
+ quadList.emplace_back(std::in_place_type_t<RenderQuad>(), move(texture),
+ worldCoords.min(), textureCoords.min(),
+ Vec2F(worldCoords.xMax(), worldCoords.yMin()), Vec2F(textureCoords.xMax(), textureCoords.yMin()),
+ worldCoords.max(), textureCoords.max(),
+ Vec2F(worldCoords.xMin(), worldCoords.yMax()), Vec2F(textureCoords.xMin(), textureCoords.yMax()),
+ color, 1.0f);
}
return occlude;
@@ -408,13 +412,12 @@ void TilePainter::produceLiquidPrimitives(HashMap<LiquidId, List<RenderPrimitive
auto texRect = worldRect.scaled(TilePixels);
auto const& liquid = m_liquids[tile.liquidId];
- primitives[tile.liquidId].append(RenderQuad{
- liquid.texture,
- RenderVertex{Vec2F(worldRect.xMin(), worldRect.yMin()), Vec2F(texRect.xMin(), texRect.yMin()), liquid.color, 1.0f},
- RenderVertex{Vec2F(worldRect.xMax(), worldRect.yMin()), Vec2F(texRect.xMax(), texRect.yMin()), liquid.color, 1.0f},
- RenderVertex{Vec2F(worldRect.xMax(), worldRect.yMax()), Vec2F(texRect.xMax(), texRect.yMax()), liquid.color, 1.0f},
- RenderVertex{Vec2F(worldRect.xMin(), worldRect.yMax()), Vec2F(texRect.xMin(), texRect.yMax()), liquid.color, 1.0f}
- });
+ primitives[tile.liquidId].emplace_back(std::in_place_type_t<RenderQuad>(), move(liquid.texture),
+ worldRect.min(), texRect.min(),
+ Vec2F(worldRect.xMax(), worldRect.yMin()), Vec2F(texRect.xMax(), texRect.yMin()),
+ worldRect.max(), texRect.max(),
+ Vec2F(worldRect.xMin(), worldRect.yMax()), Vec2F(texRect.xMin(), texRect.yMax()),
+ liquid.color, 1.0f);
}
bool TilePainter::determineMatchingPieces(MaterialPieceResultList& resultList, bool* occlude, MaterialDatabaseConstPtr const& materialDb, MaterialRenderMatchList const& matchList,
diff --git a/source/rendering/StarWorldPainter.cpp b/source/rendering/StarWorldPainter.cpp
index 8e27006..07f61e0 100644
--- a/source/rendering/StarWorldPainter.cpp
+++ b/source/rendering/StarWorldPainter.cpp
@@ -173,7 +173,10 @@ void WorldPainter::renderParticles(WorldRenderData& renderData, Particle::Layer
Vec2F size = Vec2F::filled(particle.size * m_camera.pixelRatio());
if (particle.type == Particle::Type::Ember) {
- m_renderer->render(renderFlatRect(RectF(position - size / 2, position + size / 2), particle.color.toRgba(), particle.fullbright ? 0.0f : 1.0f));
+ m_renderer->immediatePrimitives().emplace_back(std::in_place_type_t<RenderQuad>(),
+ RectF(position - size / 2, position + size / 2),
+ particle.color.toRgba(),
+ particle.fullbright ? 0.0f : 1.0f);
} else if (particle.type == Particle::Type::Streak) {
// Draw a rotated quad streaking in the direction the particle is coming from.
@@ -183,12 +186,12 @@ void WorldPainter::renderParticles(WorldRenderData& renderData, Particle::Layer
float length = particle.length * m_camera.pixelRatio();
Vec4B color = particle.color.toRgba();
float lightMapMultiplier = particle.fullbright ? 0.0f : 1.0f;
- m_renderer->render(RenderQuad{{},
- {position - sideHalf, {}, color, lightMapMultiplier},
- {position + sideHalf, {}, color, lightMapMultiplier},
- {position - dir * length + sideHalf, {}, color, lightMapMultiplier},
- {position - dir * length - sideHalf, {}, color, lightMapMultiplier}
- });
+ m_renderer->immediatePrimitives().emplace_back(std::in_place_type_t<RenderQuad>(),
+ position - sideHalf,
+ position + sideHalf,
+ position - dir * length + sideHalf,
+ position - dir * length - sideHalf,
+ color, lightMapMultiplier);
} else if (particle.type == Particle::Type::Textured || particle.type == Particle::Type::Animated) {
Drawable drawable;