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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-07-06 23:59:18 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-07-06 23:59:18 +1000
commitfe99ec69664c5ca5a400d80e060084ff78d9bb22 (patch)
tree6fbe0123c9a6cb5105e34ad2a0c26a1791fc363e
parentfe4cc1961888db364bbc70cfe0e7a15ec27a5c5b (diff)
Render the world in its own framebuffer
-rw-r--r--assets/opensb/rendering/default.config9
-rw-r--r--assets/opensb/rendering/effects/interface.config11
-rw-r--r--assets/opensb/rendering/effects/interface.frag (renamed from assets/opensb/rendering/default.frag)0
-rw-r--r--assets/opensb/rendering/effects/interface.vert (renamed from assets/opensb/rendering/default.vert)0
-rw-r--r--assets/opensb/rendering/effects/world.config (renamed from assets/opensb/rendering/world.config)2
-rw-r--r--assets/opensb/rendering/effects/world.frag (renamed from assets/opensb/rendering/world.frag)0
-rw-r--r--assets/opensb/rendering/effects/world.vert (renamed from assets/opensb/rendering/world.vert)0
-rw-r--r--assets/opensb/rendering/opengl20.config.patch5
-rw-r--r--source/application/StarRenderer.hpp2
-rw-r--r--source/application/StarRenderer_opengl20.cpp155
-rw-r--r--source/application/StarRenderer_opengl20.hpp27
-rw-r--r--source/client/StarClientApplication.cpp26
-rw-r--r--source/core/StarJsonBuilder.cpp7
-rw-r--r--source/rendering/StarTilePainter.cpp25
-rw-r--r--source/rendering/StarWorldPainter.cpp2
15 files changed, 203 insertions, 68 deletions
diff --git a/assets/opensb/rendering/default.config b/assets/opensb/rendering/default.config
deleted file mode 100644
index 5e51afc..0000000
--- a/assets/opensb/rendering/default.config
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "effectParameters" : {},
- "effectTextures" : {},
-
- "effectShaders" : {
- "vertex" : "default.vert",
- "fragment" : "default.frag"
- }
-} \ No newline at end of file
diff --git a/assets/opensb/rendering/effects/interface.config b/assets/opensb/rendering/effects/interface.config
new file mode 100644
index 0000000..b4860d6
--- /dev/null
+++ b/assets/opensb/rendering/effects/interface.config
@@ -0,0 +1,11 @@
+{
+ "blitFrameBuffer" : "world",
+
+ "effectParameters" : {},
+ "effectTextures" : {},
+
+ "effectShaders" : {
+ "vertex" : "interface.vert",
+ "fragment" : "interface.frag"
+ }
+} \ No newline at end of file
diff --git a/assets/opensb/rendering/default.frag b/assets/opensb/rendering/effects/interface.frag
index 0ba2d60..0ba2d60 100644
--- a/assets/opensb/rendering/default.frag
+++ b/assets/opensb/rendering/effects/interface.frag
diff --git a/assets/opensb/rendering/default.vert b/assets/opensb/rendering/effects/interface.vert
index 612a788..612a788 100644
--- a/assets/opensb/rendering/default.vert
+++ b/assets/opensb/rendering/effects/interface.vert
diff --git a/assets/opensb/rendering/world.config b/assets/opensb/rendering/effects/world.config
index 3ad0d88..188b727 100644
--- a/assets/opensb/rendering/world.config
+++ b/assets/opensb/rendering/effects/world.config
@@ -1,4 +1,6 @@
{
+ "frameBuffer" : "world",
+
"effectParameters" : {
"lightMapEnabled" : {
"type" : "bool",
diff --git a/assets/opensb/rendering/world.frag b/assets/opensb/rendering/effects/world.frag
index b4450ad..b4450ad 100644
--- a/assets/opensb/rendering/world.frag
+++ b/assets/opensb/rendering/effects/world.frag
diff --git a/assets/opensb/rendering/world.vert b/assets/opensb/rendering/effects/world.vert
index 67998bc..67998bc 100644
--- a/assets/opensb/rendering/world.vert
+++ b/assets/opensb/rendering/effects/world.vert
diff --git a/assets/opensb/rendering/opengl20.config.patch b/assets/opensb/rendering/opengl20.config.patch
new file mode 100644
index 0000000..3d85c1a
--- /dev/null
+++ b/assets/opensb/rendering/opengl20.config.patch
@@ -0,0 +1,5 @@
+{
+ "frameBuffers" : {
+ "world" : {}
+ }
+} \ No newline at end of file
diff --git a/source/application/StarRenderer.hpp b/source/application/StarRenderer.hpp
index 58c1c27..ad44c5c 100644
--- a/source/application/StarRenderer.hpp
+++ b/source/application/StarRenderer.hpp
@@ -130,6 +130,8 @@ public:
virtual String rendererId() const = 0;
virtual Vec2U screenSize() const = 0;
+ virtual void loadConfig(Json const& config) = 0;
+
// The actual shaders used by this renderer will be in a default no effects
// state when constructed, but can be overridden here. This config will be
// specific to each type of renderer, so it will be necessary to key the
diff --git a/source/application/StarRenderer_opengl20.cpp b/source/application/StarRenderer_opengl20.cpp
index b54361e..f85f0e8 100644
--- a/source/application/StarRenderer_opengl20.cpp
+++ b/source/application/StarRenderer_opengl20.cpp
@@ -105,6 +105,7 @@ OpenGl20Renderer::~OpenGl20Renderer() {
for (auto& effect : m_effects)
glDeleteProgram(effect.second.program);
+ m_frameBuffers.clear();
logGlErrorSummary("OpenGL errors during shutdown");
}
@@ -116,6 +117,38 @@ Vec2U OpenGl20Renderer::screenSize() const {
return m_screenSize;
}
+OpenGl20Renderer::GlFrameBuffer::GlFrameBuffer(Json const& fbConfig) : config(fbConfig) {
+ texture = createGlTexture(Image(), TextureAddressing::Clamp, TextureFiltering::Nearest);
+ glBindTexture(GL_TEXTURE_2D, texture->glTextureId());
+
+ Vec2U size = jsonToVec2U(config.getArray("size", { 256, 256 }));
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size[0] , size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+
+ glGenFramebuffers(1, &id);
+ if (!id)
+ throw RendererException("Failed to create OpenGL framebuffer");
+
+ glBindFramebuffer(GL_FRAMEBUFFER, id);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->glTextureId(), 0);
+
+ auto framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE)
+ throw RendererException("OpenGL framebuffer is not complete!");
+}
+
+
+OpenGl20Renderer::GlFrameBuffer::~GlFrameBuffer() {
+ glDeleteFramebuffers(1, &id);
+ texture.reset();
+}
+
+void OpenGl20Renderer::loadConfig(Json const& config) {
+ m_frameBuffers.clear();
+
+ for (auto& pair : config.getObject("frameBuffers", {}))
+ m_frameBuffers[pair.first] = make_ref<GlFrameBuffer>(pair.second);
+}
+
void OpenGl20Renderer::loadEffectConfig(String const& name, Json const& effectConfig, StringMap<String> const& shaders) {
if (m_effects.contains(name)) {
Logger::warn("OpenGL effect {} already exists", name);
@@ -303,6 +336,18 @@ bool OpenGl20Renderer::switchEffectConfig(String const& name) {
return false;
Effect& effect = find->second;
+ if (m_currentEffect == &effect)
+ return true;
+
+ if (auto blitFrameBufferId = effect.config.optString("blitFrameBuffer"))
+ blitGlFrameBuffer(getGlFrameBuffer(*blitFrameBufferId));
+
+ if (auto frameBufferId = effect.config.optString("frameBuffer"))
+ switchGlFrameBuffer(getGlFrameBuffer(*frameBufferId));
+ else {
+ m_currentFrameBuffer.reset();
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ }
glUseProgram(m_program = effect.program);
setupGlUniforms(effect);
@@ -387,11 +432,24 @@ void OpenGl20Renderer::setScreenSize(Vec2U screenSize) {
m_screenSize = screenSize;
glViewport(0, 0, m_screenSize[0], m_screenSize[1]);
glUniform2f(m_screenSizeUniform, m_screenSize[0], m_screenSize[1]);
+
+ for (auto& frameBuffer : m_frameBuffers) {
+ glBindTexture(GL_TEXTURE_2D, frameBuffer.second->texture->glTextureId());
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_screenSize[0], m_screenSize[1], 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ }
}
void OpenGl20Renderer::startFrame() {
if (m_scissorRect)
glDisable(GL_SCISSOR_TEST);
+
+ for (auto& frameBuffer : m_frameBuffers) {
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.second->id);
+ glClear(GL_COLOR_BUFFER_BIT);
+ frameBuffer.second->blitted = false;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -417,6 +475,9 @@ void OpenGl20Renderer::finishFrame() {
return false;
});
+ // Blit if another shader hasn't
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
if (DebugEnabled)
logGlErrorSummary("OpenGL errors this frame");
}
@@ -456,17 +517,20 @@ void OpenGl20Renderer::GlTextureAtlasSet::copyAtlasPixels(
glBindTexture(GL_TEXTURE_2D, glTexture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- if (image.pixelFormat() == PixelFormat::RGB24) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, bottomLeft[0], bottomLeft[1], image.width(), image.height(), GL_RGB, GL_UNSIGNED_BYTE, image.data());
- } else if (image.pixelFormat() == PixelFormat::RGBA32) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, bottomLeft[0], bottomLeft[1], image.width(), image.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.data());
- } else if (image.pixelFormat() == PixelFormat::BGR24) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, bottomLeft[0], bottomLeft[1], image.width(), image.height(), GL_BGR, GL_UNSIGNED_BYTE, image.data());
- } else if (image.pixelFormat() == PixelFormat::BGRA32) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, bottomLeft[0], bottomLeft[1], image.width(), image.height(), GL_BGRA, GL_UNSIGNED_BYTE, image.data());
- } else {
+ GLenum format;
+ auto pixelFormat = image.pixelFormat();
+ if (pixelFormat == PixelFormat::RGB24)
+ format = GL_RGB;
+ else if (pixelFormat == PixelFormat::RGBA32)
+ format = GL_RGBA;
+ else if (pixelFormat == PixelFormat::BGR24)
+ format = GL_BGR;
+ else if (pixelFormat == PixelFormat::BGRA32)
+ format = GL_BGRA;
+ else
throw RendererException("Unsupported texture format in OpenGL20Renderer::TextureGroup::copyAtlasPixels");
- }
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, bottomLeft[0], bottomLeft[1], image.width(), image.height(), format, GL_UNSIGNED_BYTE, image.data());
}
OpenGl20Renderer::GlTextureGroup::GlTextureGroup(unsigned atlasNumCells)
@@ -608,7 +672,7 @@ void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive>& primitives) {
glBufferData(GL_ARRAY_BUFFER, accumulationBuffer.size(), accumulationBuffer.ptr(), GL_STREAM_DRAW);
}
- vertexBuffers.append(vb);
+ vertexBuffers.emplace_back(move(vb));
currentTextures.clear();
currentTextureSizes.clear();
@@ -654,9 +718,10 @@ void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive>& primitives) {
++currentVertexCount;
};
+ float textureIndex = 0.0f;
+ Vec2F textureOffset = {};
+ Texture* lastTexture = nullptr;
for (auto& primitive : primitives) {
- float textureIndex;
- Vec2F textureOffset;
if (auto tri = primitive.ptr<RenderTriangle>()) {
tie(textureIndex, textureOffset) = addCurrentTexture(move(tri->texture));
@@ -678,6 +743,7 @@ void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive>& primitives) {
} else if (auto poly = primitive.ptr<RenderPoly>()) {
if (poly->vertexes.size() > 2) {
tie(textureIndex, textureOffset) = addCurrentTexture(move(poly->texture));
+
for (size_t i = 1; i < poly->vertexes.size() - 1; ++i) {
appendBufferVertex(poly->vertexes[0], textureIndex, textureOffset);
appendBufferVertex(poly->vertexes[i], textureIndex, textureOffset);
@@ -723,17 +789,20 @@ bool OpenGl20Renderer::logGlErrorSummary(String prefix) {
void OpenGl20Renderer::uploadTextureImage(PixelFormat pixelFormat, Vec2U size, uint8_t const* data) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- if (pixelFormat == PixelFormat::RGB24) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size[0], size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, data);
- } else if (pixelFormat == PixelFormat::RGBA32) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size[0], size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- } else if (pixelFormat == PixelFormat::BGR24) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_BGR, size[0], size[1], 0, GL_BGR, GL_UNSIGNED_BYTE, data);
- } else if (pixelFormat == PixelFormat::BGRA32) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, size[0], size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- } else {
- starAssert(false);
- }
+
+ GLenum format;
+ if (pixelFormat == PixelFormat::RGB24)
+ format = GL_RGB;
+ else if (pixelFormat == PixelFormat::RGBA32)
+ format = GL_RGBA;
+ else if (pixelFormat == PixelFormat::BGR24)
+ format = GL_BGR;
+ else if (pixelFormat == PixelFormat::BGRA32)
+ format = GL_BGRA;
+ else
+ throw RendererException("Unsupported texture format in OpenGL20Renderer::uploadTextureImage");
+
+ glTexImage2D(GL_TEXTURE_2D, 0, format, size[0], size[1], 0, format, GL_UNSIGNED_BYTE, data);
}
void OpenGl20Renderer::flushImmediatePrimitives() {
@@ -752,9 +821,6 @@ auto OpenGl20Renderer::createGlTexture(Image const& image, TextureAddressing add
glLoneTexture->textureAddressing = addressing;
glLoneTexture->textureSize = image.size();
- if (image.empty())
- return glLoneTexture;
-
glGenTextures(1, &glLoneTexture->textureId);
if (glLoneTexture->textureId == 0)
throw RendererException("Could not generate texture in OpenGL20Renderer::createGlTexture");
@@ -777,7 +843,9 @@ auto OpenGl20Renderer::createGlTexture(Image const& image, TextureAddressing add
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
- uploadTextureImage(image.pixelFormat(), image.size(), image.data());
+
+ if (!image.empty())
+ uploadTextureImage(image.pixelFormat(), image.size(), image.data());
return glLoneTexture;
}
@@ -852,6 +920,37 @@ void OpenGl20Renderer::setupGlUniforms(Effect& effect) {
glUniform2f(m_screenSizeUniform, m_screenSize[0], m_screenSize[1]);
}
+RefPtr<OpenGl20Renderer::GlFrameBuffer> OpenGl20Renderer::getGlFrameBuffer(String const& id) {
+ if (auto ptr = m_frameBuffers.ptr(id))
+ return *ptr;
+ else
+ throw RendererException::format("Frame buffer '{}' does not exist", id);
+}
+
+void OpenGl20Renderer::blitGlFrameBuffer(RefPtr<GlFrameBuffer> const& frameBuffer) {
+ if (frameBuffer->blitted)
+ return;
+
+ auto& size = m_screenSize;
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer->id);
+ glBlitFramebuffer(
+ 0, 0, size[0], size[1],
+ 0, 0, size[0], size[1],
+ GL_COLOR_BUFFER_BIT, GL_NEAREST
+ );
+
+ frameBuffer->blitted = true;
+}
+
+void OpenGl20Renderer::switchGlFrameBuffer(RefPtr<GlFrameBuffer> const& frameBuffer) {
+ if (m_currentFrameBuffer == frameBuffer)
+ return;
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->id);
+ m_currentFrameBuffer = frameBuffer;
+}
+
GLuint OpenGl20Renderer::Effect::getAttribute(String const& name) {
auto find = attributes.find(name);
if (find == attributes.end()) {
diff --git a/source/application/StarRenderer_opengl20.hpp b/source/application/StarRenderer_opengl20.hpp
index 598f803..4d917d5 100644
--- a/source/application/StarRenderer_opengl20.hpp
+++ b/source/application/StarRenderer_opengl20.hpp
@@ -10,6 +10,8 @@ namespace Star {
STAR_CLASS(OpenGl20Renderer);
+constexpr size_t FrameBufferCount = 1;
+
// OpenGL 2.0 implementation of Renderer. OpenGL context must be created and
// active during construction, destruction, and all method calls.
class OpenGl20Renderer : public Renderer {
@@ -20,6 +22,7 @@ public:
String rendererId() const override;
Vec2U screenSize() const override;
+ void loadConfig(Json const& config) override;
void loadEffectConfig(String const& name, Json const& effectConfig, StringMap<String> const& shaders) override;
void setEffectParameter(String const& parameterName, RenderEffectParameter const& parameter) override;
@@ -145,22 +148,33 @@ private:
struct EffectParameter {
GLint parameterUniform = -1;
- VariantTypeIndex parameterType;
+ VariantTypeIndex parameterType = 0;
Maybe<RenderEffectParameter> parameterValue;
};
struct EffectTexture {
GLint textureUniform = -1;
- unsigned textureUnit;
+ unsigned textureUnit = 0;
TextureAddressing textureAddressing = TextureAddressing::Clamp;
TextureFiltering textureFiltering = TextureFiltering::Linear;
GLint textureSizeUniform = -1;
RefPtr<GlLoneTexture> textureValue;
};
+
+ struct GlFrameBuffer : RefCounter {
+ GLuint id = 0;
+ RefPtr<GlLoneTexture> texture;
+
+ Json config;
+ bool blitted = false;
+
+ GlFrameBuffer(Json const& config);
+ ~GlFrameBuffer();
+ };
class Effect {
public:
- GLuint program;
+ GLuint program = 0;
Json config;
StringMap<EffectParameter> parameters;
StringMap<EffectTexture> textures;
@@ -185,6 +199,10 @@ private:
void setupGlUniforms(Effect& effect);
+ RefPtr<OpenGl20Renderer::GlFrameBuffer> getGlFrameBuffer(String const& id);
+ void blitGlFrameBuffer(RefPtr<OpenGl20Renderer::GlFrameBuffer> const& frameBuffer);
+ void switchGlFrameBuffer(RefPtr<OpenGl20Renderer::GlFrameBuffer> const& frameBuffer);
+
Vec2U m_screenSize;
GLuint m_program = 0;
@@ -203,6 +221,9 @@ private:
StringMap<Effect> m_effects;
Effect* m_currentEffect;
+ StringMap<RefPtr<GlFrameBuffer>> m_frameBuffers;
+ RefPtr<GlFrameBuffer> m_currentFrameBuffer;
+
RefPtr<GlTexture> m_whiteTexture;
Maybe<RectI> m_scissorRect;
diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp
index 2ed90ab..356421b 100644
--- a/source/client/StarClientApplication.cpp
+++ b/source/client/StarClientApplication.cpp
@@ -211,7 +211,7 @@ void ClientApplication::renderInit(RendererPtr renderer) {
auto assets = m_root->assets();
auto loadEffectConfig = [&](String const& name) {
- String path = strf("/rendering/{}.config", name);
+ String path = strf("/rendering/effects/{}.config", name);
if (assets->assetExists(path)) {
StringMap<String> shaders;
auto config = assets->json(path);
@@ -233,6 +233,8 @@ void ClientApplication::renderInit(RendererPtr renderer) {
Logger::warn("No rendering config found for renderer with id '{}'", renderer->rendererId());
};
+ renderer->loadConfig(assets->json("/rendering/opengl20.config"));
+
loadEffectConfig("world");
loadEffectConfig("interface");
@@ -372,6 +374,9 @@ void ClientApplication::update() {
void ClientApplication::render() {
auto config = m_root->configuration();
auto assets = m_root->assets();
+ auto& renderer = Application::renderer();
+
+ renderer->switchEffectConfig("interface");
if (m_guiContext->windowWidth() >= m_crossoverRes[0] && m_guiContext->windowHeight() >= m_crossoverRes[1])
m_guiContext->setInterfaceScale(m_maxInterfaceScale);
@@ -387,28 +392,21 @@ void ClientApplication::render() {
} else if (m_state > MainAppState::Title) {
WorldClientPtr worldClient = m_universeClient->worldClient();
-
- RendererPtr renderer = Application::renderer();
- renderer->switchEffectConfig("world");
if (worldClient) {
auto totalStart = Time::monotonicMicroseconds();
- auto start = totalStart;
-
+ renderer->switchEffectConfig("world");
+ auto clientStart = totalStart;
worldClient->render(m_renderData, TilePainter::BorderTileSize);
- LogMap::set("client_render_world_client", strf(u8"{:05d}\u00b5s", Time::monotonicMicroseconds() - start));
+ LogMap::set("client_render_world_client", strf(u8"{:05d}\u00b5s", Time::monotonicMicroseconds() - clientStart));
- start = Time::monotonicMicroseconds();
+ auto paintStart = Time::monotonicMicroseconds();
m_worldPainter->render(m_renderData, [&]() { worldClient->waitForLighting(); });
- LogMap::set("client_render_world_painter", strf(u8"{:05d}\u00b5s", Time::monotonicMicroseconds() - start));
-
- start = Time::monotonicMicroseconds();
- m_mainInterface->renderInWorldElements();
- LogMap::set("client_render_world_elements", strf(u8"{:05d}\u00b5s", Time::monotonicMicroseconds() - start));
-
+ LogMap::set("client_render_world_painter", strf(u8"{:05d}\u00b5s", Time::monotonicMicroseconds() - paintStart));
LogMap::set("client_render_world_total", strf(u8"{:05d}\u00b5s", Time::monotonicMicroseconds() - totalStart));
}
renderer->switchEffectConfig("interface");
auto start = Time::monotonicMicroseconds();
+ m_mainInterface->renderInWorldElements();
m_mainInterface->render();
m_cinematicOverlay->render();
LogMap::set("client_render_interface", strf(u8"{:05d}\u00b5s", Time::monotonicMicroseconds() - start));
diff --git a/source/core/StarJsonBuilder.cpp b/source/core/StarJsonBuilder.cpp
index 6084c40..6355666 100644
--- a/source/core/StarJsonBuilder.cpp
+++ b/source/core/StarJsonBuilder.cpp
@@ -127,7 +127,6 @@ void JsonStreamer<Json>::toJsonStream(Json const& val, JsonStream& stream, bool
stream.endArray();
} else if (type == Json::Type::Object) {
stream.beginObject();
- List<String::Char> chars;
if (sort) {
auto objectPtr = val.objectPtr();
List<JsonObject::const_iterator> iterators;
@@ -142,10 +141,8 @@ void JsonStreamer<Json>::toJsonStream(Json const& val, JsonStream& stream, bool
if (!first)
stream.putComma();
first = false;
- chars.clear();
- for (auto const& c : i->first)
- chars.push_back(c);
- stream.objectKey(chars.ptr(), chars.size());
+ auto ws = i->first.wideString();
+ stream.objectKey(ws.c_str(), ws.length());
stream.putColon();
toJsonStream(i->second, stream, sort);
}
diff --git a/source/rendering/StarTilePainter.cpp b/source/rendering/StarTilePainter.cpp
index d0a7e5a..40b3de6 100644
--- a/source/rendering/StarTilePainter.cpp
+++ b/source/rendering/StarTilePainter.cpp
@@ -124,25 +124,32 @@ size_t TilePainter::TextureKeyHash::operator()(TextureKey const& key) const {
}
TilePainter::ChunkHash TilePainter::terrainChunkHash(WorldRenderData& renderData, Vec2I chunkIndex) {
- XXHash3 hasher;
+ //XXHash3 hasher;
+ static ByteArray buffer;
+ buffer.clear();
RectI tileRange = RectI::withSize(chunkIndex * RenderChunkSize, Vec2I::filled(RenderChunkSize)).padded(MaterialRenderProfileMaxNeighborDistance);
-
forEachRenderTile(renderData, tileRange, [&](Vec2I const&, RenderTile const& renderTile) {
- renderTile.hashPushTerrain(hasher);
- });
+ //renderTile.hashPushTerrain(hasher);
+ buffer.append((char*)&renderTile, offsetof(RenderTile, liquidId));
+ });
- return hasher.digest();
+ //return hasher.digest();
+ return XXH3_64bits(buffer.ptr(), buffer.size());
}
TilePainter::ChunkHash TilePainter::liquidChunkHash(WorldRenderData& renderData, Vec2I chunkIndex) {
- XXHash3 hasher;
+ ///XXHash3 hasher;
RectI tileRange = RectI::withSize(chunkIndex * RenderChunkSize, Vec2I::filled(RenderChunkSize)).padded(MaterialRenderProfileMaxNeighborDistance);
+ static ByteArray buffer;
+ buffer.clear();
forEachRenderTile(renderData, tileRange, [&](Vec2I const&, RenderTile const& renderTile) {
- renderTile.hashPushLiquid(hasher);
- });
+ //renderTile.hashPushLiquid(hasher);
+ buffer.append((char*)&renderTile.liquidId, sizeof(LiquidId) + sizeof(LiquidLevel));
+ });
- return hasher.digest();
+ //return hasher.digest();
+ return XXH3_64bits(buffer.ptr(), buffer.size());
}
TilePainter::QuadZLevel TilePainter::materialZLevel(uint32_t zLevel, MaterialId material, MaterialHue hue, MaterialColorVariant colorVariant) {
diff --git a/source/rendering/StarWorldPainter.cpp b/source/rendering/StarWorldPainter.cpp
index 7bcbb45..e033ee1 100644
--- a/source/rendering/StarWorldPainter.cpp
+++ b/source/rendering/StarWorldPainter.cpp
@@ -69,6 +69,8 @@ void WorldPainter::render(WorldRenderData& renderData, function<void()> lightWai
m_environmentPainter->renderSky(Vec2F(m_camera.screenSize()), renderData.skyRenderData);
m_environmentPainter->renderFrontOrbiters(orbiterAndPlanetRatio, Vec2F(m_camera.screenSize()), renderData.skyRenderData);
+ m_renderer->flush();
+
if (lightWaiter) {
auto start = Time::monotonicMicroseconds();
lightWaiter();