diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 6525286e04..bb8f74aec1 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -616,24 +616,28 @@ Item::Bound EntityRenderer::getMaterialBound(RenderArgs* args) { return EntityRenderer::getBound(args); } -EntityRenderer::MaterialMap::iterator EntityRenderer::getAndUpdateMaterials() { - std::lock_guard lock(_materialsLock); - auto materials = _materials.find("0"); - if (materials != _materials.end() && materials->second.shouldUpdate()) { - RenderPipelines::updateMultiMaterial(materials->second); - } - - return materials; -} - -void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder, MaterialMap::iterator materials) const { +void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder) { + MaterialMap::iterator materials; { std::lock_guard lock(_materialsLock); - if (materials == _materials.end()) { + materials = _materials.find("0"); + if (materials != _materials.end()) { + if (materials->second.shouldUpdate()) { + RenderPipelines::updateMultiMaterial(materials->second); + } + } else { return; } } + if (isTransparent()) { + builder.withTranslucent(); + } + + if (_primitiveMode == PrimitiveMode::LINES) { + builder.withWireframe(); + } + builder.withCullFaceMode(materials->second.getCullFaceMode()); graphics::MaterialKey drawMaterialKey = materials->second.getMaterialKey(); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 6bf145c4e7..11aca9230c 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -131,8 +131,7 @@ protected: void updateMaterials(bool baseMaterialChanged = false); bool materialsTransparent() const; Item::Bound getMaterialBound(RenderArgs* args); - MaterialMap::iterator getAndUpdateMaterials(); - void updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder, MaterialMap::iterator materials) const; + void updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder); Item::Bound _bound; SharedSoundPointer _collisionSound; diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp index 176cca729d..2a3d71f048 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -232,19 +232,7 @@ Item::Bound GizmoEntityRenderer::getBound(RenderArgs* args) { ShapeKey GizmoEntityRenderer::getShapeKey() { auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); - - auto mat = getAndUpdateMaterials(); - - if (isTransparent()) { - builder.withTranslucent(); - } - - if (_primitiveMode == PrimitiveMode::LINES) { - builder.withUnlit().withWireframe(); - } - - updateShapeKeyBuilderFromMaterials(builder, mat); - + updateShapeKeyBuilderFromMaterials(builder); return builder.build(); } @@ -287,7 +275,7 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) { auto procedural = std::static_pointer_cast(materials.top().material); transparent |= procedural->isFading(); procedural->prepare(batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, ProceduralProgramKey(transparent)); - } else { + } else if (pipelineType == Pipeline::MATERIAL) { if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) { args->_details._materialSwitches++; } diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp index ab56798e4f..587b20543c 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp @@ -101,19 +101,7 @@ Item::Bound ImageEntityRenderer::getBound(RenderArgs* args) { ShapeKey ImageEntityRenderer::getShapeKey() { auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); - - auto mat = getAndUpdateMaterials(); - - if (isTransparent()) { - builder.withTranslucent(); - } - - if (_primitiveMode == PrimitiveMode::LINES) { - builder.withWireframe(); - } - - updateShapeKeyBuilderFromMaterials(builder, mat); - + updateShapeKeyBuilderFromMaterials(builder); return builder.build(); } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 86d178aa43..2398d079b4 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -88,19 +88,7 @@ Item::Bound ShapeEntityRenderer::getBound(RenderArgs* args) { ShapeKey ShapeEntityRenderer::getShapeKey() { ShapeKey::Builder builder; - - auto mat = getAndUpdateMaterials(); - - if (isTransparent()) { - builder.withTranslucent(); - } - - if (_primitiveMode == PrimitiveMode::LINES) { - builder.withWireframe(); - } - - updateShapeKeyBuilderFromMaterials(builder, mat); - + updateShapeKeyBuilderFromMaterials(builder); return builder.build(); } @@ -157,7 +145,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; bool forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD; if (outColor.a >= 1.0f) { - render::ShapePipelinePointer pipeline = geometryCache->getShapePipelinePointer(false, wireframe, + render::ShapePipelinePointer pipeline = geometryCache->getShapePipelinePointer(false, wireframe || materials.top().material->isUnlit(), forward, materials.top().material->getCullFaceMode()); if (wireframe) { geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline); diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 16d9afb913..909a36c1f8 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -20,6 +20,7 @@ #include "GLMHelpers.h" #include "DeferredLightingEffect.h" +#include "RenderPipelines.h" using namespace render; using namespace render::entities; @@ -35,6 +36,8 @@ TextEntityRenderer::TextEntityRenderer(const EntityItemPointer& entity) : if (geometryCache) { _geometryID = geometryCache->allocateID(); } + _material->setCullFaceMode(graphics::MaterialKey::CullFaceMode::CULL_NONE); + addMaterial(graphics::MaterialLayer(_material, 0), "0"); } TextEntityRenderer::~TextEntityRenderer() { @@ -44,41 +47,8 @@ TextEntityRenderer::~TextEntityRenderer() { } } -bool TextEntityRenderer::isTransparent() const { - return Parent::isTransparent() || _backgroundAlpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; -} - -bool TextEntityRenderer::isTextTransparent() const { - return resultWithReadLock([&] { - return Parent::isTransparent() || _textAlpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; - }); -} - -ItemKey TextEntityRenderer::getKey() { - return ItemKey::Builder(Parent::getKey()).withMetaCullGroup(); -} - -ShapeKey TextEntityRenderer::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace(); - if (isTransparent()) { - builder.withTranslucent(); - } - if (_unlit) { - builder.withUnlit(); - } - if (_primitiveMode == PrimitiveMode::LINES) { - builder.withWireframe(); - } - return builder.build(); -} - -uint32_t TextEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const { - auto parentSubs = Parent::metaFetchMetaSubItems(subItems); - if (Item::isValidID(_textRenderID)) { - subItems.emplace_back(_textRenderID); - return parentSubs + 1; - } - return parentSubs; +bool TextEntityRenderer::needsRenderUpdate() const { + return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate(); } void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { @@ -98,57 +68,121 @@ void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe _lineHeight = entity->getLineHeight(); _textColor = toGlm(entity->getTextColor()); _textAlpha = entity->getTextAlpha(); - _backgroundColor = toGlm(entity->getBackgroundColor()); - _backgroundAlpha = entity->getBackgroundAlpha(); _leftMargin = entity->getLeftMargin(); _rightMargin = entity->getRightMargin(); _topMargin = entity->getTopMargin(); _bottomMargin = entity->getBottomMargin(); - _unlit = entity->getUnlit(); _font = entity->getFont(); _effect = entity->getTextEffect(); _effectColor = toGlm(entity->getTextEffectColor()); _effectThickness = entity->getTextEffectThickness(); + + bool materialChanged = false; + glm::vec3 color = toGlm(entity->getBackgroundColor()); + if (_backgroundColor != color) { + _backgroundColor = color; + _material->setAlbedo(color); + materialChanged = true; + } + + float alpha = entity->getBackgroundAlpha(); + if (_backgroundAlpha != alpha) { + _backgroundAlpha = alpha; + _material->setOpacity(alpha); + materialChanged = true; + } + + auto unlit = entity->getUnlit(); + if (_unlit != unlit) { + _unlit = unlit; + _material->setUnlit(_unlit); + materialChanged = true; + } + + updateMaterials(materialChanged); + updateTextRenderItem(); } +bool TextEntityRenderer::isTransparent() const { + bool backgroundTransparent = _backgroundAlpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; + return backgroundTransparent || Parent::isTransparent() || materialsTransparent(); +} + +bool TextEntityRenderer::isTextTransparent() const { + return Parent::isTransparent() || _textAlpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; +} + +Item::Bound TextEntityRenderer::getBound(RenderArgs* args) { + return Parent::getMaterialBound(args); +} + +ItemKey TextEntityRenderer::getKey() { + return ItemKey::Builder(Parent::getKey()).withMetaCullGroup(); +} + +ShapeKey TextEntityRenderer::getShapeKey() { + auto builder = render::ShapeKey::Builder(); + updateShapeKeyBuilderFromMaterials(builder); + return builder.build(); +} + +uint32_t TextEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const { + auto parentSubs = Parent::metaFetchMetaSubItems(subItems); + if (Item::isValidID(_textRenderID)) { + subItems.emplace_back(_textRenderID); + return parentSubs + 1; + } + return parentSubs; +} + void TextEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableTextEntityItem::render"); Q_ASSERT(args->_batch); - gpu::Batch& batch = *args->_batch; - glm::vec4 backgroundColor; - Transform transform; - withReadLock([&] { - transform = _renderTransform; + graphics::MultiMaterial materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials["0"]; + } - float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; - backgroundColor = glm::vec4(_backgroundColor, fadeRatio * _backgroundAlpha); - }); + auto& schema = materials.getSchemaBuffer().get(); + glm::vec4 backgroundColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity); backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created); if (backgroundColor.a <= 0.0f) { return; } + gpu::Batch& batch = *args->_batch; + + bool transparent; + Transform transform; + withReadLock([&] { + transparent = isTransparent(); + transform = _renderTransform; + }); + transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition())); batch.setModelTransform(transform); - auto geometryCache = DependencyManager::get(); - // FIXME: we want to use instanced rendering here, but if textAlpha < 1 and backgroundAlpha < 1, the transparency sorting will be wrong - //render::ShapePipelinePointer pipeline = geometryCache->getShapePipelinePointer(backgroundColor.a < 1.0f, _unlit, - // _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD); - //if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) { - // geometryCache->renderWireShapeInstance(args, batch, GeometryCache::Quad, backgroundColor, pipeline); - //} else { - // geometryCache->renderSolidShapeInstance(args, batch, GeometryCache::Quad, backgroundColor, pipeline); - //} + Pipeline pipelineType = getPipelineType(materials); + if (pipelineType == Pipeline::PROCEDURAL) { + auto procedural = std::static_pointer_cast(materials.top().material); + transparent |= procedural->isFading(); + procedural->prepare(batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, ProceduralProgramKey(transparent)); + } else if (pipelineType == Pipeline::MATERIAL) { + if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) { + args->_details._materialSwitches++; + } + } + auto geometryCache = DependencyManager::get(); geometryCache->renderQuad(batch, glm::vec2(-0.5), glm::vec2(0.5), backgroundColor, _geometryID); - const int TRIANBLES_PER_QUAD = 2; - args->_details._trianglesRendered += TRIANBLES_PER_QUAD; + const int TRIANGLES_PER_QUAD = 2; + args->_details._trianglesRendered += TRIANGLES_PER_QUAD; } QSizeF TextEntityRenderer::textSize(const QString& text) const { diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index 0f736d1229..60e4eccd42 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -14,6 +14,8 @@ #include "RenderableEntityItem.h" +#include + class TextEntityItem; class TextRenderer3D; @@ -33,6 +35,7 @@ public: protected: bool isTransparent() const override; bool isTextTransparent() const; + Item::Bound getBound(RenderArgs* args) override; ShapeKey getShapeKey() override; ItemKey getKey() override; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) const override; @@ -41,6 +44,7 @@ protected: void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; private: + virtual bool needsRenderUpdate() const; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; @@ -53,10 +57,12 @@ private: float _lineHeight; glm::vec3 _textColor; float _textAlpha; - glm::vec3 _backgroundColor; - float _backgroundAlpha; bool _unlit; + std::shared_ptr _material { std::make_shared() }; + glm::vec3 _backgroundColor { NAN }; + float _backgroundAlpha { NAN }; + float _leftMargin; float _rightMargin; float _topMargin;