diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5c8d18cf4a..c1d28fa7f9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -164,6 +164,7 @@ #include #include #include +#include #include "recording/ClipCache.h" #include "AudioClient.h" @@ -2168,6 +2169,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return nullptr; }); + ReferenceMaterial::setMaterialForUUIDOperator([this](const QUuid& entityID) -> graphics::MaterialPointer { + if (_aboutToQuit) { + return nullptr; + } + + auto renderable = getEntities()->renderableForEntityId(entityID); + if (renderable) { + return renderable->getTopMaterial(); + } + + return nullptr; + }); + connect(this, &Application::aboutToQuit, [this]() { setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); }); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index b7cfcde224..0bf2b590c0 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -495,6 +495,15 @@ void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const st emit requestRenderUpdate(); } +graphics::MaterialPointer EntityRenderer::getTopMaterial() { + std::lock_guard lock(_materialsLock); + auto materials = _materials.find("0"); + if (materials != _materials.end()) { + return materials->second.top().material; + } + return nullptr; +} + EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMaterial& materials) { if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) { return Pipeline::PROCEDURAL; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 29351cb25a..823498d223 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -62,6 +62,7 @@ public: }; virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName); virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName); + virtual graphics::MaterialPointer getTopMaterial(); static Pipeline getPipelineType(const graphics::MultiMaterial& materials); virtual gpu::TexturePointer getTexture() { return nullptr; } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 340d169f29..25403e8a2b 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -26,6 +26,8 @@ public: MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {} ~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); } + graphics::MaterialPointer getTopMaterial() override { return getMaterial(); } + private: virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 18df2e5d3f..b8e284d470 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -676,9 +676,10 @@ public: _element(element) {}; - TextureView(const TexturePointer& texture, uint16 subresource) : + TextureView(const TexturePointer& texture, uint16 subresource, std::function textureOperator = nullptr) : _texture(texture), - _subresource(subresource) + _subresource(subresource), + _textureOperator(textureOperator) {}; ~TextureView() {} @@ -689,6 +690,12 @@ public: bool operator !() const { return (!_texture); } bool isValid() const { return bool(_texture); } + + bool isReference() const { return (bool)_textureOperator; } + std::function getTextureOperator() const { return _textureOperator; } + +private: + std::function _textureOperator { nullptr }; }; typedef std::vector TextureViews; @@ -708,6 +715,7 @@ public: void resetTextureOperator(std::function textureOperator); bool isDefined() const; + std::function TextureSource::getTextureOperator() const { return _gpuTextureOperator; } protected: gpu::TexturePointer _gpuTexture; diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index 41cd319595..91265b6bfc 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -281,4 +281,20 @@ void MultiMaterial::calculateMaterialInfo() const { } _hasCalculatedTextureInfo = allTextures; } -} \ No newline at end of file +} + +void MultiMaterial::resetReferenceTexturesAndMaterials() { + _referenceTextures.clear(); +} + +void MultiMaterial::addReferenceTexture(const std::function& textureOperator) { + _referenceTextures.emplace_back(textureOperator, textureOperator()); +} + +bool MultiMaterial::anyReferenceMaterialsOrTexturesChanged() const { + for (auto textureOperatorPair : _referenceTextures) { + if (textureOperatorPair.first() != textureOperatorPair.second) { + return true; + } + } +} diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 7a411e5b2c..8caa4a3187 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -341,57 +341,57 @@ public: virtual ~Material() = default; Material& operator= (const Material& material); - const MaterialKey& getKey() const { return _key; } + virtual const MaterialKey& getKey() const { return _key; } static const float DEFAULT_EMISSIVE; void setEmissive(const glm::vec3& emissive, bool isSRGB = true); - glm::vec3 getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_emissive) : _emissive); } + virtual glm::vec3 getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_emissive) : _emissive); } static const float DEFAULT_OPACITY; void setOpacity(float opacity); - float getOpacity() const { return _opacity; } + virtual float getOpacity() const { return _opacity; } static const MaterialKey::OpacityMapMode DEFAULT_OPACITY_MAP_MODE; void setOpacityMapMode(MaterialKey::OpacityMapMode opacityMapMode); - MaterialKey::OpacityMapMode getOpacityMapMode() const; + virtual MaterialKey::OpacityMapMode getOpacityMapMode() const; static const float DEFAULT_OPACITY_CUTOFF; void setOpacityCutoff(float opacityCutoff); - float getOpacityCutoff() const { return _opacityCutoff; } + virtual float getOpacityCutoff() const { return _opacityCutoff; } static const MaterialKey::CullFaceMode DEFAULT_CULL_FACE_MODE; void setCullFaceMode(MaterialKey::CullFaceMode cullFaceMode) { _cullFaceMode = cullFaceMode; } - MaterialKey::CullFaceMode getCullFaceMode() const { return _cullFaceMode; } + virtual MaterialKey::CullFaceMode getCullFaceMode() const { return _cullFaceMode; } void setUnlit(bool value); - bool isUnlit() const { return _key.isUnlit(); } + virtual bool isUnlit() const { return _key.isUnlit(); } static const float DEFAULT_ALBEDO; void setAlbedo(const glm::vec3& albedo, bool isSRGB = true); - glm::vec3 getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_albedo) : _albedo); } + virtual glm::vec3 getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_albedo) : _albedo); } static const float DEFAULT_METALLIC; void setMetallic(float metallic); - float getMetallic() const { return _metallic; } + virtual float getMetallic() const { return _metallic; } static const float DEFAULT_ROUGHNESS; void setRoughness(float roughness); - float getRoughness() const { return _roughness; } + virtual float getRoughness() const { return _roughness; } static const float DEFAULT_SCATTERING; void setScattering(float scattering); - float getScattering() const { return _scattering; } + virtual float getScattering() const { return _scattering; } // The texture map to channel association static const int NUM_TEXCOORD_TRANSFORMS { 2 }; void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap); - const TextureMaps& getTextureMaps() const { return _textureMaps; } // FIXME - not thread safe... + virtual const TextureMaps& getTextureMaps() const { return _textureMaps; } // FIXME - not thread safe... const TextureMapPointer getTextureMap(MapChannel channel) const; // Albedo maps cannot have opacity detected until they are loaded // This method allows const changing of the key/schemaBuffer without touching the map // return true if the opacity changed, flase otherwise - bool resetOpacityMap() const; + virtual bool resetOpacityMap() const; // conversion from legacy material properties to PBR equivalent static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; } @@ -404,12 +404,12 @@ public: const std::string& getModel() const { return _model; } void setModel(const std::string& model) { _model = model; } - glm::mat4 getTexCoordTransform(uint i) const { return _texcoordTransforms[i]; } + virtual glm::mat4 getTexCoordTransform(uint i) const { return _texcoordTransforms[i]; } void setTexCoordTransform(uint i, const glm::mat4& mat4) { _texcoordTransforms[i] = mat4; } - glm::vec2 getLightmapParams() const { return _lightmapParams; } - glm::vec2 getMaterialParams() const { return _materialParams; } + virtual glm::vec2 getLightmapParams() const { return _lightmapParams; } + virtual glm::vec2 getMaterialParams() const { return _materialParams; } - bool getDefaultFallthrough() const { return _defaultFallthrough; } + virtual bool getDefaultFallthrough() const { return _defaultFallthrough; } void setDefaultFallthrough(bool defaultFallthrough) { _defaultFallthrough = defaultFallthrough; } enum ExtraFlagBit { @@ -547,12 +547,15 @@ public: void setTexturesLoading(bool value) { _texturesLoading = value; } void setInitialized() { _initialized = true; } - bool shouldUpdate() const { return !_initialized || _needsUpdate || _texturesLoading; } + bool shouldUpdate() const { return !_initialized || _needsUpdate || _texturesLoading || anyReferenceMaterialsOrTexturesChanged(); } int getTextureCount() const { calculateMaterialInfo(); return _textureCount; } size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; } bool hasTextureInfo() const { return _hasCalculatedTextureInfo; } + void resetReferenceTexturesAndMaterials(); + void addReferenceTexture(const std::function& textureOperator); + private: gpu::BufferView _schemaBuffer; graphics::MaterialKey::CullFaceMode _cullFaceMode { graphics::Material::DEFAULT_CULL_FACE_MODE }; @@ -565,6 +568,10 @@ private: mutable int _textureCount { 0 }; mutable bool _hasCalculatedTextureInfo { false }; void calculateMaterialInfo() const; + + bool anyReferenceMaterialsOrTexturesChanged() const; + + std::vector, gpu::TexturePointer>> _referenceTextures; }; }; diff --git a/libraries/graphics/src/graphics/TextureMap.cpp b/libraries/graphics/src/graphics/TextureMap.cpp index 69e182fc9d..0590203907 100755 --- a/libraries/graphics/src/graphics/TextureMap.cpp +++ b/libraries/graphics/src/graphics/TextureMap.cpp @@ -23,7 +23,7 @@ bool TextureMap::isDefined() const { gpu::TextureView TextureMap::getTextureView() const { if (_textureSource) { - return gpu::TextureView(_textureSource->getGPUTexture(), 0); + return gpu::TextureView(_textureSource->getGPUTexture(), 0, _textureSource->getTextureOperator()); } else { return gpu::TextureView(); } diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index d70477429d..a198017a99 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -212,26 +212,26 @@ public: ProceduralMaterial() : NetworkMaterial() { initializeProcedural(); } ProceduralMaterial(const NetworkMaterial& material) : NetworkMaterial(material) { initializeProcedural(); } - bool isProcedural() const override { return true; } - bool isEnabled() const override { return _procedural.isEnabled(); } - bool isReady() const override { return _procedural.isReady(); } - QString getProceduralString() const override { return _proceduralString; } + virtual bool isProcedural() const override { return true; } + virtual bool isEnabled() const override { return _procedural.isEnabled(); } + virtual bool isReady() const override { return _procedural.isReady(); } + virtual QString getProceduralString() const override { return _proceduralString; } void setProceduralData(const QString& data) { _proceduralString = data; _procedural.setProceduralData(ProceduralData::parse(data)); } - glm::vec4 getColor(const glm::vec4& color) const { return _procedural.getColor(color); } - bool isFading() const { return _procedural.isFading(); } + virtual glm::vec4 getColor(const glm::vec4& color) const { return _procedural.getColor(color); } + virtual bool isFading() const { return _procedural.isFading(); } void setIsFading(bool isFading) { _procedural.setIsFading(isFading); } - uint64_t getFadeStartTime() const { return _procedural.getFadeStartTime(); } - bool hasVertexShader() const { return _procedural.hasVertexShader(); } - void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, + virtual uint64_t getFadeStartTime() const { return _procedural.getFadeStartTime(); } + virtual bool hasVertexShader() const { return _procedural.hasVertexShader(); } + virtual void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, const uint64_t& created, const ProceduralProgramKey key = ProceduralProgramKey()) { _procedural.prepare(batch, position, size, orientation, created, key); } - void initializeProcedural(); + virtual void initializeProcedural(); void setBoundOperator(const std::function& boundOperator) { _procedural.setBoundOperator(boundOperator); } bool hasBoundOperator() const { return _procedural.hasBoundOperator(); } @@ -243,4 +243,4 @@ private: }; typedef std::shared_ptr ProceduralMaterialPointer; -} \ No newline at end of file +} diff --git a/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp b/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp index 049246b4fc..7e1a769c61 100644 --- a/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp +++ b/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp @@ -14,6 +14,7 @@ #include "RegisteredMetaTypes.h" #include "Procedural.h" +#include "ReferenceMaterial.h" NetworkMaterialResource::NetworkMaterialResource(const QUrl& url) : Resource(url) {} @@ -92,14 +93,14 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater if (materialsValue.isArray()) { QJsonArray materials = materialsValue.toArray(); for (auto material : materials) { - if (!material.isNull() && material.isObject()) { - auto parsedMaterial = parseJSONMaterial(material.toObject(), baseUrl); + if (!material.isNull() && (material.isObject() || material.isString())) { + auto parsedMaterial = parseJSONMaterial(material, baseUrl); toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second; toReturn.names.push_back(parsedMaterial.first); } } - } else if (materialsValue.isObject()) { - auto parsedMaterial = parseJSONMaterial(materialsValue.toObject(), baseUrl); + } else if (materialsValue.isObject() || materialsValue.isString()) { + auto parsedMaterial = parseJSONMaterial(materialsValue, baseUrl); toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second; toReturn.names.push_back(parsedMaterial.first); } @@ -211,10 +212,22 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater * @property {ProceduralData} procedural - The definition of a procedural shader material. "hifi_shader_simple" model only. */ // Note: See MaterialEntityItem.h for default values used in practice. -std::pair> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) { +std::pair> NetworkMaterialResource::parseJSONMaterial(const QJsonValue& materialJSONValue, const QUrl& baseUrl) { std::string name = ""; std::shared_ptr networkMaterial; + if (materialJSONValue.isString()) { + QString uuidString = materialJSONValue.toString(); + name = uuidString.toStdString(); + QUuid uuid = QUuid(uuidString); + if (!uuid.isNull()) { + networkMaterial = std::make_shared(uuid); + } + return std::pair>(name, networkMaterial); + } + + QJsonObject materialJSON = materialJSONValue.toObject(); + std::string modelString = graphics::Material::HIFI_PBR; auto modelJSONIter = materialJSON.find("model"); if (modelJSONIter != materialJSON.end() && modelJSONIter.value().isString()) { diff --git a/libraries/procedural/src/procedural/ProceduralMaterialCache.h b/libraries/procedural/src/procedural/ProceduralMaterialCache.h index 0a44ccf0ef..7b71438898 100644 --- a/libraries/procedural/src/procedural/ProceduralMaterialCache.h +++ b/libraries/procedural/src/procedural/ProceduralMaterialCache.h @@ -33,8 +33,8 @@ public: void setScatteringMap(const QUrl& url); void setLightMap(const QUrl& url); - bool isMissingTexture(); - bool checkResetOpacityMap(); + virtual bool isMissingTexture(); + virtual bool checkResetOpacityMap(); class Texture { public: @@ -100,7 +100,7 @@ public: ParsedMaterials parsedMaterials; static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl); - static std::pair> parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl); + static std::pair> parseJSONMaterial(const QJsonValue& materialJSONValue, const QUrl& baseUrl); private: static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB); diff --git a/libraries/procedural/src/procedural/ReferenceMaterial.cpp b/libraries/procedural/src/procedural/ReferenceMaterial.cpp new file mode 100644 index 0000000000..389224c60b --- /dev/null +++ b/libraries/procedural/src/procedural/ReferenceMaterial.cpp @@ -0,0 +1,179 @@ +// +// Created by HifiExperiments on 3/14/2021 +// Copyright 2021 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ReferenceMaterial.h" + +std::function ReferenceMaterial::_materialForUUIDOperator = nullptr; + +// Material +const graphics::MaterialKey& ReferenceMaterial::getKey() const { + auto material = getMaterial(); + return material ? material->getKey() : Parent::getKey(); +} + +glm::vec3 ReferenceMaterial::getEmissive(bool SRGB) const { + auto material = getMaterial(); + return material ? material->getEmissive(SRGB) : glm::vec3(DEFAULT_EMISSIVE); +} + +float ReferenceMaterial::getOpacity() const { + auto material = getMaterial(); + return material ? material->getOpacity() : DEFAULT_OPACITY; +} + +graphics::MaterialKey::OpacityMapMode ReferenceMaterial::getOpacityMapMode() const { + auto material = getMaterial(); + return material ? material->getOpacityMapMode() : DEFAULT_OPACITY_MAP_MODE; +} + +float ReferenceMaterial::getOpacityCutoff() const { + auto material = getMaterial(); + return material ? material->getOpacityCutoff() : DEFAULT_OPACITY_CUTOFF; +} + +graphics::MaterialKey::CullFaceMode ReferenceMaterial::getCullFaceMode() const { + auto material = getMaterial(); + return material ? material->getCullFaceMode() : DEFAULT_CULL_FACE_MODE; +} + +bool ReferenceMaterial::isUnlit() const { + auto material = getMaterial(); + return material ? material->isUnlit() : false; +} + +glm::vec3 ReferenceMaterial::getAlbedo(bool SRGB) const { + auto material = getMaterial(); + return material ? material->getAlbedo(SRGB) : glm::vec3(DEFAULT_ALBEDO); +} + +float ReferenceMaterial::getMetallic() const { + auto material = getMaterial(); + return material ? material->getMetallic() : DEFAULT_METALLIC; +} + +float ReferenceMaterial::getRoughness() const { + auto material = getMaterial(); + return material ? material->getRoughness() : DEFAULT_ROUGHNESS; +} + +float ReferenceMaterial::getScattering() const { + auto material = getMaterial(); + return material ? material->getScattering() : DEFAULT_SCATTERING; +} + +bool ReferenceMaterial::resetOpacityMap() const { + auto material = getMaterial(); + return material ? material->resetOpacityMap() : false; +} + +const graphics::Material::TextureMaps& ReferenceMaterial::getTextureMaps() const { + auto material = getMaterial(); + return material ? material->getTextureMaps() : Parent::getTextureMaps(); +} + +glm::vec2 ReferenceMaterial::getLightmapParams() const { + auto material = getMaterial(); + return material ? material->getLightmapParams() : glm::vec2(0.0f, 1.0f); +} + +bool ReferenceMaterial::getDefaultFallthrough() const { + auto material = getMaterial(); + return material ? material->getDefaultFallthrough() : false; +} + +// NetworkMaterial +bool ReferenceMaterial::isMissingTexture() { + auto material = getNetworkMaterial(); + return material ? material->isMissingTexture() : false; +} + +bool ReferenceMaterial::checkResetOpacityMap() { + auto material = getNetworkMaterial(); + return material ? material->checkResetOpacityMap() : false; +} + +// ProceduralMaterial +bool ReferenceMaterial::isProcedural() const { + auto material = getMaterial(); + return material ? material->isProcedural() : false; +} + +bool ReferenceMaterial::isEnabled() const { + auto material = getMaterial(); + return material ? material->isEnabled() : false; +} + +bool ReferenceMaterial::isReady() const { + auto material = getMaterial(); + return material ? material->isReady() : false; +} + +QString ReferenceMaterial::getProceduralString() const { + auto material = getMaterial(); + return material ? material->getProceduralString() : false; +} + +glm::vec4 ReferenceMaterial::getColor(const glm::vec4& color) const { + auto material = getProceduralMaterial(); + return material ? material->getColor(color) : glm::vec4(); +} + +bool ReferenceMaterial::isFading() const { + auto material = getProceduralMaterial(); + return material ? material->isFading() : false; +} + +uint64_t ReferenceMaterial::getFadeStartTime() const { + auto material = getProceduralMaterial(); + return material ? material->getFadeStartTime() : 0; +} + +bool ReferenceMaterial::hasVertexShader() const { + auto material = getProceduralMaterial(); + return material ? material->hasVertexShader() : false; +} + +void ReferenceMaterial::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, + const uint64_t& created, const ProceduralProgramKey key) { + if (auto material = getProceduralMaterial()) { + material->prepare(batch, position, size, orientation, created, key); + } +} + +void ReferenceMaterial::initializeProcedural() { + if (auto material = getProceduralMaterial()) { + material->initializeProcedural(); + } +} + +graphics::MaterialPointer ReferenceMaterial::getMaterial() const { + if (_materialForUUIDOperator) { + return _materialForUUIDOperator(_uuid); + } + return nullptr; +} + +std::shared_ptr ReferenceMaterial::getNetworkMaterial() const { + if (_materialForUUIDOperator) { + auto material = _materialForUUIDOperator(_uuid); + if (material && material->isProcedural()) { + return std::static_pointer_cast(material); + } + } + return nullptr; +} + +graphics::ProceduralMaterialPointer ReferenceMaterial::getProceduralMaterial() const { + if (_materialForUUIDOperator) { + auto material = _materialForUUIDOperator(_uuid); + if (material && material->isProcedural()) { + return std::static_pointer_cast(material); + } + } + return nullptr; +} diff --git a/libraries/procedural/src/procedural/ReferenceMaterial.h b/libraries/procedural/src/procedural/ReferenceMaterial.h new file mode 100644 index 0000000000..fcefac8407 --- /dev/null +++ b/libraries/procedural/src/procedural/ReferenceMaterial.h @@ -0,0 +1,66 @@ +// +// Created by HifiExperiments on 3/14/2021 +// Copyright 2021 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once + +#include "Procedural.h" + +class ReferenceMaterial : public graphics::ProceduralMaterial { +public: + using Parent = graphics::ProceduralMaterial; + + ReferenceMaterial() {} + ReferenceMaterial(QUuid uuid) : graphics::ProceduralMaterial(), _uuid(uuid) {} + + // Material + const graphics::MaterialKey& getKey() const override; + glm::vec3 getEmissive(bool SRGB = true) const override; + float getOpacity() const override; + graphics::MaterialKey::OpacityMapMode getOpacityMapMode() const override; + float getOpacityCutoff() const override; + graphics::MaterialKey::CullFaceMode getCullFaceMode() const override; + bool isUnlit() const override; + glm::vec3 getAlbedo(bool SRGB = true) const override; + float getMetallic() const override; + float getRoughness() const override; + float getScattering() const override; + bool resetOpacityMap() const override; + const graphics::Material::TextureMaps& getTextureMaps() const override; + //glm::mat4 getTexCoordTransform(uint i) const override; // use my actual transform, instead of the original + glm::vec2 getLightmapParams() const override; + //glm::vec2 getMaterialParams() const override; // use my actual params, instead of the original + bool getDefaultFallthrough() const override; + + // NetworkMaterial + bool isMissingTexture() override; + bool checkResetOpacityMap() override; + + // ProceduralMaterial + bool isProcedural() const override; + bool isEnabled() const override; + bool isReady() const override; + QString getProceduralString() const override; + + glm::vec4 getColor(const glm::vec4& color) const override; + bool isFading() const override; + uint64_t getFadeStartTime() const override; + bool hasVertexShader() const override; + void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, + const uint64_t& created, const ProceduralProgramKey key = ProceduralProgramKey()) override; + void initializeProcedural() override; + + static void setMaterialForUUIDOperator(std::function materialForUUIDOperator) { _materialForUUIDOperator = materialForUUIDOperator; } + +private: + static std::function _materialForUUIDOperator; + QUuid _uuid; + + graphics::MaterialPointer getMaterial() const; + std::shared_ptr getNetworkMaterial() const; + graphics::ProceduralMaterialPointer getProceduralMaterial() const; +}; diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index fe42cc1d0e..b1c927761e 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -378,6 +378,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial auto& drawMaterialTextures = multiMaterial.getTextureTable(); multiMaterial.setTexturesLoading(false); + multiMaterial.resetReferenceTexturesAndMaterials(); // The total list of things we need to look for static std::set allFlags; @@ -482,6 +483,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr->second->isDefined()) { material->resetOpacityMap(); drawMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true); @@ -501,6 +505,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr != textureMaps.end()) { if (itr->second->isDefined()) { drawMaterialTextures->setTexture(gr::Texture::MaterialMetallic, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true); @@ -518,6 +525,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr != textureMaps.end()) { if (itr->second->isDefined()) { drawMaterialTextures->setTexture(gr::Texture::MaterialRoughness, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true); @@ -535,6 +545,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr != textureMaps.end()) { if (itr->second->isDefined()) { drawMaterialTextures->setTexture(gr::Texture::MaterialNormal, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true); @@ -552,6 +565,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr != textureMaps.end()) { if (itr->second->isDefined()) { drawMaterialTextures->setTexture(gr::Texture::MaterialOcclusion, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true); @@ -569,6 +585,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr != textureMaps.end()) { if (itr->second->isDefined()) { drawMaterialTextures->setTexture(gr::Texture::MaterialScattering, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true); @@ -587,6 +606,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr != textureMaps.end()) { if (itr->second->isDefined()) { drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true); @@ -607,6 +629,9 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial if (itr != textureMaps.end()) { if (itr->second->isDefined()) { drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView()); + if (itr->second->getTextureView().isReference()) { + multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator()); + } wasSet = true; } else { multiMaterial.setTexturesLoading(true);