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/rendering | |
parent | 47a527ebbff91cf530cb8758828679ef0e3334f2 (diff) |
RenderPrimitive micro-optimizations
Diffstat (limited to 'source/rendering')
-rw-r--r-- | source/rendering/StarDrawablePainter.cpp | 35 | ||||
-rw-r--r-- | source/rendering/StarEnvironmentPainter.cpp | 99 | ||||
-rw-r--r-- | source/rendering/StarTextPainter.cpp | 5 | ||||
-rw-r--r-- | source/rendering/StarTilePainter.cpp | 75 | ||||
-rw-r--r-- | source/rendering/StarWorldPainter.cpp | 17 |
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; |