This commit is contained in:
HifiExperiments 2021-07-05 16:49:17 -07:00
parent 7f99ddca2e
commit bdbb88084b
12 changed files with 180 additions and 85 deletions

View file

@ -635,6 +635,7 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
{ {
std::lock_guard<std::mutex> lock(_materialsLock); std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials.find("0"); materials = _materials.find("0");
if (materials != _materials.end()) { if (materials != _materials.end()) {
if (materials->second.shouldUpdate()) { if (materials->second.shouldUpdate()) {
RenderPipelines::updateMultiMaterial(materials->second); RenderPipelines::updateMultiMaterial(materials->second);
@ -662,7 +663,6 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
auto pipelineType = getPipelineType(materials->second); auto pipelineType = getPipelineType(materials->second);
if (pipelineType == Pipeline::MATERIAL) { if (pipelineType == Pipeline::MATERIAL) {
builder.withMaterial(); builder.withMaterial();
if (drawMaterialKey.isNormalMap()) { if (drawMaterialKey.isNormalMap()) {
builder.withTangents(); builder.withTangents();
} }

View file

@ -198,10 +198,8 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
procedural->prepare(*batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, ProceduralProgramKey(transparent)); procedural->prepare(*batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, ProceduralProgramKey(transparent));
} else if (pipelineType == Pipeline::SIMPLE) { } else if (pipelineType == Pipeline::SIMPLE) {
batch->setResourceTexture(0, _texture->getGPUTexture()); batch->setResourceTexture(0, _texture->getGPUTexture());
} else { } else if (RenderPipelines::bindMaterials(materials, *batch, args->_renderMode, args->_enableTexturing)) {
if (RenderPipelines::bindMaterials(materials, *batch, args->_renderMode, args->_enableTexturing)) { args->_details._materialSwitches++;
args->_details._materialSwitches++;
}
} }
DependencyManager::get<GeometryCache>()->renderQuad( DependencyManager::get<GeometryCache>()->renderQuad(

View file

@ -954,7 +954,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
* @property {string} materialURL="" - URL to a {@link Entities.MaterialResource|MaterialResource}. Alternatively, set the * @property {string} materialURL="" - URL to a {@link Entities.MaterialResource|MaterialResource}. Alternatively, set the
* property value to <code>"materialData"</code> to use the <code>materialData</code> property for the * property value to <code>"materialData"</code> to use the <code>materialData</code> property for the
* {@link Entities.MaterialResource|MaterialResource} values. If you append <code>"#name"</code> to the URL, the material * {@link Entities.MaterialResource|MaterialResource} values. If you append <code>"#name"</code> to the URL, the material
* with that name will be applied to the entity. You can also use the ID of another material entity as the URL, in which * with that name will be applied to the entity. You can also use the ID of another Material entity as the URL, in which
* case this material will act as a copy of that material, with its own unique material transform, priority, etc. * case this material will act as a copy of that material, with its own unique material transform, priority, etc.
* @property {string} materialData="" - Used to store {@link Entities.MaterialResource|MaterialResource} data as a JSON string. * @property {string} materialData="" - Used to store {@link Entities.MaterialResource|MaterialResource} data as a JSON string.
* You can use <code>JSON.parse()</code> to parse the string into a JavaScript object which you can manipulate the * You can use <code>JSON.parse()</code> to parse the string into a JavaScript object which you can manipulate the
@ -1380,7 +1380,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
/*@jsdoc /*@jsdoc
* The <code>"Web"</code> {@link Entities.EntityType|EntityType} displays a browsable web page. Each user views their own copy * The <code>"Web"</code> {@link Entities.EntityType|EntityType} displays a browsable web page. Each user views their own copy
* of the web page: if one user navigates to another page on the entity, other users do not see the change; if a video is being * of the web page: if one user navigates to another page on the entity, other users do not see the change; if a video is being
* played, users don't see it in sync. It has properties in addition to the common * played, users don't see it in sync. Internally, a Web Entity is rendered as a non-repeating, upside down texture, so additional
* transformations may be necessary if you reference a web entity texture by UUID. It has properties in addition to the common
* {@link Entities.EntityProperties|EntityProperties}. * {@link Entities.EntityProperties|EntityProperties}.
* *
* @typedef {object} Entities.EntityProperties-Web * @typedef {object} Entities.EntityProperties-Web

View file

@ -898,8 +898,11 @@ void SphericalHarmonics::evalFromTexture(const Texture& texture, gpu::BackendTar
// TextureSource // TextureSource
const gpu::TexturePointer TextureSource::getGPUTexture() const { const gpu::TexturePointer TextureSource::getGPUTexture() const {
if (_gpuTextureOperator) { if (_gpuTextureOperator && !_locked) {
return _gpuTextureOperator(); _locked = true;
auto gpuTexture = _gpuTextureOperator();
_locked = false;
return gpuTexture;
} }
return _gpuTexture; return _gpuTexture;
} }
@ -915,8 +918,10 @@ void TextureSource::resetTextureOperator(const std::function<gpu::TexturePointer
} }
bool TextureSource::isDefined() const { bool TextureSource::isDefined() const {
if (_gpuTextureOperator) { if (_gpuTextureOperator && !_locked) {
_locked = true;
auto gpuTexture = _gpuTextureOperator(); auto gpuTexture = _gpuTextureOperator();
_locked = false;
return gpuTexture && gpuTexture->isDefined(); return gpuTexture && gpuTexture->isDefined();
} }
return _gpuTexture && _gpuTexture->isDefined(); return _gpuTexture && _gpuTexture->isDefined();

View file

@ -727,6 +727,7 @@ public:
protected: protected:
gpu::TexturePointer _gpuTexture; gpu::TexturePointer _gpuTexture;
std::function<gpu::TexturePointer()> _gpuTextureOperator { nullptr }; std::function<gpu::TexturePointer()> _gpuTextureOperator { nullptr };
mutable bool _locked { false };
QUrl _imageUrl; QUrl _imageUrl;
int _type { 0 }; int _type { 0 };
}; };

View file

@ -341,7 +341,7 @@ public:
virtual ~Material() = default; virtual ~Material() = default;
Material& operator= (const Material& material); Material& operator= (const Material& material);
virtual const MaterialKey& getKey() const { return _key; } virtual MaterialKey getKey() const { return _key; }
static const float DEFAULT_EMISSIVE; static const float DEFAULT_EMISSIVE;
void setEmissive(const glm::vec3& emissive, bool isSRGB = true); void setEmissive(const glm::vec3& emissive, bool isSRGB = true);
@ -385,7 +385,7 @@ public:
// The texture map to channel association // The texture map to channel association
static const int NUM_TEXCOORD_TRANSFORMS { 2 }; static const int NUM_TEXCOORD_TRANSFORMS { 2 };
void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap); void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
virtual const TextureMaps& getTextureMaps() const { return _textureMaps; } // FIXME - not thread safe... virtual TextureMaps getTextureMaps() const { return _textureMaps; } // FIXME - not thread safe...
const TextureMapPointer getTextureMap(MapChannel channel) const; const TextureMapPointer getTextureMap(MapChannel channel) const;
// Albedo maps cannot have opacity detected until they are loaded // Albedo maps cannot have opacity detected until they are loaded

View file

@ -1403,3 +1403,8 @@ std::function<gpu::TexturePointer()> Texture::getTextureForUUIDOperator(const QU
} }
return nullptr; return nullptr;
} }
void Texture::setUnboundTextureForUUIDOperator(std::function<gpu::TexturePointer(const QUuid&)> textureForUUIDOperator) {
_unboundTextureForUUIDOperator = textureForUUIDOperator;
}

View file

@ -41,7 +41,7 @@ public:
gpu::TextureSourcePointer _textureSource; gpu::TextureSourcePointer _textureSource;
static std::function<gpu::TexturePointer()> getTextureForUUIDOperator(const QUuid& uuid); static std::function<gpu::TexturePointer()> getTextureForUUIDOperator(const QUuid& uuid);
static void setUnboundTextureForUUIDOperator(std::function<gpu::TexturePointer(const QUuid&)> textureForUUIDOperator) { _unboundTextureForUUIDOperator = textureForUUIDOperator; } static void setUnboundTextureForUUIDOperator(std::function<gpu::TexturePointer(const QUuid&)> textureForUUIDOperator);
private: private:
static std::function<gpu::TexturePointer(const QUuid&)> _unboundTextureForUUIDOperator; static std::function<gpu::TexturePointer(const QUuid&)> _unboundTextureForUUIDOperator;

View file

@ -40,7 +40,7 @@ const size_t MAX_PROCEDURAL_TEXTURE_CHANNELS{ 4 };
* If a procedural material contains a vertex shader, the bounding box of the material entity is used to cull the object to which the material is applied. * If a procedural material contains a vertex shader, the bounding box of the material entity is used to cull the object to which the material is applied.
* @property {string} fragmentShaderURL - A link to a fragment shader. Currently, only GLSL shaders are supported. The shader must implement a different method depending on the version. * @property {string} fragmentShaderURL - A link to a fragment shader. Currently, only GLSL shaders are supported. The shader must implement a different method depending on the version.
* <code>shaderUrl</code> is an alias. * <code>shaderUrl</code> is an alias.
* @property {string[]} channels=[] - An array of input texture URLs or entity IDs. Currently, up to 4 are supported. * @property {string[]} channels=[] - An array of input texture URLs or entity IDs. Currently, up to 4 are supported. An entity ID may be that of an Image or a Web entity.
* @property {ProceduralUniforms} uniforms={} - A {@link ProceduralUniforms} object containing all the custom uniforms to be passed to the shader. * @property {ProceduralUniforms} uniforms={} - A {@link ProceduralUniforms} object containing all the custom uniforms to be passed to the shader.
*/ */

View file

@ -18,157 +18,216 @@ ReferenceMaterial::ReferenceMaterial(QUuid uuid) :
} }
// Material // Material
const graphics::MaterialKey& ReferenceMaterial::getKey() const { graphics::MaterialKey ReferenceMaterial::getKey() const {
auto material = getMaterial(); return resultWithLock<graphics::MaterialKey>([&] {
return material ? material->getKey() : Parent::getKey(); auto material = getMaterial();
return material ? material->getKey() : Parent::getKey();
});
} }
glm::vec3 ReferenceMaterial::getEmissive(bool SRGB) const { glm::vec3 ReferenceMaterial::getEmissive(bool SRGB) const {
auto material = getMaterial(); return resultWithLock<glm::vec3>([&] {
return material ? material->getEmissive(SRGB) : glm::vec3(DEFAULT_EMISSIVE); auto material = getMaterial();
return material ? material->getEmissive(SRGB) : glm::vec3(DEFAULT_EMISSIVE);
});
} }
float ReferenceMaterial::getOpacity() const { float ReferenceMaterial::getOpacity() const {
auto material = getMaterial(); return resultWithLock<float>([&] {
return material ? material->getOpacity() : DEFAULT_OPACITY; auto material = getMaterial();
return material ? material->getOpacity() : DEFAULT_OPACITY;
});
} }
graphics::MaterialKey::OpacityMapMode ReferenceMaterial::getOpacityMapMode() const { graphics::MaterialKey::OpacityMapMode ReferenceMaterial::getOpacityMapMode() const {
auto material = getMaterial(); return resultWithLock<graphics::MaterialKey::OpacityMapMode>([&] {
return material ? material->getOpacityMapMode() : DEFAULT_OPACITY_MAP_MODE; auto material = getMaterial();
return material ? material->getOpacityMapMode() : DEFAULT_OPACITY_MAP_MODE;
});
} }
float ReferenceMaterial::getOpacityCutoff() const { float ReferenceMaterial::getOpacityCutoff() const {
auto material = getMaterial(); return resultWithLock<float>([&] {
return material ? material->getOpacityCutoff() : DEFAULT_OPACITY_CUTOFF; auto material = getMaterial();
return material ? material->getOpacityCutoff() : DEFAULT_OPACITY_CUTOFF;
});
} }
graphics::MaterialKey::CullFaceMode ReferenceMaterial::getCullFaceMode() const { graphics::MaterialKey::CullFaceMode ReferenceMaterial::getCullFaceMode() const {
auto material = getMaterial(); return resultWithLock<graphics::MaterialKey::CullFaceMode>([&] {
return material ? material->getCullFaceMode() : DEFAULT_CULL_FACE_MODE; auto material = getMaterial();
return material ? material->getCullFaceMode() : DEFAULT_CULL_FACE_MODE;
});
} }
bool ReferenceMaterial::isUnlit() const { bool ReferenceMaterial::isUnlit() const {
auto material = getMaterial(); return resultWithLock<bool>([&] {
return material ? material->isUnlit() : false; auto material = getMaterial();
return material ? material->isUnlit() : false;
});
} }
glm::vec3 ReferenceMaterial::getAlbedo(bool SRGB) const { glm::vec3 ReferenceMaterial::getAlbedo(bool SRGB) const {
auto material = getMaterial(); return resultWithLock<glm::vec3>([&] {
return material ? material->getAlbedo(SRGB) : glm::vec3(DEFAULT_ALBEDO); auto material = getMaterial();
return material ? material->getAlbedo(SRGB) : glm::vec3(DEFAULT_ALBEDO);
});
} }
float ReferenceMaterial::getMetallic() const { float ReferenceMaterial::getMetallic() const {
auto material = getMaterial(); return resultWithLock<float>([&] {
return material ? material->getMetallic() : DEFAULT_METALLIC; auto material = getMaterial();
return material ? material->getMetallic() : DEFAULT_METALLIC;
});
} }
float ReferenceMaterial::getRoughness() const { float ReferenceMaterial::getRoughness() const {
auto material = getMaterial(); return resultWithLock<float>([&] {
return material ? material->getRoughness() : DEFAULT_ROUGHNESS; auto material = getMaterial();
return material ? material->getRoughness() : DEFAULT_ROUGHNESS;
});
} }
float ReferenceMaterial::getScattering() const { float ReferenceMaterial::getScattering() const {
auto material = getMaterial(); return resultWithLock<float>([&] {
return material ? material->getScattering() : DEFAULT_SCATTERING; auto material = getMaterial();
return material ? material->getScattering() : DEFAULT_SCATTERING;
});
} }
bool ReferenceMaterial::resetOpacityMap() const { bool ReferenceMaterial::resetOpacityMap() const {
auto material = getMaterial(); return resultWithLock<bool>([&] {
return material ? material->resetOpacityMap() : false; auto material = getMaterial();
return material ? material->resetOpacityMap() : false;
});
} }
const graphics::Material::TextureMaps& ReferenceMaterial::getTextureMaps() const { graphics::Material::TextureMaps ReferenceMaterial::getTextureMaps() const {
auto material = getMaterial(); return resultWithLock<graphics::Material::TextureMaps>([&] {
return material ? material->getTextureMaps() : Parent::getTextureMaps(); auto material = getMaterial();
return material ? material->getTextureMaps() : Parent::getTextureMaps();
});
} }
glm::vec2 ReferenceMaterial::getLightmapParams() const { glm::vec2 ReferenceMaterial::getLightmapParams() const {
auto material = getMaterial(); return resultWithLock<glm::vec2>([&] {
return material ? material->getLightmapParams() : glm::vec2(0.0f, 1.0f); auto material = getMaterial();
return material ? material->getLightmapParams() : glm::vec2(0.0f, 1.0f);
});
} }
bool ReferenceMaterial::getDefaultFallthrough() const { bool ReferenceMaterial::getDefaultFallthrough() const {
auto material = getMaterial(); return resultWithLock<bool>([&] {
return material ? material->getDefaultFallthrough() : false; auto material = getMaterial();
return material ? material->getDefaultFallthrough() : false;
});
} }
// NetworkMaterial // NetworkMaterial
bool ReferenceMaterial::isMissingTexture() { bool ReferenceMaterial::isMissingTexture() {
auto material = getNetworkMaterial(); return resultWithLock<bool>([&] {
return material ? material->isMissingTexture() : false; auto material = getNetworkMaterial();
return material ? material->isMissingTexture() : false;
});
} }
bool ReferenceMaterial::checkResetOpacityMap() { bool ReferenceMaterial::checkResetOpacityMap() {
auto material = getNetworkMaterial(); return resultWithLock<bool>([&] {
return material ? material->checkResetOpacityMap() : false; auto material = getNetworkMaterial();
return material ? material->checkResetOpacityMap() : false;
});
} }
// ProceduralMaterial // ProceduralMaterial
bool ReferenceMaterial::isProcedural() const { bool ReferenceMaterial::isProcedural() const {
auto material = getMaterial(); return resultWithLock<bool>([&] {
return material ? material->isProcedural() : false; auto material = getMaterial();
return material ? material->isProcedural() : false;
});
} }
bool ReferenceMaterial::isEnabled() const { bool ReferenceMaterial::isEnabled() const {
auto material = getMaterial(); return resultWithLock<bool>([&] {
return material ? material->isEnabled() : false; auto material = getMaterial();
return material ? material->isEnabled() : false;
});
} }
bool ReferenceMaterial::isReady() const { bool ReferenceMaterial::isReady() const {
auto material = getMaterial(); return resultWithLock<bool>([&] {
return material ? material->isReady() : false; auto material = getMaterial();
return material ? material->isReady() : false;
});
} }
QString ReferenceMaterial::getProceduralString() const { QString ReferenceMaterial::getProceduralString() const {
auto material = getMaterial(); return resultWithLock<QString>([&] {
return material ? material->getProceduralString() : QString(); auto material = getMaterial();
return material ? material->getProceduralString() : QString();
});
} }
glm::vec4 ReferenceMaterial::getColor(const glm::vec4& color) const { glm::vec4 ReferenceMaterial::getColor(const glm::vec4& color) const {
auto material = getProceduralMaterial(); return resultWithLock<glm::vec4>([&] {
return material ? material->getColor(color) : glm::vec4(); auto material = getProceduralMaterial();
return material ? material->getColor(color) : glm::vec4();
});
} }
bool ReferenceMaterial::isFading() const { bool ReferenceMaterial::isFading() const {
auto material = getProceduralMaterial(); return resultWithLock<bool>([&] {
return material ? material->isFading() : false; auto material = getProceduralMaterial();
return material ? material->isFading() : false;
});
} }
uint64_t ReferenceMaterial::getFadeStartTime() const { uint64_t ReferenceMaterial::getFadeStartTime() const {
auto material = getProceduralMaterial(); return resultWithLock<uint64_t>([&] {
return material ? material->getFadeStartTime() : 0; auto material = getProceduralMaterial();
return material ? material->getFadeStartTime() : 0;
});
} }
bool ReferenceMaterial::hasVertexShader() const { bool ReferenceMaterial::hasVertexShader() const {
auto material = getProceduralMaterial(); return resultWithLock<bool>([&] {
return material ? material->hasVertexShader() : false; 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, 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) { const uint64_t& created, const ProceduralProgramKey key) {
if (auto material = getProceduralMaterial()) { withLock([&] {
material->prepare(batch, position, size, orientation, created, key); if (auto material = getProceduralMaterial()) {
} material->prepare(batch, position, size, orientation, created, key);
}
});
} }
void ReferenceMaterial::initializeProcedural() { void ReferenceMaterial::initializeProcedural() {
if (auto material = getProceduralMaterial()) { withLock([&] {
material->initializeProcedural(); if (auto material = getProceduralMaterial()) {
} material->initializeProcedural();
}
});
}
void ReferenceMaterial::setMaterialForUUIDOperator(std::function<graphics::MaterialPointer(QUuid)> materialForUUIDOperator) {
_unboundMaterialForUUIDOperator = materialForUUIDOperator;
} }
graphics::MaterialPointer ReferenceMaterial::getMaterial() const { graphics::MaterialPointer ReferenceMaterial::getMaterial() const {
if (_materialForUUIDOperator) { if (_materialForUUIDOperator) {
return _materialForUUIDOperator(); auto material = _materialForUUIDOperator();
return material;
} }
return nullptr; return nullptr;
} }
std::shared_ptr<NetworkMaterial> ReferenceMaterial::getNetworkMaterial() const { std::shared_ptr<NetworkMaterial> ReferenceMaterial::getNetworkMaterial() const {
if (_materialForUUIDOperator) { if (_materialForUUIDOperator) {
auto material = _materialForUUIDOperator(); std::shared_ptr<NetworkMaterial> result = nullptr;
if (material && material->isProcedural()) { if (auto material = _materialForUUIDOperator()) {
return std::static_pointer_cast<NetworkMaterial>(material); return std::static_pointer_cast<NetworkMaterial>(material);
} }
} }
@ -184,3 +243,24 @@ graphics::ProceduralMaterialPointer ReferenceMaterial::getProceduralMaterial() c
} }
return nullptr; return nullptr;
} }
template <typename T, typename F>
inline T ReferenceMaterial::resultWithLock(F&& f) const {
if (_locked) {
return T();
} else {
_locked = true;
T result = f();
_locked = false;
return result;
}
}
template <typename F>
inline void ReferenceMaterial::withLock(F&& f) const {
if (!_locked) {
_locked = true;
f();
_locked = false;
}
}

View file

@ -18,7 +18,7 @@ public:
ReferenceMaterial(QUuid uuid); ReferenceMaterial(QUuid uuid);
// Material // Material
const graphics::MaterialKey& getKey() const override; graphics::MaterialKey getKey() const override;
glm::vec3 getEmissive(bool SRGB = true) const override; glm::vec3 getEmissive(bool SRGB = true) const override;
float getOpacity() const override; float getOpacity() const override;
graphics::MaterialKey::OpacityMapMode getOpacityMapMode() const override; graphics::MaterialKey::OpacityMapMode getOpacityMapMode() const override;
@ -30,10 +30,8 @@ public:
float getRoughness() const override; float getRoughness() const override;
float getScattering() const override; float getScattering() const override;
bool resetOpacityMap() const override; bool resetOpacityMap() const override;
const graphics::Material::TextureMaps& getTextureMaps() const override; 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 getLightmapParams() const override;
//glm::vec2 getMaterialParams() const override; // use my actual params, instead of the original
bool getDefaultFallthrough() const override; bool getDefaultFallthrough() const override;
// NetworkMaterial // NetworkMaterial
@ -57,13 +55,20 @@ public:
bool isReference() const override { return true; } bool isReference() const override { return true; }
std::function<graphics::MaterialPointer()> getReferenceOperator() const { return _materialForUUIDOperator; } std::function<graphics::MaterialPointer()> getReferenceOperator() const { return _materialForUUIDOperator; }
static void setMaterialForUUIDOperator(std::function<graphics::MaterialPointer(QUuid)> materialForUUIDOperator) { _unboundMaterialForUUIDOperator = materialForUUIDOperator; } static void setMaterialForUUIDOperator(std::function<graphics::MaterialPointer(QUuid)> materialForUUIDOperator);
private: private:
static std::function<graphics::MaterialPointer(QUuid)> _unboundMaterialForUUIDOperator; static std::function<graphics::MaterialPointer(QUuid)> _unboundMaterialForUUIDOperator;
std::function<graphics::MaterialPointer()> _materialForUUIDOperator; std::function<graphics::MaterialPointer()> _materialForUUIDOperator;
mutable bool _locked { false };
graphics::MaterialPointer getMaterial() const; graphics::MaterialPointer getMaterial() const;
std::shared_ptr<NetworkMaterial> getNetworkMaterial() const; std::shared_ptr<NetworkMaterial> getNetworkMaterial() const;
graphics::ProceduralMaterialPointer getProceduralMaterial() const; graphics::ProceduralMaterialPointer getProceduralMaterial() const;
template <typename T, typename F>
T resultWithLock(F&& f) const;
template <typename F>
void withLock(F&& f) const;
}; };

View file

@ -415,8 +415,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} }
bool defaultFallthrough = material->getDefaultFallthrough(); bool defaultFallthrough = material->getDefaultFallthrough();
const auto& materialKey = material->getKey(); const auto materialKey = material->getKey();
const auto& textureMaps = material->getTextureMaps(); const auto textureMaps = material->getTextureMaps();
auto it = flagsToCheck.begin(); auto it = flagsToCheck.begin();
while (it != flagsToCheck.end()) { while (it != flagsToCheck.end()) {