mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #7546 from zzmp/fix/release-skyboxes
Release skybox textures when rendering stars
This commit is contained in:
commit
278fe93f2b
5 changed files with 46 additions and 15 deletions
|
@ -297,7 +297,14 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
auto sceneLocation = sceneStage->getLocation();
|
||||
auto sceneTime = sceneStage->getTime();
|
||||
|
||||
// Skybox and procedural skybox data
|
||||
auto skybox = std::dynamic_pointer_cast<ProceduralSkybox>(skyStage->getSkybox());
|
||||
static QString userData;
|
||||
|
||||
if (!zone) {
|
||||
userData = QString();
|
||||
skybox->clear();
|
||||
|
||||
_pendingSkyboxTexture = false;
|
||||
_skyboxTexture.clear();
|
||||
|
||||
|
@ -373,9 +380,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
|
||||
switch (zone->getBackgroundMode()) {
|
||||
case BACKGROUND_MODE_SKYBOX: {
|
||||
auto skybox = std::dynamic_pointer_cast<ProceduralSkybox>(skyStage->getSkybox());
|
||||
skybox->setColor(zone->getSkyboxProperties().getColorVec3());
|
||||
static QString userData;
|
||||
if (userData != zone->getUserData()) {
|
||||
userData = zone->getUserData();
|
||||
skybox->parse(userData);
|
||||
|
@ -414,9 +419,15 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
|
||||
case BACKGROUND_MODE_INHERIT:
|
||||
default:
|
||||
skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application background through
|
||||
_pendingSkyboxTexture = false;
|
||||
// Clear the skybox to release its textures
|
||||
userData = QString();
|
||||
skybox->clear();
|
||||
|
||||
_skyboxTexture.clear();
|
||||
_pendingSkyboxTexture = false;
|
||||
|
||||
// Let the application background through
|
||||
skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ public:
|
|||
void setCubemap(const gpu::TexturePointer& cubemap);
|
||||
const gpu::TexturePointer& getCubemap() const { return _cubemap; }
|
||||
|
||||
virtual void clear() { setCubemap(nullptr); }
|
||||
|
||||
void prepare(gpu::Batch& batch, int textureSlot = SKYBOX_SKYMAP_SLOT, int bufferSlot = SKYBOX_CONSTANTS_SLOT) const;
|
||||
virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const;
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ bool Procedural::parseVersion(const QJsonValue& version) {
|
|||
bool Procedural::parseUrl(const QUrl& shaderUrl) {
|
||||
if (!shaderUrl.isValid()) {
|
||||
qWarning() << "Invalid shader URL: " << shaderUrl;
|
||||
_networkShader.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -110,6 +111,7 @@ bool Procedural::parseUrl(const QUrl& shaderUrl) {
|
|||
_shaderPath = _shaderUrl.toLocalFile();
|
||||
qDebug() << "Shader path: " << _shaderPath;
|
||||
if (!QFile(_shaderPath).exists()) {
|
||||
_networkShader.reset();
|
||||
return false;;
|
||||
}
|
||||
} else {
|
||||
|
@ -135,9 +137,14 @@ bool Procedural::parseTextures(const QJsonArray& channels) {
|
|||
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
size_t channelCount = std::min(MAX_PROCEDURAL_TEXTURE_CHANNELS, (size_t)_parsedChannels.size());
|
||||
for (size_t i = 0; i < channelCount; ++i) {
|
||||
QString url = _parsedChannels.at((int)i).toString();
|
||||
_channels[i] = textureCache->getTexture(QUrl(url));
|
||||
size_t channel = 0;
|
||||
for (; channel < channelCount; ++channel) {
|
||||
QString url = _parsedChannels.at((int)channel).toString();
|
||||
_channels[channel] = textureCache->getTexture(QUrl(url));
|
||||
}
|
||||
for (; channel < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++channel) {
|
||||
// Release those textures no longer in use
|
||||
_channels[channel] = textureCache->getTexture(QUrl());
|
||||
}
|
||||
|
||||
_channelsDirty = true;
|
||||
|
@ -149,20 +156,21 @@ bool Procedural::parseTextures(const QJsonArray& channels) {
|
|||
void Procedural::parse(const QJsonObject& proceduralData) {
|
||||
_enabled = false;
|
||||
|
||||
if (proceduralData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto version = proceduralData[VERSION_KEY];
|
||||
auto shaderUrl = proceduralData[URL_KEY].toString();
|
||||
shaderUrl = ResourceManager::normalizeURL(shaderUrl);
|
||||
auto uniforms = proceduralData[UNIFORMS_KEY].toObject();
|
||||
auto channels = proceduralData[CHANNELS_KEY].toArray();
|
||||
|
||||
if (parseVersion(version) &&
|
||||
parseUrl(shaderUrl) &&
|
||||
parseUniforms(uniforms) &&
|
||||
parseTextures(channels)) {
|
||||
bool isValid = true;
|
||||
|
||||
// Run through parsing regardless of validity to clear old cached resources
|
||||
isValid = parseVersion(version) && isValid;
|
||||
isValid = parseUrl(shaderUrl) && isValid;
|
||||
isValid = parseUniforms(uniforms) && isValid;
|
||||
isValid = parseTextures(channels) && isValid;
|
||||
|
||||
if (!proceduralData.isEmpty() && isValid) {
|
||||
_enabled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,14 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() {
|
|||
_procedural._state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
}
|
||||
|
||||
void ProceduralSkybox::clear() {
|
||||
// Parse and prepare a procedural with no shaders to release textures
|
||||
parse(QString());
|
||||
_procedural.ready();
|
||||
|
||||
Skybox::clear();
|
||||
}
|
||||
|
||||
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const {
|
||||
if (_procedural.ready()) {
|
||||
ProceduralSkybox::render(batch, frustum, (*this));
|
||||
|
|
|
@ -24,6 +24,8 @@ public:
|
|||
|
||||
void parse(const QString& userData) { _procedural.parse(userData); }
|
||||
|
||||
virtual void clear() override;
|
||||
|
||||
virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const;
|
||||
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const ProceduralSkybox& skybox);
|
||||
|
||||
|
|
Loading…
Reference in a new issue