From 305cb6d323367659686cd53068700aa62b727a45 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 3 Dec 2018 18:04:34 -0800 Subject: [PATCH 1/4] grid entities --- .../src/RenderableEntityItem.cpp | 5 + .../src/RenderableGridEntityItem.cpp | 144 ++++++++++++++ .../src/RenderableGridEntityItem.h | 51 +++++ .../src/RenderableImageEntityItem.h | 58 +++--- .../entities/src/EntityItemProperties.cpp | 87 ++++++++- libraries/entities/src/EntityItemProperties.h | 6 + .../entities/src/EntityItemPropertiesMacros.h | 1 + libraries/entities/src/EntityPropertyFlags.h | 6 + libraries/entities/src/EntityTypes.cpp | 2 + libraries/entities/src/EntityTypes.h | 3 + libraries/entities/src/GridEntityItem.cpp | 178 ++++++++++++++++++ libraries/entities/src/GridEntityItem.h | 71 +++++++ .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 3 +- 14 files changed, 584 insertions(+), 33 deletions(-) create mode 100644 libraries/entities-renderer/src/RenderableGridEntityItem.cpp create mode 100644 libraries/entities-renderer/src/RenderableGridEntityItem.h create mode 100644 libraries/entities/src/GridEntityItem.cpp create mode 100644 libraries/entities/src/GridEntityItem.h diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 6c979f8afe..92387dafa6 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -26,6 +26,7 @@ #include "RenderableZoneEntityItem.h" #include "RenderableMaterialEntityItem.h" #include "RenderableImageEntityItem.h" +#include "RenderableGridEntityItem.h" using namespace render; @@ -256,6 +257,10 @@ EntityRenderer::Pointer EntityRenderer::addToScene(EntityTreeRenderer& renderer, result = make_renderer(entity); break; + case Type::Grid: + result = make_renderer(entity); + break; + case Type::Light: result = make_renderer(entity); break; diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.cpp b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp new file mode 100644 index 0000000000..9156ca33e9 --- /dev/null +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp @@ -0,0 +1,144 @@ +// +// Created by Sam Gondelman on 11/29/18 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "RenderableGridEntityItem.h" + +#include +#include + +using namespace render; +using namespace render::entities; + +GridEntityRenderer::GridEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { + _geometryId = DependencyManager::get()->allocateID(); +} + +GridEntityRenderer::~GridEntityRenderer() { + auto geometryCache = DependencyManager::get(); + if (geometryCache) { + geometryCache->releaseID(_geometryId); + } +} + +bool GridEntityRenderer::isTransparent() const { + return Parent::isTransparent() || _alpha < 1.0f; +} + +bool GridEntityRenderer::needsRenderUpdate() const { + return Parent::needsRenderUpdate(); +} + +bool GridEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { + bool needsUpdate = resultWithReadLock([&] { + if (_color != entity->getColor()) { + return true; + } + + if (_alpha != entity->getAlpha()) { + return true; + } + + if (_followCamera != entity->getFollowCamera()) { + return true; + } + + if (_majorGridEvery != entity->getMajorGridEvery()) { + return true; + } + + if (_minorGridEvery != entity->getMinorGridEvery()) { + return true; + } + + return false; + }); + + return needsUpdate; +} + +void GridEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { + withWriteLock([&] { + _color = entity->getColor(); + _alpha = entity->getAlpha(); + + _followCamera = entity->getFollowCamera(); + _majorGridEvery = entity->getMajorGridEvery(); + _minorGridEvery = entity->getMinorGridEvery(); + }); + + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity]() { + withWriteLock([&] { + _dimensions = entity->getScaledDimensions(); + updateModelTransformAndBound(); + _renderTransform = getModelTransform(); + }); + }); +} + +Item::Bound GridEntityRenderer::getBound() { + if (_followCamera) { + // This is a UI element that should always be in view, lie to the octree to avoid culling + const AABox DOMAIN_BOX = AABox(glm::vec3(-TREE_SCALE / 2), TREE_SCALE); + return DOMAIN_BOX; + } + return Parent::getBound(); +} + +ShapeKey GridEntityRenderer::getShapeKey() { + return render::ShapeKey::Builder().withOwnPipeline().withUnlit().withDepthBias(); +} + +void GridEntityRenderer::doRender(RenderArgs* args) { + glm::u8vec3 color; + glm::vec3 dimensions; + Transform renderTransform; + withReadLock([&] { + color = _color; + dimensions = _dimensions; + renderTransform = _renderTransform; + }); + + if (!_visible) { + return; + } + + auto batch = args->_batch; + + Transform transform; + transform.setScale(dimensions); + transform.setRotation(renderTransform.getRotation()); + if (_followCamera) { + // Get the camera position rounded to the nearest major grid line + // This grid is for UI and should lie on worldlines + glm::vec3 localCameraPosition = glm::inverse(transform.getRotation()) * args->getViewFrustum().getPosition(); + localCameraPosition.z = 0; + localCameraPosition = (float)_majorGridEvery * glm::round(localCameraPosition / (float)_majorGridEvery); + transform.setTranslation(renderTransform.getTranslation() + transform.getRotation() * localCameraPosition); + } else { + transform.setTranslation(renderTransform.getTranslation()); + } + batch->setModelTransform(transform); + + auto minCorner = glm::vec2(-0.5f, -0.5f); + auto maxCorner = glm::vec2(0.5f, 0.5f); + float majorGridRowDivisions = dimensions.x / _majorGridEvery; + float majorGridColDivisions = dimensions.y / _majorGridEvery; + float minorGridRowDivisions = dimensions.x / _minorGridEvery; + float minorGridColDivisions = dimensions.y / _minorGridEvery; + glm::vec4 gridColor(toGlm(color), _alpha); + + const float MINOR_GRID_EDGE = 0.0025f; + const float MAJOR_GRID_EDGE = 0.005f; + // FIXME: add layered props to entities + const float LAYERED = false; + DependencyManager::get()->renderGrid(*batch, minCorner, maxCorner, + minorGridRowDivisions, minorGridColDivisions, MINOR_GRID_EDGE, + majorGridRowDivisions, majorGridColDivisions, MAJOR_GRID_EDGE, + gridColor, LAYERED, _geometryId); +} \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.h b/libraries/entities-renderer/src/RenderableGridEntityItem.h new file mode 100644 index 0000000000..23f1f03d0d --- /dev/null +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.h @@ -0,0 +1,51 @@ +// +// Created by Sam Gondelman on 11/29/18 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_RenderableGridEntityItem_h +#define hifi_RenderableGridEntityItem_h + +#include "RenderableEntityItem.h" + +#include + +namespace render { namespace entities { + +class GridEntityRenderer : public TypedEntityRenderer { + using Parent = TypedEntityRenderer; + using Pointer = std::shared_ptr; +public: + GridEntityRenderer(const EntityItemPointer& entity); + ~GridEntityRenderer(); + +protected: + Item::Bound getBound() override; + ShapeKey getShapeKey() override; + + bool isTransparent() const override; + +private: + virtual bool needsRenderUpdate() const override; + virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRender(RenderArgs* args) override; + + glm::u8vec3 _color; + float _alpha; + + bool _followCamera; + uint32_t _majorGridEvery; + float _minorGridEvery; + + glm::vec3 _dimensions; + + int _geometryId { 0 }; + +}; + +} } +#endif // hifi_RenderableGridEntityItem_h diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.h b/libraries/entities-renderer/src/RenderableImageEntityItem.h index 669db13a22..9bc990f6fa 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.h +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.h @@ -13,44 +13,42 @@ #include -namespace render { - namespace entities { +namespace render { namespace entities { - class ImageEntityRenderer : public TypedEntityRenderer { - using Parent = TypedEntityRenderer; - using Pointer = std::shared_ptr; - public: - ImageEntityRenderer(const EntityItemPointer& entity); - ~ImageEntityRenderer(); +class ImageEntityRenderer : public TypedEntityRenderer { + using Parent = TypedEntityRenderer; + using Pointer = std::shared_ptr; +public: + ImageEntityRenderer(const EntityItemPointer& entity); + ~ImageEntityRenderer(); - protected: - ShapeKey getShapeKey() override; +protected: + ShapeKey getShapeKey() override; - bool isTransparent() const override; + bool isTransparent() const override; - private: - virtual bool needsRenderUpdate() const override; - virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; - virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; - virtual void doRender(RenderArgs* args) override; +private: + virtual bool needsRenderUpdate() const override; + virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRender(RenderArgs* args) override; - QString _imageURL; - NetworkTexturePointer _texture; - bool _textureIsLoaded { false }; + QString _imageURL; + NetworkTexturePointer _texture; + bool _textureIsLoaded { false }; - bool _emissive; - bool _keepAspectRatio; - BillboardMode _billboardMode; - QRect _subImage; + bool _emissive; + bool _keepAspectRatio; + BillboardMode _billboardMode; + QRect _subImage; - glm::u8vec3 _color; - float _alpha; + glm::u8vec3 _color; + float _alpha; - glm::vec3 _dimensions; + glm::vec3 _dimensions; - int _geometryId { 0 }; - }; + int _geometryId { 0 }; +}; - } -} +} } #endif // hifi_RenderableImageEntityItem_h diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 6f451f937a..4fcf2ebc6e 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -415,6 +415,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_KEEP_ASPECT_RATIO, keepAspectRatio); CHECK_PROPERTY_CHANGE(PROP_SUB_IMAGE, subImage); + CHECK_PROPERTY_CHANGE(PROP_GRID_FOLLOW_CAMERA, followCamera); + CHECK_PROPERTY_CHANGE(PROP_MAJOR_GRID_EVERY, majorGridEvery); + CHECK_PROPERTY_CHANGE(PROP_MINOR_GRID_EVERY, minorGridEvery); + // Certifiable Properties CHECK_PROPERTY_CHANGE(PROP_ITEM_NAME, itemName); CHECK_PROPERTY_CHANGE(PROP_ITEM_DESCRIPTION, itemDescription); @@ -684,6 +688,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @see {@link Entities.EntityProperties-Line|EntityProperties-Line} * @see {@link Entities.EntityProperties-PolyLine|EntityProperties-PolyLine} * @see {@link Entities.EntityProperties-PolyVox|EntityProperties-PolyVox} + * @see {@link Entities.EntityProperties-Grid|EntityProperties-Grid} * @see {@link Entities.EntityProperties-Light|EntityProperties-Light} * @see {@link Entities.EntityProperties-Zone|EntityProperties-Zone} * @see {@link Entities.EntityProperties-Material|EntityProperties-Material} @@ -1239,7 +1244,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * "isFacingAvatar" to true to set billboardMode to "full". Setting either to false sets the mode to "none" * @property {Rect} subImage={ x: 0, y: 0, width: -1, height: -1 } - The portion of the image to display. If width or height are -1, defaults to * the full image in that dimension. - * @property {Color} color=255,255,255 - The color of image. + * @property {Color} color=255,255,255 - The color of the image. * @property {number} alpha=1 - The alpha of the image. * @example Create a image entity. * var image = Entities.addEntity({ @@ -1252,6 +1257,30 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * }); */ +/**jsdoc + * The "Grid" {@link Entities.EntityType|EntityType} displays a grid on a 2D plane. + * It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}. + * @typedef {object} Entities.EntityProperties-Grid + * @property {Color} color=255,255,255 - The color of the grid. + * @property {number} alpha=1 - The alpha of the grid. + * @property {boolean} followCamera=true - If true, the grid is always visible even as the camera moves to another + * position. + * @property {number} majorGridEvery=5 - Integer number of minorGridEvery intervals at which to draw a thick grid + * line. Minimum value = 1. + * @property {number} minorGridEvery=1 - Real number of meters at which to draw thin grid lines. Minimum value = + * 0.001. + * @example Create a grid entity. + * var grid = Entities.addEntity({ + * type: "Grid", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * dimensions: { x: 100.0, y: 100.0, z: 0.01 }, + * followCamera: false, + * majorGridEvery: 4, + * minorGridEvery: 0.5, + * lifetime: 300 // Delete after 5 minutes. + * }); + */ + QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime, bool strictSemantics, EntityPsuedoPropertyFlags psueudoPropertyFlags) const { @@ -1543,6 +1572,16 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool } } + // Grid only + if (_type == EntityTypes::Grid) { + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha); + + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GRID_FOLLOW_CAMERA, followCamera); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAJOR_GRID_EVERY, majorGridEvery); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MINOR_GRID_EVERY, minorGridEvery); + } + /**jsdoc * The axis-aligned bounding box of an entity. * @typedef {object} Entities.BoundingBox @@ -1778,6 +1817,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(keepAspectRatio, bool, setKeepAspectRatio); COPY_PROPERTY_FROM_QSCRIPTVALUE(subImage, QRect, setSubImage); + COPY_PROPERTY_FROM_QSCRIPTVALUE(followCamera, bool, setFollowCamera); + COPY_PROPERTY_FROM_QSCRIPTVALUE(majorGridEvery, uint32_t, setMajorGridEvery); + COPY_PROPERTY_FROM_QSCRIPTVALUE(minorGridEvery, float, setMinorGridEvery); + if (!honorReadOnly) { // this is used by the json reader to set things that we don't want javascript to able to affect. COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(created, QDateTime, setCreated, [this]() { @@ -1962,6 +2005,10 @@ void EntityItemProperties::merge(const EntityItemProperties& other) { COPY_PROPERTY_IF_CHANGED(keepAspectRatio); COPY_PROPERTY_IF_CHANGED(subImage); + COPY_PROPERTY_IF_CHANGED(followCamera); + COPY_PROPERTY_IF_CHANGED(majorGridEvery); + COPY_PROPERTY_IF_CHANGED(minorGridEvery); + // Certifiable Properties COPY_PROPERTY_IF_CHANGED(itemName); COPY_PROPERTY_IF_CHANGED(itemDescription); @@ -2321,6 +2368,10 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_KEEP_ASPECT_RATIO, KeepAspectRatio, keepAspectRatio, bool); ADD_PROPERTY_TO_MAP(PROP_SUB_IMAGE, SubImage, subImage, QRect); + ADD_PROPERTY_TO_MAP(PROP_GRID_FOLLOW_CAMERA, FollowCamera, followCamera, bool); + ADD_PROPERTY_TO_MAP(PROP_MAJOR_GRID_EVERY, MajorGridEvery, majorGridEvery, uint32_t); + ADD_PROPERTY_TO_MAP(PROP_MINOR_GRID_EVERY, MinorGridEvery, minorGridEvery, float); + // FIXME - these are not yet handled //ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64); @@ -2654,6 +2705,16 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha()); } + // Grid + if (properties.getType() == EntityTypes::Grid) { + APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha()); + + APPEND_ENTITY_PROPERTY(PROP_GRID_FOLLOW_CAMERA, properties.getFollowCamera()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_GRID_EVERY, properties.getMajorGridEvery()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_GRID_EVERY, properties.getMinorGridEvery()); + } + APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL()); APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, properties.getActionData()); @@ -3061,6 +3122,16 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha); } + // Grid + if (properties.getType() == EntityTypes::Grid) { + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha); + + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GRID_FOLLOW_CAMERA, bool, setFollowCamera); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAJOR_GRID_EVERY, uint32_t, setMajorGridEvery); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MINOR_GRID_EVERY, float, setMinorGridEvery); + } + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACTION_DATA, QByteArray, setActionData); @@ -3392,6 +3463,10 @@ void EntityItemProperties::markAllChanged() { _emissiveChanged = true; _keepAspectRatioChanged = true; _subImageChanged = true; + + _followCameraChanged = true; + _majorGridEveryChanged = true; + _minorGridEveryChanged = true; } // The minimum bounding box for the entity. @@ -3945,6 +4020,16 @@ QList EntityItemProperties::listChangedProperties() { out += "billboardMode"; } + if (followCameraChanged()) { + out += "followCamera"; + } + if (majorGridEveryChanged()) { + out += "majorGridEvery"; + } + if (minorGridEveryChanged()) { + out += "minorGridEvery"; + } + getAnimation().listChangedProperties(out); getKeyLight().listChangedProperties(out); getAmbientLight().listChangedProperties(out); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 8a9e22f28c..a73bba38ed 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -46,6 +46,7 @@ #include "BloomPropertyGroup.h" #include "TextEntityItem.h" #include "ZoneEntityItem.h" +#include "GridEntityItem.h" #include "MaterialMappingMode.h" #include "BillboardMode.h" @@ -80,6 +81,7 @@ class EntityItemProperties { friend class LineEntityItem; friend class PolyLineEntityItem; friend class PolyVoxEntityItem; + friend class GridEntityItem; friend class LightEntityItem; friend class ZoneEntityItem; friend class MaterialEntityItem; @@ -257,6 +259,10 @@ public: DEFINE_PROPERTY_REF(PROP_KEEP_ASPECT_RATIO, KeepAspectRatio, keepAspectRatio, bool, true); DEFINE_PROPERTY_REF(PROP_SUB_IMAGE, SubImage, subImage, QRect, QRect()); + DEFINE_PROPERTY_REF(PROP_GRID_FOLLOW_CAMERA, FollowCamera, followCamera, bool, true); + DEFINE_PROPERTY(PROP_MAJOR_GRID_EVERY, MajorGridEvery, majorGridEvery, uint32_t, GridEntityItem::DEFAULT_MAJOR_GRID_EVERY); + DEFINE_PROPERTY(PROP_MINOR_GRID_EVERY, MinorGridEvery, minorGridEvery, float, GridEntityItem::DEFAULT_MINOR_GRID_EVERY); + // Certifiable Properties - related to Proof of Purchase certificates DEFINE_PROPERTY_REF(PROP_ITEM_NAME, ItemName, itemName, QString, ENTITY_ITEM_DEFAULT_ITEM_NAME); DEFINE_PROPERTY_REF(PROP_ITEM_DESCRIPTION, ItemDescription, itemDescription, QString, ENTITY_ITEM_DEFAULT_ITEM_DESCRIPTION); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 225b77bd97..c963c66187 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -226,6 +226,7 @@ inline quint32 quint32_convertFromScriptValue(const QScriptValue& v, bool& isVal } inline quint16 quint16_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } +inline uint32_t uint32_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline int int_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline bool bool_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toBool(); } inline uint8_t uint8_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return (uint8_t)(0xff & v.toVariant().toInt(&isValid)); } diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 803d391e11..13d5c876b1 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -316,6 +316,12 @@ enum EntityPropertyList { PROP_IMAGE_URL = PROP_MODEL_URL, PROP_KEEP_ASPECT_RATIO = PROP_ANIMATION_PLAYING, + // Aliases/Piggyback properties for Grid. These properties intentionally reuse the enum values for + // other properties which will never overlap with each other. + PROP_GRID_FOLLOW_CAMERA = PROP_ANIMATION_PLAYING, + PROP_MAJOR_GRID_EVERY = PROP_ANIMATION_URL, + PROP_MINOR_GRID_EVERY = PROP_ANIMATION_FPS, + // WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above }; diff --git a/libraries/entities/src/EntityTypes.cpp b/libraries/entities/src/EntityTypes.cpp index 30f9d9b541..e511af83b0 100644 --- a/libraries/entities/src/EntityTypes.cpp +++ b/libraries/entities/src/EntityTypes.cpp @@ -29,6 +29,7 @@ #include "LineEntityItem.h" #include "PolyLineEntityItem.h" #include "PolyVoxEntityItem.h" +#include "GridEntityItem.h" #include "LightEntityItem.h" #include "ZoneEntityItem.h" #include "MaterialEntityItem.h" @@ -52,6 +53,7 @@ REGISTER_ENTITY_TYPE(ParticleEffect) REGISTER_ENTITY_TYPE(Line) REGISTER_ENTITY_TYPE(PolyLine) REGISTER_ENTITY_TYPE(PolyVox) +REGISTER_ENTITY_TYPE(Grid) REGISTER_ENTITY_TYPE(Light) REGISTER_ENTITY_TYPE(Zone) REGISTER_ENTITY_TYPE(Material) diff --git a/libraries/entities/src/EntityTypes.h b/libraries/entities/src/EntityTypes.h index c85cb5b2dd..29a695718e 100644 --- a/libraries/entities/src/EntityTypes.h +++ b/libraries/entities/src/EntityTypes.h @@ -76,6 +76,8 @@ public: * {@link Entities.EntityProperties-PolyLine|EntityProperties-PolyLine} * "PolyVox"A set of textured voxels. * {@link Entities.EntityProperties-PolyVox|EntityProperties-PolyVox} + * "Grid"A grid of lines in a plane. + * {@link Entities.EntityProperties-Grid|EntityProperties-Grid} * "Light"A local lighting effect. * {@link Entities.EntityProperties-Light|EntityProperties-Light} * "Zone"A volume of lighting effects and avatar permissions. @@ -100,6 +102,7 @@ public: Line, PolyLine, PolyVox, + Grid, Light, Zone, Material, diff --git a/libraries/entities/src/GridEntityItem.cpp b/libraries/entities/src/GridEntityItem.cpp new file mode 100644 index 0000000000..b4709239ed --- /dev/null +++ b/libraries/entities/src/GridEntityItem.cpp @@ -0,0 +1,178 @@ +// +// Created by Sam Gondelman on 11/29/18 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "GridEntityItem.h" + +#include "EntityItemProperties.h" + +const uint32_t GridEntityItem::DEFAULT_MAJOR_GRID_EVERY = 5; +const float GridEntityItem::DEFAULT_MINOR_GRID_EVERY = 1.0f; + +EntityItemPointer GridEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { + Pointer entity(new GridEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); }); + entity->setProperties(properties); + return entity; +} + +// our non-pure virtual subclass for now... +GridEntityItem::GridEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { + _type = EntityTypes::Grid; +} + +void GridEntityItem::setUnscaledDimensions(const glm::vec3& value) { + const float GRID_ENTITY_ITEM_FIXED_DEPTH = 0.01f; + // NOTE: Grid Entities always have a "depth" of 1cm. + EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, GRID_ENTITY_ITEM_FIXED_DEPTH)); +} + +EntityItemProperties GridEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { + EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class + + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha); + + COPY_ENTITY_PROPERTY_TO_PROPERTIES(followCamera, getFollowCamera); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(majorGridEvery, getMajorGridEvery); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(minorGridEvery, getMinorGridEvery); + + return properties; +} + +bool GridEntityItem::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class + + SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha); + + SET_ENTITY_PROPERTY_FROM_PROPERTIES(followCamera, setFollowCamera); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(majorGridEvery, setMajorGridEvery); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(minorGridEvery, setMinorGridEvery); + + if (somethingChanged) { + bool wantDebug = false; + if (wantDebug) { + uint64_t now = usecTimestampNow(); + int elapsed = now - getLastEdited(); + qCDebug(entities) << "GridEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << + "now=" << now << " getLastEdited()=" << getLastEdited(); + } + setLastEdited(properties.getLastEdited()); + } + return somethingChanged; +} + +int GridEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor); + READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); + + READ_ENTITY_PROPERTY(PROP_GRID_FOLLOW_CAMERA, bool, setFollowCamera); + READ_ENTITY_PROPERTY(PROP_MAJOR_GRID_EVERY, uint32_t, setMajorGridEvery); + READ_ENTITY_PROPERTY(PROP_MINOR_GRID_EVERY, float, setMinorGridEvery); + + return bytesRead; +} + +EntityPropertyFlags GridEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); + + requestedProperties += PROP_COLOR; + requestedProperties += PROP_ALPHA; + + requestedProperties += PROP_GRID_FOLLOW_CAMERA; + requestedProperties += PROP_MAJOR_GRID_EVERY; + requestedProperties += PROP_MINOR_GRID_EVERY; + + return requestedProperties; +} + +void GridEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha()); + + APPEND_ENTITY_PROPERTY(PROP_GRID_FOLLOW_CAMERA, getFollowCamera()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_GRID_EVERY, getMajorGridEvery()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_GRID_EVERY, getMinorGridEvery()); +} + +void GridEntityItem::setColor(const glm::u8vec3& color) { + withWriteLock([&] { + _color = color; + }); +} + +glm::u8vec3 GridEntityItem::getColor() const { + return resultWithReadLock([&] { + return _color; + }); +} + +void GridEntityItem::setAlpha(float alpha) { + withWriteLock([&] { + _alpha = alpha; + }); +} + +float GridEntityItem::getAlpha() const { + return resultWithReadLock([&] { + return _alpha; + }); +} + +void GridEntityItem::setFollowCamera(bool followCamera) { + withWriteLock([&] { + _followCamera = followCamera; + }); +} + +bool GridEntityItem::getFollowCamera() const { + return resultWithReadLock([&] { + return _followCamera; + }); +} + +void GridEntityItem::setMajorGridEvery(uint32_t majorGridEvery) { + withWriteLock([&] { + const uint32_t MAJOR_GRID_EVERY_MIN = 1; + _majorGridEvery = std::max(majorGridEvery, MAJOR_GRID_EVERY_MIN); + }); +} + +uint32_t GridEntityItem::getMajorGridEvery() const { + return resultWithReadLock([&] { + return _majorGridEvery; + }); +} + +void GridEntityItem::setMinorGridEvery(float minorGridEvery) { + withWriteLock([&] { + const float MINOR_GRID_EVERY_MIN = 0.01f; + _minorGridEvery = std::max(minorGridEvery, MINOR_GRID_EVERY_MIN); + }); +} + +float GridEntityItem::getMinorGridEvery() const { + return resultWithReadLock([&] { + return _minorGridEvery; + }); +} \ No newline at end of file diff --git a/libraries/entities/src/GridEntityItem.h b/libraries/entities/src/GridEntityItem.h new file mode 100644 index 0000000000..6209aee73d --- /dev/null +++ b/libraries/entities/src/GridEntityItem.h @@ -0,0 +1,71 @@ +// +// Created by Sam Gondelman on 11/29/18 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_GridEntityItem_h +#define hifi_GridEntityItem_h + +#include "EntityItem.h" + +class GridEntityItem : public EntityItem { + using Pointer = std::shared_ptr; +public: + static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); + + GridEntityItem(const EntityItemID& entityItemID); + + ALLOW_INSTANTIATION // This class can be instantiated + + virtual void setUnscaledDimensions(const glm::vec3& value) override; + + // methods for getting/setting all properties of an entity + EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override; + bool setProperties(const EntityItemProperties& properties) override; + + EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; + + void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) override; + + static const uint32_t DEFAULT_MAJOR_GRID_EVERY; + static const float DEFAULT_MINOR_GRID_EVERY; + + void setColor(const glm::u8vec3& color); + glm::u8vec3 getColor() const; + + void setAlpha(float alpha); + float getAlpha() const; + + void setFollowCamera(bool followCamera); + bool getFollowCamera() const; + + void setMajorGridEvery(uint32_t majorGridEvery); + uint32_t getMajorGridEvery() const; + + void setMinorGridEvery(float minorGridEvery); + float getMinorGridEvery() const; + +protected: + glm::u8vec3 _color; + float _alpha; + bool _followCamera { true }; + uint32_t _majorGridEvery { DEFAULT_MAJOR_GRID_EVERY }; + float _minorGridEvery { DEFAULT_MINOR_GRID_EVERY }; + +}; + +#endif // hifi_GridEntityItem_h diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 3325faa95c..485f8f7de2 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -33,7 +33,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return static_cast(EntityVersion::ImageEntities); + return static_cast(EntityVersion::GridEntities); case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::ConicalFrustums); case PacketType::AvatarIdentity: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 421c9a96c1..e9f9dd3dc9 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -246,7 +246,8 @@ enum class EntityVersion : PacketVersion { ScriptGlmVectors, FixedLightSerialization, CleanupProperties, - ImageEntities + ImageEntities, + GridEntities }; enum class EntityScriptCallMethodVersion : PacketVersion { From 9923e76968c8f37a71c96d6a9783ec620d7f87c0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 5 Dec 2018 17:18:26 -0800 Subject: [PATCH 2/4] cleanup --- interface/src/ui/overlays/Grid3DOverlay.cpp | 2 +- .../src/RenderableGridEntityItem.cpp | 14 ++++-- libraries/render-utils/src/GeometryCache.cpp | 48 ++++++++++++------- libraries/render-utils/src/GeometryCache.h | 11 ++--- 4 files changed, 43 insertions(+), 32 deletions(-) diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 87ab0fb2e8..402d170ca9 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -85,7 +85,7 @@ void Grid3DOverlay::render(RenderArgs* args) { DependencyManager::get()->renderGrid(*batch, minCorner, maxCorner, _minorGridRowDivisions, _minorGridColDivisions, MINOR_GRID_EDGE, _majorGridRowDivisions, _majorGridColDivisions, MAJOR_GRID_EDGE, - gridColor, _drawInFront, _geometryId); + gridColor, _geometryId); } } diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.cpp b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp index 9156ca33e9..22cf72cec6 100644 --- a/libraries/entities-renderer/src/RenderableGridEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp @@ -91,7 +91,13 @@ Item::Bound GridEntityRenderer::getBound() { } ShapeKey GridEntityRenderer::getShapeKey() { - return render::ShapeKey::Builder().withOwnPipeline().withUnlit().withDepthBias(); + auto builder = render::ShapeKey::Builder().withOwnPipeline().withUnlit().withDepthBias(); + + if (isTransparent()) { + builder.withTranslucent(); + } + + return builder.build(); } void GridEntityRenderer::doRender(RenderArgs* args) { @@ -116,7 +122,7 @@ void GridEntityRenderer::doRender(RenderArgs* args) { if (_followCamera) { // Get the camera position rounded to the nearest major grid line // This grid is for UI and should lie on worldlines - glm::vec3 localCameraPosition = glm::inverse(transform.getRotation()) * args->getViewFrustum().getPosition(); + glm::vec3 localCameraPosition = glm::inverse(transform.getRotation()) * (args->getViewFrustum().getPosition() - renderTransform.getTranslation()); localCameraPosition.z = 0; localCameraPosition = (float)_majorGridEvery * glm::round(localCameraPosition / (float)_majorGridEvery); transform.setTranslation(renderTransform.getTranslation() + transform.getRotation() * localCameraPosition); @@ -135,10 +141,8 @@ void GridEntityRenderer::doRender(RenderArgs* args) { const float MINOR_GRID_EDGE = 0.0025f; const float MAJOR_GRID_EDGE = 0.005f; - // FIXME: add layered props to entities - const float LAYERED = false; DependencyManager::get()->renderGrid(*batch, minCorner, maxCorner, minorGridRowDivisions, minorGridColDivisions, MINOR_GRID_EDGE, majorGridRowDivisions, majorGridColDivisions, MAJOR_GRID_EDGE, - gridColor, LAYERED, _geometryId); + gridColor, _geometryId); } \ No newline at end of file diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 38c3106af6..14249f5b9b 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -946,7 +946,7 @@ void GeometryCache::renderWireSphere(gpu::Batch& batch, const glm::vec4& color) void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, int majorRows, int majorCols, float majorEdge, int minorRows, int minorCols, float minorEdge, - const glm::vec4& color, bool isLayered, int id) { + const glm::vec4& color, int id) { static const glm::vec2 MIN_TEX_COORD(0.0f, 0.0f); static const glm::vec2 MAX_TEX_COORD(1.0f, 1.0f); @@ -978,7 +978,7 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co } // Set the grid pipeline - useGridPipeline(batch, _registeredGridBuffers[id], isLayered); + useGridPipeline(batch, _registeredGridBuffers[id], color.a < 1.0); renderQuad(batch, minCorner, maxCorner, MIN_TEX_COORD, MAX_TEX_COORD, color, id); } @@ -2115,26 +2115,38 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { } } -void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bool isLayered) { - if (!_gridPipeline) { +void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bool transparent) { + if (!_gridPipelineOpaque || !_gridPipelineTransparent) { auto program = gpu::Shader::createProgram(shader::render_utils::program::grid); - _gridSlot = 0; - auto stateLayered = std::make_shared(); - stateLayered->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); - PrepareStencil::testMask(*stateLayered); - _gridPipelineLayered = gpu::Pipeline::create(program, stateLayered); - - auto state = std::make_shared(stateLayered->getValues()); const float DEPTH_BIAS = 0.001f; - state->setDepthBias(DEPTH_BIAS); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - PrepareStencil::testMaskDrawShape(*state); - _gridPipeline = gpu::Pipeline::create(program, state); + + { + auto state = std::make_shared(); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMaskDrawShape(*state); + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthBias(DEPTH_BIAS); + _gridPipelineOpaque = gpu::Pipeline::create(program, state); + } + + { + auto state = std::make_shared(); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMask(*state); + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthBias(DEPTH_BIAS); + _gridPipelineTransparent = gpu::Pipeline::create(program, state); + } } - gpu::PipelinePointer pipeline = isLayered ? _gridPipelineLayered : _gridPipeline; - batch.setPipeline(pipeline); - batch.setUniformBuffer(_gridSlot, gridBuffer); + batch.setPipeline(transparent ? _gridPipelineTransparent : _gridPipelineOpaque); + batch.setUniformBuffer(0, gridBuffer); } diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index fcbf5ee128..589be4dcc1 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -270,11 +270,7 @@ public: void renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, int majorRows, int majorCols, float majorEdge, int minorRows, int minorCols, float minorEdge, - const glm::vec4& color, bool isLayered, int id); - void renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, - int rows, int cols, float edge, const glm::vec4& color, bool isLayered, int id) { - renderGrid(batch, minCorner, maxCorner, rows, cols, edge, 0, 0, 0.0f, color, isLayered, id); - } + const glm::vec4& color, int id); void renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id); @@ -414,9 +410,8 @@ private: }; using GridBuffer = gpu::BufferView; void useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bool isLayered); - gpu::PipelinePointer _gridPipeline; - gpu::PipelinePointer _gridPipelineLayered; - int _gridSlot; + gpu::PipelinePointer _gridPipelineOpaque; + gpu::PipelinePointer _gridPipelineTransparent; class BatchItemDetails { public: From 50efb48a584f452f848490fd05fbc91959dc8263 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Thu, 6 Dec 2018 12:26:18 -0800 Subject: [PATCH 3/4] Update GeometryCache.cpp --- libraries/render-utils/src/GeometryCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 14249f5b9b..f11478f7e1 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -978,7 +978,7 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co } // Set the grid pipeline - useGridPipeline(batch, _registeredGridBuffers[id], color.a < 1.0); + useGridPipeline(batch, _registeredGridBuffers[id], color.a < 1.0f); renderQuad(batch, minCorner, maxCorner, MIN_TEX_COORD, MAX_TEX_COORD, color, id); } From 87947a7165d9bef9b9ed8da835dee12b0c75b8ef Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Sat, 22 Dec 2018 03:31:38 -0500 Subject: [PATCH 4/4] try to fix grid color issue --- libraries/render-utils/src/GeometryCache.cpp | 54 ++++++++++--------- libraries/render-utils/src/grid.slf | 16 ++---- .../render-utils/src/grid_translucent.slf | 41 ++++++++++++++ .../src/render-utils/grid_translucent.slp | 1 + 4 files changed, 76 insertions(+), 36 deletions(-) create mode 100644 libraries/render-utils/src/grid_translucent.slf create mode 100644 libraries/render-utils/src/render-utils/grid_translucent.slp diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index f11478f7e1..d6d6f4903e 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -944,42 +944,44 @@ void GeometryCache::renderWireSphere(gpu::Batch& batch, const glm::vec4& color) } void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, - int majorRows, int majorCols, float majorEdge, - int minorRows, int minorCols, float minorEdge, - const glm::vec4& color, int id) { - static const glm::vec2 MIN_TEX_COORD(0.0f, 0.0f); - static const glm::vec2 MAX_TEX_COORD(1.0f, 1.0f); - - bool registered = (id != UNKNOWN_ID); + int majorRows, int majorCols, float majorEdge, int minorRows, int minorCols, float minorEdge, + const glm::vec4& color, int id) { Vec2FloatPair majorKey(glm::vec2(majorRows, majorCols), majorEdge); Vec2FloatPair minorKey(glm::vec2(minorRows, minorCols), minorEdge); Vec2FloatPairPair key(majorKey, minorKey); // Make the gridbuffer - if (registered && (!_registeredGridBuffers.contains(id) || _lastRegisteredGridBuffer[id] != key)) { - GridSchema gridSchema; - GridBuffer gridBuffer = std::make_shared(sizeof(GridSchema), (const gpu::Byte*) &gridSchema); - - if (registered && _registeredGridBuffers.contains(id)) { - gridBuffer = _registeredGridBuffers[id]; + GridBuffer gridBuffer; + if (id != UNKNOWN_ID) { + auto gridBufferIter = _registeredGridBuffers.find(id); + bool hadGridBuffer = gridBufferIter != _registeredGridBuffers.end(); + if (hadGridBuffer) { + gridBuffer = gridBufferIter.value(); + } else { + GridSchema gridSchema; + gridBuffer = std::make_shared(sizeof(GridSchema), (const gpu::Byte*)&gridSchema); } - _registeredGridBuffers[id] = gridBuffer; - _lastRegisteredGridBuffer[id] = key; + if (!hadGridBuffer || _lastRegisteredGridBuffer[id] != key) { + _registeredGridBuffers[id] = gridBuffer; + _lastRegisteredGridBuffer[id] = key; - gridBuffer.edit().period = glm::vec4(majorRows, majorCols, minorRows, minorCols); - gridBuffer.edit().offset.x = -(majorEdge / majorRows) / 2; - gridBuffer.edit().offset.y = -(majorEdge / majorCols) / 2; - gridBuffer.edit().offset.z = -(minorEdge / minorRows) / 2; - gridBuffer.edit().offset.w = -(minorEdge / minorCols) / 2; - gridBuffer.edit().edge = glm::vec4(glm::vec2(majorEdge), - // If rows or columns are not set, do not draw minor gridlines - glm::vec2((minorRows != 0 && minorCols != 0) ? minorEdge : 0.0f)); + gridBuffer.edit().period = glm::vec4(majorRows, majorCols, minorRows, minorCols); + gridBuffer.edit().offset.x = -(majorEdge / majorRows) / 2; + gridBuffer.edit().offset.y = -(majorEdge / majorCols) / 2; + gridBuffer.edit().offset.z = -(minorEdge / minorRows) / 2; + gridBuffer.edit().offset.w = -(minorEdge / minorCols) / 2; + gridBuffer.edit().edge = glm::vec4(glm::vec2(majorEdge), + // If rows or columns are not set, do not draw minor gridlines + glm::vec2((minorRows != 0 && minorCols != 0) ? minorEdge : 0.0f)); + } } // Set the grid pipeline - useGridPipeline(batch, _registeredGridBuffers[id], color.a < 1.0f); + useGridPipeline(batch, gridBuffer, color.a < 1.0f); + static const glm::vec2 MIN_TEX_COORD(0.0f, 0.0f); + static const glm::vec2 MAX_TEX_COORD(1.0f, 1.0f); renderQuad(batch, minCorner, maxCorner, MIN_TEX_COORD, MAX_TEX_COORD, color, id); } @@ -2117,10 +2119,11 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bool transparent) { if (!_gridPipelineOpaque || !_gridPipelineTransparent) { - auto program = gpu::Shader::createProgram(shader::render_utils::program::grid); const float DEPTH_BIAS = 0.001f; + // FIXME: need forward pipelines { + auto program = gpu::Shader::createProgram(shader::render_utils::program::grid); auto state = std::make_shared(); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(false, @@ -2133,6 +2136,7 @@ void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bo } { + auto program = gpu::Shader::createProgram(shader::render_utils::program::grid_translucent); auto state = std::make_shared(); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(true, diff --git a/libraries/render-utils/src/grid.slf b/libraries/render-utils/src/grid.slf index 408a9ca190..50c420bc10 100644 --- a/libraries/render-utils/src/grid.slf +++ b/libraries/render-utils/src/grid.slf @@ -1,8 +1,6 @@ <@include gpu/Config.slh@> <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> -// grid.frag -// fragment shader // // Created by Zach Pomerantz on 2/16/2016. // Copyright 2016 High Fidelity, Inc. @@ -11,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + <@include gpu/ShaderConstants.h@> <@include gpu/Paint.slh@> @@ -21,26 +21,20 @@ struct Grid { }; LAYOUT(binding=0) uniform gridBuffer { - Grid grid; + Grid grid; }; -Grid getGrid() { return grid; } - layout(location=GPU_ATTR_TEXCOORD0) in vec2 varTexCoord0; layout(location=GPU_ATTR_COLOR) in vec4 varColor; -layout(location=0) out vec4 outFragColor; - void main(void) { - Grid grid = getGrid(); - float alpha = mix(paintGridMajorMinor(varTexCoord0, grid.offset, grid.period, grid.edge), paintGrid(varTexCoord0, grid.offset.xy, grid.period.xy, grid.edge.xy), float(grid.edge.z == 0.0)); - if (alpha == 0.0) { + if (alpha < 0.0001) { discard; } - outFragColor = vec4(varColor.xyz, varColor.w * alpha); + packDeferredFragmentUnlit(vec3(1.0, 0.0, 0.0), 1.0, varColor.xyz); } diff --git a/libraries/render-utils/src/grid_translucent.slf b/libraries/render-utils/src/grid_translucent.slf new file mode 100644 index 0000000000..bb61126991 --- /dev/null +++ b/libraries/render-utils/src/grid_translucent.slf @@ -0,0 +1,41 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gondelman on 12/22/18 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include DeferredBufferWrite.slh@> + +<@include gpu/ShaderConstants.h@> +<@include gpu/Paint.slh@> + +struct Grid { + vec4 period; + vec4 offset; + vec4 edge; +}; + +LAYOUT(binding=0) uniform gridBuffer { + Grid grid; +}; + +layout(location=GPU_ATTR_TEXCOORD0) in vec2 varTexCoord0; +layout(location=GPU_ATTR_COLOR) in vec4 varColor; + +void main(void) { + float alpha = mix(paintGridMajorMinor(varTexCoord0, grid.offset, grid.period, grid.edge), + paintGrid(varTexCoord0, grid.offset.xy, grid.period.xy, grid.edge.xy), + float(grid.edge.z == 0.0)); + alpha *= varColor.w; + + if (alpha < 0.0001) { + discard; + } + + packDeferredFragmentTranslucent(vec3(1.0, 0.0, 0.0), alpha, varColor.xyz, DEFAULT_ROUGHNESS); +} diff --git a/libraries/render-utils/src/render-utils/grid_translucent.slp b/libraries/render-utils/src/render-utils/grid_translucent.slp new file mode 100644 index 0000000000..c81b208f63 --- /dev/null +++ b/libraries/render-utils/src/render-utils/grid_translucent.slp @@ -0,0 +1 @@ +VERTEX standardTransformPNTC