From 25e4f59d55800abb16db2c87f7e0fc484cc80b4c Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Tue, 23 Feb 2021 20:54:57 -0800 Subject: [PATCH 1/7] gizmos have materials, working on images --- .../src/RenderableEntityItem.cpp | 172 +++++++++++++++++- .../src/RenderableEntityItem.h | 19 +- .../src/RenderableGizmoEntityItem.cpp | 55 +++++- .../src/RenderableGizmoEntityItem.h | 4 + .../src/RenderableImageEntityItem.cpp | 16 +- .../src/RenderableImageEntityItem.h | 2 + .../src/RenderableShapeEntityItem.cpp | 163 ++++------------- .../src/RenderableShapeEntityItem.h | 3 - 8 files changed, 286 insertions(+), 148 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index b2670e3bce..6fb4be7025 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -29,6 +29,8 @@ #include "RenderableZoneEntityItem.h" #include "RenderableMaterialEntityItem.h" +#include "RenderPipelines.h" + using namespace render; using namespace render::entities; @@ -149,10 +151,11 @@ Item::Bound EntityRenderer::getBound(RenderArgs* args) { } ShapeKey EntityRenderer::getShapeKey() { + ShapeKey::Builder builder = ShapeKey::Builder().withOwnPipeline(); if (_primitiveMode == PrimitiveMode::LINES) { - return ShapeKey::Builder().withOwnPipeline().withWireframe(); + builder.withWireframe(); } - return ShapeKey::Builder().withOwnPipeline(); + return builder.build(); } render::hifi::Tag EntityRenderer::getTagMask() const { @@ -365,6 +368,7 @@ bool EntityRenderer::needsRenderUpdate() const { if (_prevIsTransparent != isTransparent()) { return true; } + return needsRenderUpdateFromEntity(_entity); } @@ -486,6 +490,170 @@ void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const st emit requestRenderUpdate(); } +EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMaterial& materials) { + if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) { + return Pipeline::PROCEDURAL; + } + + graphics::MaterialKey drawMaterialKey = materials.getMaterialKey(); + if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) { + return Pipeline::MATERIAL; + } + + // If the material is using any map, we need to use a material ShapeKey + for (int i = 0; i < graphics::Material::MapChannel::NUM_MAP_CHANNELS; i++) { + if (drawMaterialKey.isMapChannel(graphics::Material::MapChannel(i))) { + return Pipeline::MATERIAL; + } + } + return Pipeline::SIMPLE; +} + +bool EntityRenderer::needsRenderUpdateFromMaterials() const { + MaterialMap::const_iterator materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials.find("0"); + + if (materials == _materials.cend()) { + return false; + } + } + + if (materials->second.shouldUpdate()) { + return true; + } + + if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + auto procedural = std::static_pointer_cast(materials->second.top().material); + if (procedural->isFading()) { + return true; + } + } + + return false; +} + +void EntityRenderer::updateMaterials(bool baseMaterialChanged) { + MaterialMap::iterator materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials.find("0"); + + if (materials == _materials.end()) { + return; + } + } + + if (baseMaterialChanged) { + materials->second.setNeedsUpdate(true); + } + + bool requestUpdate = false; + if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + auto procedural = std::static_pointer_cast(materials->second.top().material); + if (procedural->isFading()) { + procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f); + requestUpdate = true; + } + } + + if (materials->second.shouldUpdate()) { + RenderPipelines::updateMultiMaterial(materials->second); + requestUpdate = true; + } + + if (requestUpdate) { + emit requestRenderUpdate(); + } +} + +bool EntityRenderer::materialsTransparent() const { + MaterialMap::const_iterator materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials.find("0"); + + if (materials == _materials.cend()) { + return false; + } + } + + if (materials->second.top().material) { + if (materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + auto procedural = std::static_pointer_cast(materials->second.top().material); + if (procedural->isFading()) { + return true; + } + } + + if (materials->second.getMaterialKey().isTranslucent()) { + return true; + } + } + + return false; +} + +Item::Bound EntityRenderer::getMaterialBound(RenderArgs* args) { + MaterialMap::iterator materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials.find("0"); + + if (materials == _materials.end()) { + return EntityRenderer::getBound(args); + } + } + + if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + auto procedural = std::static_pointer_cast(materials->second.top().material); + if (procedural->hasVertexShader() && procedural->hasBoundOperator()) { + return procedural->getBound(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 { + { + std::lock_guard lock(_materialsLock); + if (materials == _materials.end()) { + return; + } + } + + builder.withCullFaceMode(materials->second.getCullFaceMode()); + auto pipelineType = getPipelineType(materials->second); + if (pipelineType == Pipeline::MATERIAL) { + builder.withMaterial(); + + graphics::MaterialKey drawMaterialKey = materials->second.getMaterialKey(); + if (drawMaterialKey.isNormalMap()) { + builder.withTangents(); + } + if (drawMaterialKey.isLightMap()) { + builder.withLightMap(); + } + if (drawMaterialKey.isUnlit()) { + builder.withUnlit(); + } + } else if (pipelineType == Pipeline::PROCEDURAL) { + builder.withOwnPipeline(); + } +} + glm::vec4 EntityRenderer::calculatePulseColor(const glm::vec4& color, const PulsePropertyGroup& pulseProperties, quint64 start) { if (pulseProperties.getPeriod() == 0.0f || (pulseProperties.getColorMode() == PulseMode::NONE && pulseProperties.getAlphaMode() == PulseMode::NONE)) { return color; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 7f0e1e16ee..6bf145c4e7 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -55,8 +55,14 @@ public: const uint64_t& getUpdateTime() const { return _updateTime; } + enum class Pipeline { + SIMPLE, + MATERIAL, + PROCEDURAL + }; virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName); virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName); + static Pipeline getPipelineType(const graphics::MultiMaterial& materials); virtual scriptable::ScriptableModelBase getScriptableModel() override { return scriptable::ScriptableModelBase(); } @@ -119,6 +125,15 @@ protected: static void makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters); const Transform& getModelTransform() const; + // Shared methods for entities that support materials + using MaterialMap = std::unordered_map; + bool needsRenderUpdateFromMaterials() const; + 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; + Item::Bound _bound; SharedSoundPointer _collisionSound; QUuid _changeHandlerId; @@ -139,8 +154,8 @@ protected: bool _moving { false }; Transform _renderTransform; - std::unordered_map _materials; - std::mutex _materialsLock; + MaterialMap _materials; + mutable std::mutex _materialsLock; quint64 _created; diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp index bf005ae2e5..1d4c238148 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -11,10 +11,15 @@ #include #include +#include "RenderPipelines.h" + using namespace render; using namespace render::entities; -GizmoEntityRenderer::GizmoEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {} +GizmoEntityRenderer::GizmoEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { + _material->setCullFaceMode(graphics::MaterialKey::CullFaceMode::CULL_NONE); + addMaterial(graphics::MaterialLayer(_material, 0), "0"); +} GizmoEntityRenderer::~GizmoEntityRenderer() { auto geometryCache = DependencyManager::get(); @@ -31,12 +36,8 @@ GizmoEntityRenderer::~GizmoEntityRenderer() { } } -bool GizmoEntityRenderer::isTransparent() const { - bool ringTransparent = _gizmoType == GizmoType::RING && (_ringProperties.getInnerStartAlpha() < 1.0f || - _ringProperties.getInnerEndAlpha() < 1.0f || _ringProperties.getOuterStartAlpha() < 1.0f || - _ringProperties.getOuterEndAlpha() < 1.0f); - - return Parent::isTransparent() || ringTransparent; +bool GizmoEntityRenderer::needsRenderUpdate() const { + return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate(); } void GizmoEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { @@ -193,10 +194,20 @@ void GizmoEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint } } } + + updateMaterials(); +} + +bool GizmoEntityRenderer::isTransparent() const { + bool ringTransparent = _gizmoType == GizmoType::RING && (_ringProperties.getInnerStartAlpha() < 1.0f || + _ringProperties.getInnerEndAlpha() < 1.0f || _ringProperties.getOuterStartAlpha() < 1.0f || + _ringProperties.getOuterEndAlpha() < 1.0f); + + return ringTransparent || Parent::isTransparent() || materialsTransparent(); } Item::Bound GizmoEntityRenderer::getBound(RenderArgs* args) { - auto bound = Parent::getBound(args); + auto bound = Parent::getMaterialBound(args); if (_ringProperties.getHasTickMarks()) { glm::vec3 scale = bound.getScale(); for (int i = 0; i < 3; i += 2) { @@ -221,12 +232,19 @@ Item::Bound GizmoEntityRenderer::getBound(RenderArgs* args) { ShapeKey GizmoEntityRenderer::getShapeKey() { auto builder = render::ShapeKey::Builder().withoutCullFace(); + + auto mat = getAndUpdateMaterials(); + if (isTransparent()) { builder.withTranslucent(); } + if (_primitiveMode == PrimitiveMode::LINES) { - builder.withUnlit().withDepthBias(); + builder.withUnlit().withDepthBias().withWireframe(); } + + updateShapeKeyBuilderFromMaterials(builder, mat); + return builder.build(); } @@ -249,15 +267,32 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) { transparent = isTransparent(); }); + graphics::MultiMaterial materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials["0"]; + } + bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; bool forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD; - geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE); + //geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, materials.getCullFaceMode()); transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), true)); batch.setModelTransform(transform); + 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 (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) { + args->_details._materialSwitches++; + } + } + // Background circle geometryCache->renderVertices(batch, wireframe ? gpu::LINE_STRIP : _solidPrimitive, _ringGeometryID); diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.h b/libraries/entities-renderer/src/RenderableGizmoEntityItem.h index 6a09d1a047..b6c22b19de 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.h +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.h @@ -13,6 +13,8 @@ #include +#include + namespace render { namespace entities { class GizmoEntityRenderer : public TypedEntityRenderer { @@ -29,10 +31,12 @@ protected: bool isTransparent() const override; private: + virtual bool needsRenderUpdate() const override; 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; + std::shared_ptr _material { std::make_shared() }; GizmoType _gizmoType { UNSET_GIZMO_TYPE }; RingGizmoPropertyGroup _ringProperties; PrimitiveMode _prevPrimitiveMode; diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp index e03655f09c..d96c948d7d 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp @@ -25,8 +25,8 @@ ImageEntityRenderer::~ImageEntityRenderer() { } } -bool ImageEntityRenderer::isTransparent() const { - return Parent::isTransparent() || (_textureIsLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha()) || _alpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; +bool ImageEntityRenderer::needsRenderUpdate() const { + return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate(); } void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { @@ -63,6 +63,18 @@ void ImageEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint emit requestRenderUpdate(); } _textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed()); + + updateMaterials(); +} + +bool ImageEntityRenderer::isTransparent() const { + bool imageTransparent = _alpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE || + (_textureIsLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha()); + return imageTransparent || Parent::isTransparent() || materialsTransparent(); +} + +Item::Bound ImageEntityRenderer::getBound(RenderArgs* args) { + return Parent::getMaterialBound(args); } ShapeKey ImageEntityRenderer::getShapeKey() { diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.h b/libraries/entities-renderer/src/RenderableImageEntityItem.h index 2359dcc6d1..ca4173d938 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.h +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.h @@ -23,11 +23,13 @@ public: ~ImageEntityRenderer(); protected: + Item::Bound getBound(RenderArgs* args) override; ShapeKey getShapeKey() override; bool isTransparent() const override; private: + virtual bool needsRenderUpdate() const override; 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; diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 674d7c297d..496d933889 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -29,26 +29,7 @@ ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Pare } bool ShapeEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([&] { - auto mat = _materials.find("0"); - if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && - mat->second.top().material->isReady()) { - auto procedural = std::static_pointer_cast(mat->second.top().material); - if (procedural->isFading()) { - return true; - } - } - - if (mat != _materials.end() && mat->second.shouldUpdate()) { - return true; - } - - return false; - })) { - return true; - } - - return Parent::needsRenderUpdate(); + return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate(); } void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { @@ -94,81 +75,21 @@ void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint materialChanged = true; } - withReadLock([&] { - auto materials = _materials.find("0"); - if (materials != _materials.end()) { - if (materialChanged) { - materials->second.setNeedsUpdate(true); - } - - bool requestUpdate = false; - if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { - auto procedural = std::static_pointer_cast(materials->second.top().material); - if (procedural->isFading()) { - procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f); - requestUpdate = true; - } - } - - if (materials->second.shouldUpdate()) { - RenderPipelines::updateMultiMaterial(materials->second); - requestUpdate = true; - } - - if (requestUpdate) { - emit requestRenderUpdate(); - } - } - }); + updateMaterials(materialChanged); } bool ShapeEntityRenderer::isTransparent() const { - if (_pulseProperties.getAlphaMode() != PulseMode::NONE) { - return true; - } - - auto mat = _materials.find("0"); - if (mat != _materials.end() && mat->second.top().material) { - if (mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) { - auto procedural = std::static_pointer_cast(mat->second.top().material); - if (procedural->isFading()) { - return true; - } - } - - if (mat->second.getMaterialKey().isTranslucent()) { - return true; - } - } - - return Parent::isTransparent(); + return _pulseProperties.getAlphaMode() != PulseMode::NONE || Parent::isTransparent() || materialsTransparent(); } -ShapeEntityRenderer::Pipeline ShapeEntityRenderer::getPipelineType(const graphics::MultiMaterial& materials) const { - if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) { - return Pipeline::PROCEDURAL; - } - - graphics::MaterialKey drawMaterialKey = materials.getMaterialKey(); - if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) { - return Pipeline::MATERIAL; - } - - // If the material is using any map, we need to use a material ShapeKey - for (int i = 0; i < graphics::Material::MapChannel::NUM_MAP_CHANNELS; i++) { - if (drawMaterialKey.isMapChannel(graphics::Material::MapChannel(i))) { - return Pipeline::MATERIAL; - } - } - return Pipeline::SIMPLE; +Item::Bound ShapeEntityRenderer::getBound(RenderArgs* args) { + return Parent::getMaterialBound(args); } ShapeKey ShapeEntityRenderer::getShapeKey() { ShapeKey::Builder builder; - auto mat = _materials.find("0"); - if (mat != _materials.end() && mat->second.shouldUpdate()) { - RenderPipelines::updateMultiMaterial(mat->second); - } + + auto mat = getAndUpdateMaterials(); if (isTransparent()) { builder.withTranslucent(); @@ -178,71 +99,46 @@ ShapeKey ShapeEntityRenderer::getShapeKey() { builder.withWireframe(); } - auto pipelineType = getPipelineType(mat->second); - if (pipelineType == Pipeline::MATERIAL) { - builder.withMaterial(); - - graphics::MaterialKey drawMaterialKey = mat->second.getMaterialKey(); - if (drawMaterialKey.isNormalMap()) { - builder.withTangents(); - } - if (drawMaterialKey.isLightMap()) { - builder.withLightMap(); - } - if (drawMaterialKey.isUnlit()) { - builder.withUnlit(); - } - builder.withCullFaceMode(mat->second.getCullFaceMode()); - } else if (pipelineType == Pipeline::PROCEDURAL) { - builder.withOwnPipeline(); - } + updateShapeKeyBuilderFromMaterials(builder, mat); return builder.build(); } -Item::Bound ShapeEntityRenderer::getBound(RenderArgs* args) { - auto mat = _materials.find("0"); - if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && - mat->second.top().material->isReady()) { - auto procedural = std::static_pointer_cast(mat->second.top().material); - if (procedural->hasVertexShader() && procedural->hasBoundOperator()) { - return procedural->getBound(args); - } - } - return Parent::getBound(args); -} - void ShapeEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableShapeEntityItem::render"); Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - graphics::MultiMaterial materials; auto geometryCache = DependencyManager::get(); GeometryCache::Shape geometryShape = geometryCache->getShapeForEntityShape(_shape); - glm::vec4 outColor; - Pipeline pipelineType; Transform transform; withReadLock([&] { transform = _renderTransform; - materials = _materials["0"]; - pipelineType = getPipelineType(materials); - auto& schema = materials.getSchemaBuffer().get(); - outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity); }); + graphics::MultiMaterial materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials["0"]; + } + + auto& schema = materials.getSchemaBuffer().get(); + glm::vec4 outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity); outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created); if (outColor.a == 0.0f) { return; } + bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; + transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), _shape < entity::Shape::Cube || _shape > entity::Shape::Icosahedron)); batch.setModelTransform(transform); + Pipeline pipelineType = getPipelineType(materials); if (pipelineType == Pipeline::PROCEDURAL) { auto procedural = std::static_pointer_cast(materials.top().material); outColor = procedural->getColor(outColor); @@ -251,7 +147,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { procedural->prepare(batch, _position, _dimensions, _orientation, _created, ProceduralProgramKey(outColor.a < 1.0f)); }); - if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) { + if (wireframe) { geometryCache->renderWireShape(batch, geometryShape, outColor); } else { geometryCache->renderShape(batch, geometryShape, outColor); @@ -259,12 +155,21 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { } else if (pipelineType == Pipeline::SIMPLE) { // FIXME, support instanced multi-shape rendering using multidraw indirect outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; - render::ShapePipelinePointer pipeline = geometryCache->getShapePipelinePointer(outColor.a < 1.0f, false, - _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD, materials.top().material->getCullFaceMode()); - if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) { - geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline); + bool forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD; + if (outColor.a >= 1.0f) { + render::ShapePipelinePointer pipeline = geometryCache->getShapePipelinePointer(false, wireframe, + forward, materials.top().material->getCullFaceMode()); + if (wireframe) { + geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline); + } else { + geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline); + } } else { - geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline); + if (wireframe) { + geometryCache->renderWireShape(batch, geometryShape, outColor); + } else { + geometryCache->renderShape(batch, geometryShape, outColor); + } } } else { if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) { diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.h b/libraries/entities-renderer/src/RenderableShapeEntityItem.h index fe62ad48b9..b77822aa19 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.h +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.h @@ -35,9 +35,6 @@ private: virtual void doRender(RenderArgs* args) override; virtual bool isTransparent() const override; - enum Pipeline { SIMPLE, MATERIAL, PROCEDURAL }; - Pipeline getPipelineType(const graphics::MultiMaterial& materials) const; - QString _proceduralData; entity::Shape _shape { entity::Sphere }; From 186f505b157ae7468cde2d4c05deea4f0f969148 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 24 Feb 2021 20:56:14 -0800 Subject: [PATCH 2/7] images support materials --- .../src/RenderableEntityItem.cpp | 12 +-- .../src/RenderableGizmoEntityItem.cpp | 4 +- .../src/RenderableImageEntityItem.cpp | 85 ++++++++++++++----- .../src/RenderableImageEntityItem.h | 7 +- .../src/RenderableShapeEntityItem.cpp | 18 ++-- 5 files changed, 89 insertions(+), 37 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 6fb4be7025..6525286e04 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -496,7 +496,7 @@ EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMa } graphics::MaterialKey drawMaterialKey = materials.getMaterialKey(); - if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) { + if (drawMaterialKey.isEmissive() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) { return Pipeline::MATERIAL; } @@ -635,20 +635,22 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build } builder.withCullFaceMode(materials->second.getCullFaceMode()); + + graphics::MaterialKey drawMaterialKey = materials->second.getMaterialKey(); + if (drawMaterialKey.isUnlit()) { + builder.withUnlit(); + } + auto pipelineType = getPipelineType(materials->second); if (pipelineType == Pipeline::MATERIAL) { builder.withMaterial(); - graphics::MaterialKey drawMaterialKey = materials->second.getMaterialKey(); if (drawMaterialKey.isNormalMap()) { builder.withTangents(); } if (drawMaterialKey.isLightMap()) { builder.withLightMap(); } - if (drawMaterialKey.isUnlit()) { - builder.withUnlit(); - } } else if (pipelineType == Pipeline::PROCEDURAL) { builder.withOwnPipeline(); } diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp index 1d4c238148..176cca729d 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -231,7 +231,7 @@ Item::Bound GizmoEntityRenderer::getBound(RenderArgs* args) { } ShapeKey GizmoEntityRenderer::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace(); + auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); auto mat = getAndUpdateMaterials(); @@ -240,7 +240,7 @@ ShapeKey GizmoEntityRenderer::getShapeKey() { } if (_primitiveMode == PrimitiveMode::LINES) { - builder.withUnlit().withDepthBias().withWireframe(); + builder.withUnlit().withWireframe(); } updateShapeKeyBuilderFromMaterials(builder, mat); diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp index d96c948d7d..ab56798e4f 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp @@ -11,11 +11,15 @@ #include #include +#include "RenderPipelines.h" + using namespace render; using namespace render::entities; ImageEntityRenderer::ImageEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { _geometryId = DependencyManager::get()->allocateID(); + _material->setCullFaceMode(graphics::MaterialKey::CullFaceMode::CULL_NONE); + addMaterial(graphics::MaterialLayer(_material, 0), "0"); } ImageEntityRenderer::~ImageEntityRenderer() { @@ -51,20 +55,38 @@ void ImageEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint _textureIsLoaded = false; } - _emissive = entity->getEmissive(); _keepAspectRatio = entity->getKeepAspectRatio(); _subImage = entity->getSubImage(); - - _color = entity->getColor(); - _alpha = entity->getAlpha(); _pulseProperties = entity->getPulseProperties(); + bool materialChanged = false; + glm::vec3 color = toGlm(entity->getColor()); + if (_color != color) { + _color = color; + _material->setAlbedo(color); + materialChanged = true; + } + + float alpha = entity->getAlpha(); + if (_alpha != alpha) { + _alpha = alpha; + _material->setOpacity(alpha); + materialChanged = true; + } + + auto emissive = entity->getEmissive(); + if (_emissive != emissive) { + _emissive = emissive; + _material->setUnlit(_emissive); + materialChanged = true; + } + + updateMaterials(materialChanged); + if (!_textureIsLoaded) { emit requestRenderUpdate(); } _textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed()); - - updateMaterials(); } bool ImageEntityRenderer::isTransparent() const { @@ -79,41 +101,53 @@ Item::Bound ImageEntityRenderer::getBound(RenderArgs* args) { ShapeKey ImageEntityRenderer::getShapeKey() { auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); + + auto mat = getAndUpdateMaterials(); + if (isTransparent()) { builder.withTranslucent(); } - if (_emissive) { - builder.withUnlit(); - } - if (_primitiveMode == PrimitiveMode::LINES) { builder.withWireframe(); } + updateShapeKeyBuilderFromMaterials(builder, mat); + return builder.build(); } void ImageEntityRenderer::doRender(RenderArgs* args) { - glm::vec4 color = glm::vec4(toGlm(_color), _alpha); - color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); - Transform transform; - withReadLock([&] { - transform = _renderTransform; - }); + PerformanceTimer perfTimer("RenderableImageEntityItem::render"); + Q_ASSERT(args->_batch); - if (!_visible || !_texture || !_texture->isLoaded() || color.a == 0.0f) { + graphics::MultiMaterial materials; + { + std::lock_guard lock(_materialsLock); + materials = _materials["0"]; + } + + auto& schema = materials.getSchemaBuffer().get(); + glm::vec4 color = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity); + color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); + + if (!_texture || !_texture->isLoaded() || color.a == 0.0f) { return; } - Q_ASSERT(args->_batch); + Transform transform; + bool transparent; + withReadLock([&] { + transform = _renderTransform; + transparent = isTransparent(); + }); + gpu::Batch* batch = args->_batch; transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition())); batch->setModelTransform(transform); - batch->setResourceTexture(0, _texture->getGPUTexture()); float imageWidth = _texture->getWidth(); float imageHeight = _texture->getHeight(); @@ -144,6 +178,19 @@ void ImageEntityRenderer::doRender(RenderArgs* args) { glm::vec2 texCoordBottomLeft((fromImage.x() + 0.5f) / imageWidth, (fromImage.y() + fromImage.height() - 0.5f) / imageHeight); glm::vec2 texCoordTopRight((fromImage.x() + fromImage.width() - 0.5f) / imageWidth, (fromImage.y() + 0.5f) / imageHeight); + 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::SIMPLE) { + batch->setResourceTexture(0, _texture->getGPUTexture()); + } else { + if (RenderPipelines::bindMaterials(materials, *batch, args->_renderMode, args->_enableTexturing)) { + args->_details._materialSwitches++; + } + } + DependencyManager::get()->renderQuad( *batch, glm::vec2(-x, -y), glm::vec2(x, y), texCoordBottomLeft, texCoordTopRight, color, _geometryId diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.h b/libraries/entities-renderer/src/RenderableImageEntityItem.h index ca4173d938..ff82dc157a 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.h +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.h @@ -13,6 +13,8 @@ #include +#include + namespace render { namespace entities { class ImageEntityRenderer : public TypedEntityRenderer { @@ -42,8 +44,9 @@ private: bool _keepAspectRatio; QRect _subImage; - glm::u8vec3 _color; - float _alpha; + std::shared_ptr _material { std::make_shared() }; + glm::vec3 _color { NAN }; + float _alpha { NAN }; PulsePropertyGroup _pulseProperties; int _geometryId { 0 }; diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 496d933889..86d178aa43 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -108,15 +108,6 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableShapeEntityItem::render"); Q_ASSERT(args->_batch); - gpu::Batch& batch = *args->_batch; - - auto geometryCache = DependencyManager::get(); - GeometryCache::Shape geometryShape = geometryCache->getShapeForEntityShape(_shape); - Transform transform; - withReadLock([&] { - transform = _renderTransform; - }); - graphics::MultiMaterial materials; { std::lock_guard lock(_materialsLock); @@ -131,6 +122,15 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { return; } + gpu::Batch& batch = *args->_batch; + + auto geometryCache = DependencyManager::get(); + GeometryCache::Shape geometryShape = geometryCache->getShapeForEntityShape(_shape); + Transform transform; + withReadLock([&] { + transform = _renderTransform; + }); + bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, From 826eb709ce2aefdb4a04aadaa5fe5f59a946b320 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Thu, 25 Feb 2021 19:03:42 -0800 Subject: [PATCH 3/7] more work on materials --- .../src/RenderableEntityItem.cpp | 28 ++-- .../src/RenderableEntityItem.h | 3 +- .../src/RenderableGizmoEntityItem.cpp | 16 +- .../src/RenderableImageEntityItem.cpp | 14 +- .../src/RenderableShapeEntityItem.cpp | 16 +- .../src/RenderableTextEntityItem.cpp | 148 +++++++++++------- .../src/RenderableTextEntityItem.h | 10 +- 7 files changed, 121 insertions(+), 114 deletions(-) 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; From ccda630a3abc663ed96373024e0de8dddb9ab17c Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Tue, 2 Mar 2021 21:44:06 -0800 Subject: [PATCH 4/7] fixing _glColor4f --- .../src/RenderableGizmoEntityItem.cpp | 2 +- .../src/RenderableImageEntityItem.cpp | 9 +++-- .../src/RenderableTextEntityItem.cpp | 2 +- .../gpu-gl-common/src/gpu/gl/GLBackend.cpp | 5 +-- .../gpu-gl-common/src/gpu/gl/GLBackend.h | 39 ++++++++++--------- .../src/gpu/gl/GLBackendInput.cpp | 28 ++++++------- .../gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 21 +++++----- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 22 +++++------ libraries/render-utils/src/GeometryCache.cpp | 2 - 9 files changed, 65 insertions(+), 65 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp index 171594cca3..9d337a0c47 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -231,7 +231,7 @@ Item::Bound GizmoEntityRenderer::getBound(RenderArgs* args) { } ShapeKey GizmoEntityRenderer::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); + auto builder = render::ShapeKey::Builder().withDepthBias(); updateShapeKeyBuilderFromMaterials(builder); return builder.build(); } diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp index 587b20543c..65d1d42068 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp @@ -10,6 +10,7 @@ #include #include +#include #include "RenderPipelines.h" @@ -100,7 +101,7 @@ Item::Bound ImageEntityRenderer::getBound(RenderArgs* args) { } ShapeKey ImageEntityRenderer::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); + auto builder = render::ShapeKey::Builder().withDepthBias(); updateShapeKeyBuilderFromMaterials(builder); return builder.build(); } @@ -134,7 +135,6 @@ void ImageEntityRenderer::doRender(RenderArgs* args) { transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition())); - batch->setModelTransform(transform); float imageWidth = _texture->getWidth(); @@ -184,5 +184,8 @@ void ImageEntityRenderer::doRender(RenderArgs* args) { color, _geometryId ); - batch->setResourceTexture(0, nullptr); + if (pipelineType == Pipeline::SIMPLE) { + // we have to reset this to white for other simple shapes + batch->setResourceTexture(graphics::slot::texture::Texture::MaterialAlbedo, DependencyManager::get()->getWhiteTexture()); + } } diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 01eff4cd06..a6f94beb99 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -123,7 +123,7 @@ ItemKey TextEntityRenderer::getKey() { } ShapeKey TextEntityRenderer::getShapeKey() { - auto builder = render::ShapeKey::Builder(); + auto builder = render::ShapeKey::Builder().withDepthBias(); updateShapeKeyBuilderFromMaterials(builder); return builder.build(); } diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index 8126988294..dd30727523 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -840,10 +840,7 @@ void GLBackend::do_glColor4f(const Batch& batch, size_t paramOffset) { if (_input._colorAttribute != newColor) { _input._colorAttribute = newColor; glVertexAttrib4fv(gpu::Stream::COLOR, &_input._colorAttribute.r); - // Color has been changed and is not white. To prevent colors from bleeding - // between different objects, we need to set the _hadColorAttribute flag - // as if a previous render call had potential colors - _input._hadColorAttribute = (newColor != glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + _input._hasColorAttribute = true; } (void)CHECK_GL_ERROR(); } diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 0c8676493b..2947649ce7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -348,36 +348,37 @@ protected: virtual void updateInput() = 0; struct InputStageState { - bool _invalidFormat{ true }; - bool _lastUpdateStereoState{ false }; - bool _hadColorAttribute{ true }; - FormatReference _format{ GPU_REFERENCE_INIT_VALUE }; + bool _invalidFormat { true }; + bool _lastUpdateStereoState { false }; + bool _hasColorAttribute { false }; + bool _hadColorAttribute { false }; + FormatReference _format { GPU_REFERENCE_INIT_VALUE }; std::string _formatKey; typedef std::bitset ActivationCache; - ActivationCache _attributeActivation{ 0 }; + ActivationCache _attributeActivation { 0 }; typedef std::bitset BuffersState; - BuffersState _invalidBuffers{ 0 }; - BuffersState _attribBindingBuffers{ 0 }; + BuffersState _invalidBuffers { 0 }; + BuffersState _attribBindingBuffers { 0 }; - std::array _buffers{}; - std::array _bufferOffsets{}; - std::array _bufferStrides{}; - std::array _bufferVBOs{}; + std::array _buffers; + std::array _bufferOffsets; + std::array _bufferStrides; + std::array _bufferVBOs; - glm::vec4 _colorAttribute{ 0.0f }; + glm::vec4 _colorAttribute { 1.0f }; - BufferReference _indexBuffer{}; - Offset _indexBufferOffset{ 0 }; - Type _indexBufferType{ UINT32 }; + BufferReference _indexBuffer; + Offset _indexBufferOffset { 0 }; + Type _indexBufferType { UINT32 }; - BufferReference _indirectBuffer{}; - Offset _indirectBufferOffset{ 0 }; - Offset _indirectBufferStride{ 0 }; + BufferReference _indirectBuffer; + Offset _indirectBufferOffset { 0 }; + Offset _indirectBufferStride { 0 }; - GLuint _defaultVAO{ 0 }; + GLuint _defaultVAO { 0 }; } _input; virtual void initTransform() = 0; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 85e6ba5382..1bfc27f0d2 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -103,6 +103,9 @@ void GLBackend::resetInputStage() { reset(_input._format); _input._formatKey.clear(); _input._invalidFormat = false; + _input._hasColorAttribute = false; + _input._hadColorAttribute = false; + _input._colorAttribute = vec4(1.0f); _input._attributeActivation.reset(); for (uint32_t i = 0; i < _input._buffers.size(); i++) { @@ -159,15 +162,15 @@ void GLBackend::updateInput() { _input._invalidFormat |= (isStereoNow != _input._lastUpdateStereoState); #endif _input._lastUpdateStereoState = isStereoNow; - + + bool hasColorAttribute = _input._hasColorAttribute; + if (_input._invalidFormat) { InputStageState::ActivationCache newActivation; // Assign the vertex format required auto format = acquire(_input._format); if (format) { - bool hasColorAttribute{ false }; - _input._attribBindingBuffers.reset(); const auto& attributes = format->getAttributes(); @@ -186,12 +189,12 @@ void GLBackend::updateInput() { uint8_t locationCount = attrib._element.getLocationCount(); GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; - GLuint offset = (GLuint)attrib._offset;; + GLuint offset = (GLuint)attrib._offset; GLboolean isNormalized = attrib._element.isNormalized(); GLenum perLocationSize = attrib._element.getLocationSize(); - hasColorAttribute = hasColorAttribute || (slot == Stream::COLOR); + hasColorAttribute |= slot == Stream::COLOR; for (GLuint locNum = 0; locNum < locationCount; ++locNum) { GLuint attriNum = (GLuint)(slot + locNum); @@ -224,14 +227,11 @@ void GLBackend::updateInput() { #endif } - if (_input._hadColorAttribute && !hasColorAttribute) { - // The previous input stage had a color attribute but this one doesn't so reset - // color to pure white. - const auto white = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4fv(Stream::COLOR, &white.r); - _input._colorAttribute = white; + if (!hasColorAttribute && _input._hadColorAttribute) { + // The last stage had a color attribute but this one doens't, so reset the color to pure white. + _input._colorAttribute = glm::vec4(1.0f); + glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r); } - _input._hadColorAttribute = hasColorAttribute; } // Manage Activation what was and what is expected now @@ -253,6 +253,9 @@ void GLBackend::updateInput() { _stats._ISNumFormatChanges++; } + _input._hadColorAttribute = hasColorAttribute; + _input._hasColorAttribute = false; + if (_input._invalidBuffers.any()) { auto vbo = _input._bufferVBOs.data(); auto offset = _input._bufferOffsets.data(); @@ -276,4 +279,3 @@ void GLBackend::updateInput() { (void)CHECK_GL_ERROR(); } } - diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 2b985c122e..0a3d2d7a16 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -33,6 +33,8 @@ void GL41Backend::updateInput() { #endif _input._lastUpdateStereoState = isStereoNow; + bool hasColorAttribute = _input._hasColorAttribute; + if (_input._invalidFormat || _input._invalidBuffers.any()) { auto format = acquire(_input._format); @@ -71,8 +73,6 @@ void GL41Backend::updateInput() { // now we need to bind the buffers and assign the attrib pointers if (format) { - bool hasColorAttribute{ false }; - const auto& buffers = _input._buffers; const auto& offsets = _input._bufferOffsets; const auto& strides = _input._bufferStrides; @@ -110,7 +110,7 @@ void GL41Backend::updateInput() { uintptr_t pointer = (uintptr_t)(attrib._offset + offsets[bufferNum]); GLboolean isNormalized = attrib._element.isNormalized(); - hasColorAttribute = hasColorAttribute || (slot == Stream::COLOR); + hasColorAttribute |= slot == Stream::COLOR; for (size_t locNum = 0; locNum < locationCount; ++locNum) { if (attrib._element.isInteger()) { @@ -132,17 +132,16 @@ void GL41Backend::updateInput() { } } - if (_input._hadColorAttribute && !hasColorAttribute) { - // The previous input stage had a color attribute but this one doesn't so reset - // color to pure white. - const auto white = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4fv(Stream::COLOR, &white.r); - _input._colorAttribute = white; + if (!hasColorAttribute && _input._hadColorAttribute) { + // The last stage had a color attribute but this one doens't, so reset the color to pure white. + _input._colorAttribute = glm::vec4(1.0f); + glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r); } - _input._hadColorAttribute = hasColorAttribute; } // everything format related should be in sync now _input._invalidFormat = false; } -} + _input._hadColorAttribute = hasColorAttribute; + _input._hasColorAttribute = false; +} diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 5285e62d3e..2f0b140e0b 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -35,14 +35,14 @@ void GL45Backend::updateInput() { #endif _input._lastUpdateStereoState = isStereoNow; + bool hasColorAttribute = _input._hasColorAttribute; + if (_input._invalidFormat) { InputStageState::ActivationCache newActivation; // Assign the vertex format required auto format = acquire(_input._format); if (format) { - bool hasColorAttribute{ false }; - _input._attribBindingBuffers.reset(); const auto& attributes = format->getAttributes(); @@ -61,12 +61,12 @@ void GL45Backend::updateInput() { uint8_t locationCount = attrib._element.getLocationCount(); GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; - GLuint offset = (GLuint)attrib._offset;; + GLuint offset = (GLuint)attrib._offset; GLboolean isNormalized = attrib._element.isNormalized(); GLenum perLocationSize = attrib._element.getLocationSize(); - hasColorAttribute = hasColorAttribute || (slot == Stream::COLOR); + hasColorAttribute |= slot == Stream::COLOR; for (GLuint locNum = 0; locNum < locationCount; ++locNum) { GLuint attriNum = (GLuint)(slot + locNum); @@ -99,14 +99,11 @@ void GL45Backend::updateInput() { #endif } - if (_input._hadColorAttribute && !hasColorAttribute) { - // The previous input stage had a color attribute but this one doesn't so reset - // color to pure white. - const auto white = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4fv(Stream::COLOR, &white.r); - _input._colorAttribute = white; + if (!hasColorAttribute && _input._hadColorAttribute) { + // The last stage had a color attribute but this one doens't, so reset the color to pure white. + _input._colorAttribute = glm::vec4(1.0f); + glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r); } - _input._hadColorAttribute = hasColorAttribute; } // Manage Activation what was and what is expected now @@ -128,6 +125,9 @@ void GL45Backend::updateInput() { _stats._ISNumFormatChanges++; } + _input._hadColorAttribute = hasColorAttribute; + _input._hasColorAttribute = false; + if (_input._invalidBuffers.any()) { auto vbo = _input._bufferVBOs.data(); auto offset = _input._bufferOffsets.data(); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 325e228120..af33899617 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -821,14 +821,12 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) { void GeometryCache::renderShape(gpu::Batch& batch, Shape shape, const glm::vec4& color) { batch.setInputFormat(getSolidStreamFormat()); - // Color must be set after input format batch._glColor4f(color.r, color.g, color.b, color.a); _shapes[shape].draw(batch); } void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color) { batch.setInputFormat(getWireStreamFormat()); - // Color must be set after input format batch._glColor4f(color.r, color.g, color.b, color.a); _shapes[shape].drawWire(batch); } From 68c20ce73d74b4a27afe66dc9ef0538a072bdcf8 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 3 Mar 2021 17:47:03 -0800 Subject: [PATCH 5/7] text backgrounds have texcoord if not simple --- .../entities-renderer/src/RenderableTextEntityItem.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index a6f94beb99..2858e12afd 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -180,7 +180,11 @@ void TextEntityRenderer::doRender(RenderArgs* args) { } auto geometryCache = DependencyManager::get(); - geometryCache->renderQuad(batch, glm::vec2(-0.5), glm::vec2(0.5), backgroundColor, _geometryID); + if (pipelineType == Pipeline::SIMPLE) { + geometryCache->renderQuad(batch, glm::vec2(-0.5f), glm::vec2(0.5f), backgroundColor, _geometryID); + } else { + geometryCache->renderQuad(batch, glm::vec2(-0.5f), glm::vec2(0.5f), glm::vec2(0.0f), glm::vec2(1.0f), backgroundColor, _geometryID); + } const int TRIANGLES_PER_QUAD = 2; args->_details._trianglesRendered += TRIANGLES_PER_QUAD; From 1abb408a93da76a62c811557e5ca470dc1de44bc Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 3 Mar 2021 18:58:09 -0800 Subject: [PATCH 6/7] type --- libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp | 2 +- libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 2 +- libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 1bfc27f0d2..4efd5f9941 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -228,7 +228,7 @@ void GLBackend::updateInput() { } if (!hasColorAttribute && _input._hadColorAttribute) { - // The last stage had a color attribute but this one doens't, so reset the color to pure white. + // The previous input stage had a color attribute but this one doesn't, so reset the color to pure white. _input._colorAttribute = glm::vec4(1.0f); glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r); } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 0a3d2d7a16..188b4a1084 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -133,7 +133,7 @@ void GL41Backend::updateInput() { } if (!hasColorAttribute && _input._hadColorAttribute) { - // The last stage had a color attribute but this one doens't, so reset the color to pure white. + // The previous input stage had a color attribute but this one doesn't, so reset the color to pure white. _input._colorAttribute = glm::vec4(1.0f); glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r); } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 2f0b140e0b..8add4a9296 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -100,7 +100,7 @@ void GL45Backend::updateInput() { } if (!hasColorAttribute && _input._hadColorAttribute) { - // The last stage had a color attribute but this one doens't, so reset the color to pure white. + // The previous input stage had a color attribute but this one doesn't, so reset the color to pure white. _input._colorAttribute = glm::vec4(1.0f); glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r); } From 9a247172f3412977707fc4aa6d10a6b06488742d Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Tue, 9 Mar 2021 21:09:48 -0800 Subject: [PATCH 7/7] non-parented material use the right cull mode --- .../entities-renderer/src/RenderableMaterialEntityItem.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 714defe817..8f8a2076f8 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -219,6 +219,10 @@ ShapeKey MaterialEntityRenderer::getShapeKey() { builder.withTranslucent(); } + if (drawMaterial) { + builder.withCullFaceMode(drawMaterial->getCullFaceMode()); + } + if (drawMaterial && drawMaterial->isProcedural() && drawMaterial->isReady()) { builder.withOwnPipeline(); } else {