From c5a94a415d6bd4d48d62d8ac0649119ba0e647ce Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 17 Oct 2018 09:55:44 -0700 Subject: [PATCH] fix material entity opacity maps --- .../src/RenderableMaterialEntityItem.cpp | 14 ++++- .../src/RenderableMaterialEntityItem.h | 1 + .../src/model-networking/ModelCache.cpp | 51 +++++++++++-------- .../src/model-networking/ModelCache.h | 3 ++ 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index d7a0cfd18d..c607f678b6 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -24,12 +24,18 @@ bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) { return true; } + if (!_texturesLoaded) { + return true; + } return false; } void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { withWriteLock([&] { - _drawMaterial = entity->getMaterial(); + if (_drawMaterial != entity->getMaterial()) { + _texturesLoaded = false; + _drawMaterial = entity->getMaterial(); + } _parentID = entity->getParentID(); _materialMappingPos = entity->getMaterialMappingPos(); _materialMappingScale = entity->getMaterialMappingScale(); @@ -38,6 +44,12 @@ void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& const float MATERIAL_ENTITY_SCALE = 0.5f; _renderTransform.postScale(MATERIAL_ENTITY_SCALE); _renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); + + bool newTexturesLoaded = _drawMaterial ? !_drawMaterial->isMissingTexture() : false; + if (!_texturesLoaded && newTexturesLoaded) { + _drawMaterial->checkResetOpacityMap(); + } + _texturesLoaded = newTexturesLoaded; }); } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 168041a842..c90048ecf5 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -35,6 +35,7 @@ private: glm::vec2 _materialMappingPos; glm::vec2 _materialMappingScale; float _materialMappingRot; + bool _texturesLoaded { false }; std::shared_ptr _drawMaterial; }; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 4d6297303b..e96815d391 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -414,33 +414,13 @@ bool Geometry::areTexturesLoaded() const { if (!_areTexturesLoaded) { for (auto& material : _materials) { // Check if material textures are loaded - bool materialMissingTexture = std::any_of(material->_textures.cbegin(), material->_textures.cend(), - [](const NetworkMaterial::Textures::value_type& it) { - auto texture = it.texture; - if (!texture) { - return false; - } - // Failed texture downloads need to be considered as 'loaded' - // or the object will never fade in - bool finished = texture->isFailed() || (texture->isLoaded() && texture->getGPUTexture() && texture->getGPUTexture()->isDefined()); - if (!finished) { - return true; - } - return false; - }); + bool materialMissingTexture = material->isMissingTexture(); if (materialMissingTexture) { return false; } - // If material textures are loaded, check the material translucency - // FIXME: This should not be done here. The opacity map should already be reset in Material::setTextureMap. - // However, currently that code can be called before the albedo map is defined, so resetOpacityMap will fail. - // Geometry::areTexturesLoaded() is called repeatedly until it returns true, so we do the check here for now - const auto albedoTexture = material->_textures[NetworkMaterial::MapChannel::ALBEDO_MAP]; - if (albedoTexture.texture) { - material->resetOpacityMap(); - } + material->checkResetOpacityMap(); } _areTexturesLoaded = true; @@ -783,4 +763,31 @@ void NetworkMaterial::setTextures(const QVariantMap& textureMap) { } } +bool NetworkMaterial::isMissingTexture() { + for (auto& networkTexture : _textures) { + auto& texture = networkTexture.texture; + if (!texture) { + continue; + } + // Failed texture downloads need to be considered as 'loaded' + // or the object will never fade in + bool finished = texture->isFailed() || (texture->isLoaded() && texture->getGPUTexture() && texture->getGPUTexture()->isDefined()); + if (!finished) { + return true; + } + } + return false; +} + +void NetworkMaterial::checkResetOpacityMap() { + // If material textures are loaded, check the material translucency + // FIXME: This should not be done here. The opacity map should already be reset in Material::setTextureMap. + // However, currently that code can be called before the albedo map is defined, so resetOpacityMap will fail. + // Geometry::areTexturesLoaded() is called repeatedly until it returns true, so we do the check here for now + const auto& albedoTexture = _textures[NetworkMaterial::MapChannel::ALBEDO_MAP]; + if (albedoTexture.texture) { + resetOpacityMap(); + } +} + #include "ModelCache.moc" diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index dfe26788f2..de52da0b54 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -177,6 +177,9 @@ public: void setScatteringMap(const QUrl& url); void setLightmapMap(const QUrl& url); + bool isMissingTexture(); + void checkResetOpacityMap(); + protected: friend class Geometry;