mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +02:00
Merge pull request #8380 from highfidelity/fade
Add fade in loading effect
This commit is contained in:
commit
412052c285
40 changed files with 345 additions and 133 deletions
|
@ -780,7 +780,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderBevelCornersRect");
|
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderBevelCornersRect");
|
||||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, true, true, true);
|
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, true, true, true);
|
||||||
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height,
|
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height,
|
||||||
bevelDistance, backgroundColor);
|
bevelDistance, backgroundColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
auto pipeline = args->_pipeline;
|
auto pipeline = args->_pipeline;
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
pipeline = _isSolid ? geometryCache->getShapePipeline() : geometryCache->getWireShapePipeline();
|
pipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isSolid) {
|
if (_isSolid) {
|
||||||
|
@ -55,7 +55,7 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
||||||
batch->setModelTransform(transform);
|
batch->setModelTransform(transform);
|
||||||
geometryCache->renderSolidCubeInstance(*batch, cubeColor, pipeline);
|
geometryCache->renderSolidCubeInstance(*batch, cubeColor, pipeline);
|
||||||
} else {
|
} else {
|
||||||
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
|
geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
|
||||||
if (getIsDashedLine()) {
|
if (getIsDashedLine()) {
|
||||||
transform.setScale(1.0f);
|
transform.setScale(1.0f);
|
||||||
batch->setModelTransform(transform);
|
batch->setModelTransform(transform);
|
||||||
|
|
|
@ -57,12 +57,12 @@ void Line3DOverlay::render(RenderArgs* args) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
if (getIsDashedLine()) {
|
if (getIsDashedLine()) {
|
||||||
// TODO: add support for color to renderDashedLine()
|
// TODO: add support for color to renderDashedLine()
|
||||||
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
|
geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
|
||||||
geometryCache->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
geometryCache->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
||||||
} else if (_glow > 0.0f) {
|
} else if (_glow > 0.0f) {
|
||||||
geometryCache->renderGlowLine(*batch, _start, _end, colorv4, _glow, _glowWidth, _geometryCacheID);
|
geometryCache->renderGlowLine(*batch, _start, _end, colorv4, _glow, _glowWidth, _geometryCacheID);
|
||||||
} else {
|
} else {
|
||||||
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
|
geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
|
||||||
geometryCache->renderLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
geometryCache->renderLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
|
||||||
geometryCache->bindSimpleProgram(*batch);
|
geometryCache->bindSimpleProgram(*batch);
|
||||||
geometryCache->renderQuad(*batch, topLeft, bottomRight, rectangleColor);
|
geometryCache->renderQuad(*batch, topLeft, bottomRight, rectangleColor);
|
||||||
} else {
|
} else {
|
||||||
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
|
geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
|
||||||
if (getIsDashedLine()) {
|
if (getIsDashedLine()) {
|
||||||
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
|
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
|
||||||
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
|
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
|
||||||
|
|
|
@ -47,7 +47,7 @@ void Shape3DOverlay::render(RenderArgs* args) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
auto pipeline = args->_pipeline;
|
auto pipeline = args->_pipeline;
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
pipeline = _isSolid ? geometryCache->getShapePipeline() : geometryCache->getWireShapePipeline();
|
pipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
transform.setScale(dimensions);
|
transform.setScale(dimensions);
|
||||||
|
|
|
@ -46,7 +46,7 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
auto pipeline = args->_pipeline;
|
auto pipeline = args->_pipeline;
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
pipeline = _isSolid ? geometryCache->getShapePipeline() : geometryCache->getWireShapePipeline();
|
pipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isSolid) {
|
if (_isSolid) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace render {
|
||||||
if (payload->entity->getType() == EntityTypes::Light) {
|
if (payload->entity->getType() == EntityTypes::Light) {
|
||||||
return ItemKey::Builder::light();
|
return ItemKey::Builder::light();
|
||||||
}
|
}
|
||||||
if (payload && payload->entity->getType() == EntityTypes::PolyLine) {
|
if (payload && payload->entity->isTransparent()) {
|
||||||
return ItemKey::Builder::transparentShape();
|
return ItemKey::Builder::transparentShape();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,8 +96,17 @@ public: \
|
||||||
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override { _renderHelper.removeFromScene(self, scene, pendingChanges); } \
|
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override { _renderHelper.removeFromScene(self, scene, pendingChanges); } \
|
||||||
virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); _renderHelper.notifyChanged(); } \
|
virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); _renderHelper.notifyChanged(); } \
|
||||||
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); _renderHelper.notifyChanged(); } \
|
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); _renderHelper.notifyChanged(); } \
|
||||||
|
void checkFading() { \
|
||||||
|
bool transparent = isTransparent(); \
|
||||||
|
if (transparent != _prevIsTransparent) { \
|
||||||
|
_renderHelper.notifyChanged(); \
|
||||||
|
_isFading = false; \
|
||||||
|
_prevIsTransparent = transparent; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
private: \
|
private: \
|
||||||
SimpleRenderableEntityItem _renderHelper;
|
SimpleRenderableEntityItem _renderHelper; \
|
||||||
|
bool _prevIsTransparent { isTransparent() };
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_RenderableEntityItem_h
|
#endif // hifi_RenderableEntityItem_h
|
||||||
|
|
|
@ -28,6 +28,8 @@ EntityItemPointer RenderableLightEntityItem::factory(const EntityItemID& entityI
|
||||||
void RenderableLightEntityItem::render(RenderArgs* args) {
|
void RenderableLightEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RenderableLightEntityItem::render");
|
PerformanceTimer perfTimer("RenderableLightEntityItem::render");
|
||||||
assert(getType() == EntityTypes::Light);
|
assert(getType() == EntityTypes::Light);
|
||||||
|
checkFading();
|
||||||
|
|
||||||
glm::vec3 position = getPosition();
|
glm::vec3 position = getPosition();
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getDimensions();
|
||||||
glm::quat rotation = getRotation();
|
glm::quat rotation = getRotation();
|
||||||
|
@ -35,7 +37,7 @@ void RenderableLightEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
glm::vec3 color = toGlm(getXColor());
|
glm::vec3 color = toGlm(getXColor());
|
||||||
|
|
||||||
float intensity = getIntensity();
|
float intensity = getIntensity() * (_isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f);
|
||||||
float falloffRadius = getFalloffRadius();
|
float falloffRadius = getFalloffRadius();
|
||||||
float exponent = getExponent();
|
float exponent = getExponent();
|
||||||
float cutoff = glm::radians(getCutoff());
|
float cutoff = glm::radians(getCutoff());
|
||||||
|
|
|
@ -371,6 +371,12 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RMEIrender");
|
PerformanceTimer perfTimer("RMEIrender");
|
||||||
assert(getType() == EntityTypes::Model);
|
assert(getType() == EntityTypes::Model);
|
||||||
|
|
||||||
|
// When the individual mesh parts of a model finish fading, they will mark their Model as needing updating
|
||||||
|
// we will watch for that and ask the model to update it's render items
|
||||||
|
if (_model && _model->getRenderItemsNeedUpdate()) {
|
||||||
|
_model->updateRenderItems();
|
||||||
|
}
|
||||||
|
|
||||||
if (hasModel()) {
|
if (hasModel()) {
|
||||||
// Prepare the current frame
|
// Prepare the current frame
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,6 +92,9 @@ public:
|
||||||
|
|
||||||
render::ItemID getMetaRenderItem() { return _myMetaItem; }
|
render::ItemID getMetaRenderItem() { return _myMetaItem; }
|
||||||
|
|
||||||
|
// Transparency is handled in ModelMeshPartPayload
|
||||||
|
bool isTransparent() override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVariantMap parseTexturesToMap(QString textures);
|
QVariantMap parseTexturesToMap(QString textures);
|
||||||
void remapTextures();
|
void remapTextures();
|
||||||
|
|
|
@ -167,6 +167,8 @@ void RenderablePolyLineEntityItem::update(const quint64& now) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
||||||
|
checkFading();
|
||||||
|
|
||||||
QWriteLocker lock(&_quadReadWriteLock);
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
if (_points.size() < 2 || _normals.size () < 2 || _strokeWidths.size() < 2) {
|
if (_points.size() < 2 || _normals.size () < 2 || _strokeWidths.size() < 2) {
|
||||||
return;
|
return;
|
||||||
|
@ -204,5 +206,9 @@ void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
||||||
batch.setInputFormat(_format);
|
batch.setInputFormat(_format);
|
||||||
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||||
|
|
||||||
|
if (_isFading) {
|
||||||
|
batch._glColor4f(1.0f, 1.0f, 1.0f, Interpolate::calculateFadeRatio(_fadeStartTime));
|
||||||
|
}
|
||||||
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
|
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,9 @@ public:
|
||||||
|
|
||||||
virtual void render(RenderArgs* args) override;
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual void update(const quint64& now) override;
|
virtual void update(const quint64& now) override;
|
||||||
virtual bool needsToCallUpdate() const override { return true; };
|
virtual bool needsToCallUpdate() const override { return true; }
|
||||||
|
|
||||||
|
bool isTransparent() override { return true; }
|
||||||
|
|
||||||
SIMPLE_RENDERABLE();
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
|
@ -47,7 +49,6 @@ protected:
|
||||||
gpu::BufferView _uniformBuffer;
|
gpu::BufferView _uniformBuffer;
|
||||||
unsigned int _numVertices;
|
unsigned int _numVertices;
|
||||||
QVector<glm::vec3> _vertices;
|
QVector<glm::vec3> _vertices;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
|
|
||||||
void initializePolyVox();
|
void initializePolyVox();
|
||||||
|
|
||||||
virtual void somethingChangedNotification() {
|
virtual void somethingChangedNotification() override {
|
||||||
// This gets called from EnityItem::readEntityDataFromBuffer every time a packet describing
|
// This gets called from EnityItem::readEntityDataFromBuffer every time a packet describing
|
||||||
// this entity comes from the entity-server. It gets called even if nothing has actually changed
|
// this entity comes from the entity-server. It gets called even if nothing has actually changed
|
||||||
// (see the comment in EntityItem.cpp). If that gets fixed, this could be used to know if we
|
// (see the comment in EntityItem.cpp). If that gets fixed, this could be used to know if we
|
||||||
|
@ -58,19 +58,19 @@ public:
|
||||||
// _needsModelReload = true;
|
// _needsModelReload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint8_t getVoxel(int x, int y, int z);
|
virtual uint8_t getVoxel(int x, int y, int z) override;
|
||||||
virtual bool setVoxel(int x, int y, int z, uint8_t toValue);
|
virtual bool setVoxel(int x, int y, int z, uint8_t toValue) override;
|
||||||
|
|
||||||
void render(RenderArgs* args);
|
void render(RenderArgs* args) override;
|
||||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
void** intersectedObject, bool precisionPicking) const;
|
void** intersectedObject, bool precisionPicking) const override;
|
||||||
|
|
||||||
virtual void setVoxelData(QByteArray voxelData);
|
virtual void setVoxelData(QByteArray voxelData) override;
|
||||||
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize);
|
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize) override;
|
||||||
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle);
|
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) override;
|
||||||
|
|
||||||
glm::vec3 getSurfacePositionAdjustment() const;
|
glm::vec3 getSurfacePositionAdjustment() const;
|
||||||
glm::mat4 voxelToWorldMatrix() const;
|
glm::mat4 voxelToWorldMatrix() const;
|
||||||
|
@ -78,45 +78,45 @@ public:
|
||||||
glm::mat4 voxelToLocalMatrix() const;
|
glm::mat4 voxelToLocalMatrix() const;
|
||||||
glm::mat4 localToVoxelMatrix() const;
|
glm::mat4 localToVoxelMatrix() const;
|
||||||
|
|
||||||
virtual ShapeType getShapeType() const;
|
virtual ShapeType getShapeType() const override;
|
||||||
virtual bool shouldBePhysical() const { return !isDead(); }
|
virtual bool shouldBePhysical() const override { return !isDead(); }
|
||||||
virtual bool isReadyToComputeShape();
|
virtual bool isReadyToComputeShape() override;
|
||||||
virtual void computeShapeInfo(ShapeInfo& info);
|
virtual void computeShapeInfo(ShapeInfo& info) override;
|
||||||
|
|
||||||
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3& voxelCoords) const;
|
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3& voxelCoords) const override;
|
||||||
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3& worldCoords) const;
|
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3& worldCoords) const override;
|
||||||
virtual glm::vec3 voxelCoordsToLocalCoords(glm::vec3& voxelCoords) const;
|
virtual glm::vec3 voxelCoordsToLocalCoords(glm::vec3& voxelCoords) const override;
|
||||||
virtual glm::vec3 localCoordsToVoxelCoords(glm::vec3& localCoords) const;
|
virtual glm::vec3 localCoordsToVoxelCoords(glm::vec3& localCoords) const override;
|
||||||
|
|
||||||
// coords are in voxel-volume space
|
// coords are in voxel-volume space
|
||||||
virtual bool setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue);
|
virtual bool setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) override;
|
||||||
virtual bool setVoxelInVolume(glm::vec3 position, uint8_t toValue);
|
virtual bool setVoxelInVolume(glm::vec3 position, uint8_t toValue) override;
|
||||||
|
|
||||||
// coords are in world-space
|
// coords are in world-space
|
||||||
virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue);
|
virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue) override;
|
||||||
virtual bool setAll(uint8_t toValue);
|
virtual bool setAll(uint8_t toValue) override;
|
||||||
virtual bool setCuboid(const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int toValue);
|
virtual bool setCuboid(const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int toValue) override;
|
||||||
|
|
||||||
virtual void setXTextureURL(QString xTextureURL);
|
virtual void setXTextureURL(QString xTextureURL) override;
|
||||||
virtual void setYTextureURL(QString yTextureURL);
|
virtual void setYTextureURL(QString yTextureURL) override;
|
||||||
virtual void setZTextureURL(QString zTextureURL);
|
virtual void setZTextureURL(QString zTextureURL) override;
|
||||||
|
|
||||||
virtual bool addToScene(EntityItemPointer self,
|
virtual bool addToScene(EntityItemPointer self,
|
||||||
std::shared_ptr<render::Scene> scene,
|
std::shared_ptr<render::Scene> scene,
|
||||||
render::PendingChanges& pendingChanges);
|
render::PendingChanges& pendingChanges) override;
|
||||||
virtual void removeFromScene(EntityItemPointer self,
|
virtual void removeFromScene(EntityItemPointer self,
|
||||||
std::shared_ptr<render::Scene> scene,
|
std::shared_ptr<render::Scene> scene,
|
||||||
render::PendingChanges& pendingChanges);
|
render::PendingChanges& pendingChanges) override;
|
||||||
|
|
||||||
virtual void setXNNeighborID(const EntityItemID& xNNeighborID);
|
virtual void setXNNeighborID(const EntityItemID& xNNeighborID) override;
|
||||||
virtual void setYNNeighborID(const EntityItemID& yNNeighborID);
|
virtual void setYNNeighborID(const EntityItemID& yNNeighborID) override;
|
||||||
virtual void setZNNeighborID(const EntityItemID& zNNeighborID);
|
virtual void setZNNeighborID(const EntityItemID& zNNeighborID) override;
|
||||||
|
|
||||||
virtual void setXPNeighborID(const EntityItemID& xPNeighborID);
|
virtual void setXPNeighborID(const EntityItemID& xPNeighborID) override;
|
||||||
virtual void setYPNeighborID(const EntityItemID& yPNeighborID);
|
virtual void setYPNeighborID(const EntityItemID& yPNeighborID) override;
|
||||||
virtual void setZPNeighborID(const EntityItemID& zPNeighborID);
|
virtual void setZPNeighborID(const EntityItemID& zPNeighborID) override;
|
||||||
|
|
||||||
virtual void updateRegistrationPoint(const glm::vec3& value);
|
virtual void updateRegistrationPoint(const glm::vec3& value) override;
|
||||||
|
|
||||||
void setVoxelsFromData(QByteArray uncompressedData, quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize);
|
void setVoxelsFromData(QByteArray uncompressedData, quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize);
|
||||||
void forEachVoxelValue(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize,
|
void forEachVoxelValue(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize,
|
||||||
|
@ -131,6 +131,9 @@ public:
|
||||||
|
|
||||||
void setVolDataDirty() { withWriteLock([&] { _volDataDirty = true; }); }
|
void setVolDataDirty() { withWriteLock([&] { _volDataDirty = true; }); }
|
||||||
|
|
||||||
|
// Transparent polyvox didn't seem to be working so disable for now
|
||||||
|
bool isTransparent() override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
||||||
// may not match _voxelVolumeSize.
|
// may not match _voxelVolumeSize.
|
||||||
|
@ -161,7 +164,7 @@ private:
|
||||||
// these are run off the main thread
|
// these are run off the main thread
|
||||||
void decompressVolumeData();
|
void decompressVolumeData();
|
||||||
void compressVolumeDataAndSendEditPacket();
|
void compressVolumeDataAndSendEditPacket();
|
||||||
virtual void getMesh(); // recompute mesh
|
virtual void getMesh() override; // recompute mesh
|
||||||
void computeShapeInfoWorker();
|
void computeShapeInfoWorker();
|
||||||
|
|
||||||
// these are cached lookups of _xNNeighborID, _yNNeighborID, _zNNeighborID, _xPNeighborID, _yPNeighborID, _zPNeighborID
|
// these are cached lookups of _xNNeighborID, _yNNeighborID, _zNNeighborID, _xPNeighborID, _yPNeighborID, _zPNeighborID
|
||||||
|
|
|
@ -40,7 +40,6 @@ static std::array<GeometryCache::Shape, entity::NUM_SHAPES> MAPPING { {
|
||||||
GeometryCache::Cylinder,
|
GeometryCache::Cylinder,
|
||||||
} };
|
} };
|
||||||
|
|
||||||
|
|
||||||
RenderableShapeEntityItem::Pointer RenderableShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
RenderableShapeEntityItem::Pointer RenderableShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
Pointer entity = std::make_shared<RenderableShapeEntityItem>(entityID);
|
Pointer entity = std::make_shared<RenderableShapeEntityItem>(entityID);
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
|
@ -72,10 +71,21 @@ void RenderableShapeEntityItem::setUserData(const QString& value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RenderableShapeEntityItem::isTransparent() {
|
||||||
|
if (_procedural && _procedural->isFading()) {
|
||||||
|
float isFading = Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) < 1.0f;
|
||||||
|
_procedural->setIsFading(isFading);
|
||||||
|
return isFading;
|
||||||
|
} else {
|
||||||
|
return getLocalRenderAlpha() < 1.0f || EntityItem::isTransparent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RenderableShapeEntityItem::render(RenderArgs* args) {
|
void RenderableShapeEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RenderableShapeEntityItem::render");
|
PerformanceTimer perfTimer("RenderableShapeEntityItem::render");
|
||||||
//Q_ASSERT(getType() == EntityTypes::Shape);
|
//Q_ASSERT(getType() == EntityTypes::Shape);
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
|
checkFading();
|
||||||
|
|
||||||
if (!_procedural) {
|
if (!_procedural) {
|
||||||
_procedural.reset(new Procedural(getUserData()));
|
_procedural.reset(new Procedural(getUserData()));
|
||||||
|
@ -83,7 +93,7 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
|
||||||
_procedural->_fragmentSource = simple_frag;
|
_procedural->_fragmentSource = simple_frag;
|
||||||
_procedural->_state->setCullMode(gpu::State::CULL_NONE);
|
_procedural->_state->setCullMode(gpu::State::CULL_NONE);
|
||||||
_procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
_procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
_procedural->_state->setBlendFunction(false,
|
_procedural->_state->setBlendFunction(true,
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
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);
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
}
|
}
|
||||||
|
@ -102,14 +112,17 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
|
||||||
if (_procedural->ready()) {
|
if (_procedural->ready()) {
|
||||||
_procedural->prepare(batch, getPosition(), getDimensions(), getOrientation());
|
_procedural->prepare(batch, getPosition(), getDimensions(), getOrientation());
|
||||||
auto outColor = _procedural->getColor(color);
|
auto outColor = _procedural->getColor(color);
|
||||||
|
outColor.a *= _procedural->isFading() ? Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) : 1.0f;
|
||||||
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
||||||
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
|
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
|
||||||
} else {
|
} else {
|
||||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidShapeInstance(batch, MAPPING[_shape], color);
|
color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||||
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||||
|
geometryCache->renderSolidShapeInstance(batch, MAPPING[_shape], color, pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(MAPPING[_shape]);
|
static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(MAPPING[_shape]);
|
||||||
args->_details._trianglesRendered += (int)triCount;
|
args->_details._trianglesRendered += (int)triCount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,12 @@ public:
|
||||||
void render(RenderArgs* args) override;
|
void render(RenderArgs* args) override;
|
||||||
void setUserData(const QString& value) override;
|
void setUserData(const QString& value) override;
|
||||||
|
|
||||||
SIMPLE_RENDERABLE();
|
bool isTransparent() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<Procedural> _procedural;
|
std::unique_ptr<Procedural> _procedural { nullptr };
|
||||||
|
|
||||||
|
SIMPLE_RENDERABLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <Transform.h>
|
#include <Transform.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "RenderableTextEntityItem.h"
|
#include "RenderableTextEntityItem.h"
|
||||||
#include "GLMHelpers.h"
|
#include "GLMHelpers.h"
|
||||||
|
|
||||||
|
@ -29,10 +27,13 @@ EntityItemPointer RenderableTextEntityItem::factory(const EntityItemID& entityID
|
||||||
void RenderableTextEntityItem::render(RenderArgs* args) {
|
void RenderableTextEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RenderableTextEntityItem::render");
|
PerformanceTimer perfTimer("RenderableTextEntityItem::render");
|
||||||
Q_ASSERT(getType() == EntityTypes::Text);
|
Q_ASSERT(getType() == EntityTypes::Text);
|
||||||
|
checkFading();
|
||||||
|
|
||||||
static const float SLIGHTLY_BEHIND = -0.005f;
|
static const float SLIGHTLY_BEHIND = -0.005f;
|
||||||
glm::vec4 textColor = glm::vec4(toGlm(getTextColorX()), 1.0f);
|
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||||
glm::vec4 backgroundColor = glm::vec4(toGlm(getBackgroundColorX()), 1.0f);
|
bool transparent = fadeRatio < 1.0f;
|
||||||
|
glm::vec4 textColor = glm::vec4(toGlm(getTextColorX()), fadeRatio);
|
||||||
|
glm::vec4 backgroundColor = glm::vec4(toGlm(getBackgroundColorX()), fadeRatio);
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getDimensions();
|
||||||
|
|
||||||
// Render background
|
// Render background
|
||||||
|
@ -62,7 +63,7 @@ void RenderableTextEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
batch.setModelTransform(transformToTopLeft);
|
batch.setModelTransform(transformToTopLeft);
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, false, true);
|
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, transparent, false, false, true);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, minCorner, maxCorner, backgroundColor);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, minCorner, maxCorner, backgroundColor);
|
||||||
|
|
||||||
float scale = _lineHeight / _textRenderer->getFontSize();
|
float scale = _lineHeight / _textRenderer->getFontSize();
|
||||||
|
|
|
@ -164,6 +164,8 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableWebEntityItem::render(RenderArgs* args) {
|
void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||||
|
checkFading();
|
||||||
|
|
||||||
#ifdef WANT_EXTRA_DEBUGGING
|
#ifdef WANT_EXTRA_DEBUGGING
|
||||||
{
|
{
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
|
@ -181,6 +183,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||||
if (!buildWebSurface(static_cast<EntityTreeRenderer*>(args->_renderer))) {
|
if (!buildWebSurface(static_cast<EntityTreeRenderer*>(args->_renderer))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_fadeStartTime = usecTimestampNow();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,8 +210,11 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||||
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
|
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||||
|
batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio);
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(batch);
|
DependencyManager::get<GeometryCache>()->bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(batch);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableWebEntityItem::setSourceUrl(const QString& value) {
|
void RenderableWebEntityItem::setSourceUrl(const QString& value) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ void main(void) {
|
||||||
vec3 color = varColor.rgb;
|
vec3 color = varColor.rgb;
|
||||||
packDeferredFragmentTranslucent(
|
packDeferredFragmentTranslucent(
|
||||||
interpolatedNormal * frontCondition,
|
interpolatedNormal * frontCondition,
|
||||||
texel.a,
|
texel.a * varColor.a,
|
||||||
polyline.color * texel.rgb,
|
polyline.color * texel.rgb,
|
||||||
vec3(0.01, 0.01, 0.01),
|
vec3(0.01, 0.01, 0.01),
|
||||||
10.0);
|
10.0);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<@include gpu/Config.slh@>
|
<@include gpu/Config.slh@>
|
||||||
<$VERSION_HEADER$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
// model.frag
|
// polyvox.frag
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
// Created by Seth Alves on 2015-8-3
|
// Created by Seth Alves on 2015-8-3
|
||||||
|
@ -41,5 +41,13 @@ void main(void) {
|
||||||
vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x);
|
vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x);
|
||||||
vec4 diffuse = vec4(xyDiffuseScaled + xzDiffuseScaled + yzDiffuseScaled, 1.0);
|
vec4 diffuse = vec4(xyDiffuseScaled + xzDiffuseScaled + yzDiffuseScaled, 1.0);
|
||||||
|
|
||||||
packDeferredFragment(_normal, 1.0, vec3(diffuse), DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_EMISSIVE, DEFAULT_OCCLUSION, DEFAULT_SCATTERING);
|
packDeferredFragment(
|
||||||
|
_normal,
|
||||||
|
1.0,
|
||||||
|
vec3(diffuse),
|
||||||
|
DEFAULT_ROUGHNESS,
|
||||||
|
DEFAULT_METALLIC,
|
||||||
|
DEFAULT_EMISSIVE,
|
||||||
|
DEFAULT_OCCLUSION,
|
||||||
|
DEFAULT_SCATTERING);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2212,4 +2212,4 @@ void EntityItem::globalizeProperties(EntityItemProperties& properties, const QSt
|
||||||
}
|
}
|
||||||
QUuid empty;
|
QUuid empty;
|
||||||
properties.setParentID(empty);
|
properties.setParentID(empty);
|
||||||
}
|
}
|
|
@ -26,6 +26,7 @@
|
||||||
#include <Transform.h>
|
#include <Transform.h>
|
||||||
#include <Sound.h>
|
#include <Sound.h>
|
||||||
#include <SpatiallyNestable.h>
|
#include <SpatiallyNestable.h>
|
||||||
|
#include <Interpolate.h>
|
||||||
|
|
||||||
#include "EntityItemID.h"
|
#include "EntityItemID.h"
|
||||||
#include "EntityItemPropertiesDefaults.h"
|
#include "EntityItemPropertiesDefaults.h"
|
||||||
|
@ -435,6 +436,7 @@ public:
|
||||||
QUuid getOwningAvatarID() const { return _owningAvatarID; }
|
QUuid getOwningAvatarID() const { return _owningAvatarID; }
|
||||||
void setOwningAvatarID(const QUuid& owningAvatarID) { _owningAvatarID = owningAvatarID; }
|
void setOwningAvatarID(const QUuid& owningAvatarID) { _owningAvatarID = owningAvatarID; }
|
||||||
|
|
||||||
|
virtual bool isTransparent() { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -565,7 +567,8 @@ protected:
|
||||||
quint64 _lastUpdatedAngularVelocityTimestamp { 0 };
|
quint64 _lastUpdatedAngularVelocityTimestamp { 0 };
|
||||||
quint64 _lastUpdatedAccelerationTimestamp { 0 };
|
quint64 _lastUpdatedAccelerationTimestamp { 0 };
|
||||||
|
|
||||||
|
quint64 _fadeStartTime { usecTimestampNow() };
|
||||||
|
bool _isFading { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityItem_h
|
#endif // hifi_EntityItem_h
|
||||||
|
|
|
@ -175,6 +175,10 @@ void Procedural::parse(const QJsonObject& proceduralData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Procedural::ready() {
|
bool Procedural::ready() {
|
||||||
|
if (!_hasStartedFade) {
|
||||||
|
_fadeStartTime = usecTimestampNow();
|
||||||
|
}
|
||||||
|
|
||||||
// Load any changes to the procedural
|
// Load any changes to the procedural
|
||||||
// Check for changes atomically, in case they are currently being made
|
// Check for changes atomically, in case they are currently being made
|
||||||
if (_proceduralDataDirty) {
|
if (_proceduralDataDirty) {
|
||||||
|
@ -202,6 +206,10 @@ bool Procedural::ready() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_hasStartedFade) {
|
||||||
|
_hasStartedFade = true;
|
||||||
|
_isFading = true;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@ public:
|
||||||
const gpu::ShaderPointer& getShader() const { return _shader; }
|
const gpu::ShaderPointer& getShader() const { return _shader; }
|
||||||
|
|
||||||
glm::vec4 getColor(const glm::vec4& entityColor);
|
glm::vec4 getColor(const glm::vec4& entityColor);
|
||||||
|
quint64 getFadeStartTime() { return _fadeStartTime; }
|
||||||
|
bool isFading() { return _isFading; }
|
||||||
|
void setIsFading(bool isFading) { _isFading = isFading; }
|
||||||
|
|
||||||
uint8_t _version { 1 };
|
uint8_t _version { 1 };
|
||||||
|
|
||||||
|
@ -106,6 +109,10 @@ private:
|
||||||
|
|
||||||
void setupUniforms();
|
void setupUniforms();
|
||||||
void setupChannels(bool shouldCreate);
|
void setupChannels(bool shouldCreate);
|
||||||
|
|
||||||
|
quint64 _fadeStartTime;
|
||||||
|
bool _hasStartedFade { false };
|
||||||
|
bool _isFading { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,6 +73,8 @@ void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, vec3
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
_fragColor0 = vec4(albedo.rgb, alpha);
|
_fragColor0 = vec4(albedo.rgb, alpha);
|
||||||
|
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -398,26 +398,36 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
|
||||||
return INSTANCED_SOLID_STREAM_FORMAT;
|
return INSTANCED_SOLID_STREAM_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
render::ShapePipelinePointer GeometryCache::_simplePipeline;
|
render::ShapePipelinePointer GeometryCache::_simpleOpaquePipeline;
|
||||||
|
render::ShapePipelinePointer GeometryCache::_simpleTransparentPipeline;
|
||||||
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
|
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
|
||||||
|
|
||||||
GeometryCache::GeometryCache() :
|
GeometryCache::GeometryCache() :
|
||||||
_nextID(0) {
|
_nextID(0) {
|
||||||
buildShapes();
|
buildShapes();
|
||||||
GeometryCache::_simplePipeline =
|
GeometryCache::_simpleOpaquePipeline =
|
||||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(), nullptr,
|
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, false), nullptr,
|
||||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||||
// Set the defaults needed for a simple program
|
// Set the defaults needed for a simple program
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
|
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
|
||||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
GeometryCache::_simpleTransparentPipeline =
|
||||||
|
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, true, true, false), nullptr,
|
||||||
|
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||||
|
// Set the defaults needed for a simple program
|
||||||
|
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||||
|
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
|
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
|
||||||
|
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
|
}
|
||||||
|
);
|
||||||
GeometryCache::_simpleWirePipeline =
|
GeometryCache::_simpleWirePipeline =
|
||||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, true), nullptr,
|
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, true), nullptr,
|
||||||
[](const render::ShapePipeline&, gpu::Batch& batch) {}
|
[](const render::ShapePipeline&, gpu::Batch& batch) {});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GeometryCache::~GeometryCache() {
|
GeometryCache::~GeometryCache() {
|
||||||
|
@ -1704,6 +1714,7 @@ class SimpleProgramKey {
|
||||||
public:
|
public:
|
||||||
enum FlagBit {
|
enum FlagBit {
|
||||||
IS_TEXTURED_FLAG = 0,
|
IS_TEXTURED_FLAG = 0,
|
||||||
|
IS_TRANSPARENT_FLAG,
|
||||||
IS_CULLED_FLAG,
|
IS_CULLED_FLAG,
|
||||||
IS_UNLIT_FLAG,
|
IS_UNLIT_FLAG,
|
||||||
HAS_DEPTH_BIAS_FLAG,
|
HAS_DEPTH_BIAS_FLAG,
|
||||||
|
@ -1713,6 +1724,7 @@ public:
|
||||||
|
|
||||||
enum Flag {
|
enum Flag {
|
||||||
IS_TEXTURED = (1 << IS_TEXTURED_FLAG),
|
IS_TEXTURED = (1 << IS_TEXTURED_FLAG),
|
||||||
|
IS_TRANSPARENT = (1 << IS_TRANSPARENT_FLAG),
|
||||||
IS_CULLED = (1 << IS_CULLED_FLAG),
|
IS_CULLED = (1 << IS_CULLED_FLAG),
|
||||||
IS_UNLIT = (1 << IS_UNLIT_FLAG),
|
IS_UNLIT = (1 << IS_UNLIT_FLAG),
|
||||||
HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG),
|
HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG),
|
||||||
|
@ -1722,6 +1734,7 @@ public:
|
||||||
bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); }
|
bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); }
|
||||||
|
|
||||||
bool isTextured() const { return isFlag(IS_TEXTURED); }
|
bool isTextured() const { return isFlag(IS_TEXTURED); }
|
||||||
|
bool isTransparent() const { return isFlag(IS_TRANSPARENT); }
|
||||||
bool isCulled() const { return isFlag(IS_CULLED); }
|
bool isCulled() const { return isFlag(IS_CULLED); }
|
||||||
bool isUnlit() const { return isFlag(IS_UNLIT); }
|
bool isUnlit() const { return isFlag(IS_UNLIT); }
|
||||||
bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); }
|
bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); }
|
||||||
|
@ -1732,9 +1745,9 @@ public:
|
||||||
int getRaw() const { return *reinterpret_cast<const int*>(this); }
|
int getRaw() const { return *reinterpret_cast<const int*>(this); }
|
||||||
|
|
||||||
|
|
||||||
SimpleProgramKey(bool textured = false, bool culled = true,
|
SimpleProgramKey(bool textured = false, bool transparent = false, bool culled = true,
|
||||||
bool unlit = false, bool depthBias = false) {
|
bool unlit = false, bool depthBias = false) {
|
||||||
_flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) |
|
_flags = (textured ? IS_TEXTURED : 0) | (transparent ? IS_TRANSPARENT : 0) | (culled ? IS_CULLED : 0) |
|
||||||
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0);
|
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1771,7 +1784,7 @@ gpu::PipelinePointer GeometryCache::getSimpleSRGBTexturedUnlitNoTexAlphaPipeline
|
||||||
auto state = std::make_shared<gpu::State>();
|
auto state = std::make_shared<gpu::State>();
|
||||||
state->setCullMode(gpu::State::CULL_NONE);
|
state->setCullMode(gpu::State::CULL_NONE);
|
||||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
state->setBlendFunction(false,
|
state->setBlendFunction(true,
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
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);
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
|
||||||
|
@ -1781,8 +1794,8 @@ gpu::PipelinePointer GeometryCache::getSimpleSRGBTexturedUnlitNoTexAlphaPipeline
|
||||||
return _simpleSRGBTexturedUnlitNoTexAlphaPipeline;
|
return _simpleSRGBTexturedUnlitNoTexAlphaPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool unlit, bool depthBiased) {
|
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool transparent, bool culled, bool unlit, bool depthBiased) {
|
||||||
batch.setPipeline(getSimplePipeline(textured, culled, unlit, depthBiased));
|
batch.setPipeline(getSimplePipeline(textured, transparent, culled, unlit, depthBiased));
|
||||||
|
|
||||||
// If not textured, set a default albedo map
|
// If not textured, set a default albedo map
|
||||||
if (!textured) {
|
if (!textured) {
|
||||||
|
@ -1794,8 +1807,8 @@ void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool cul
|
||||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled, bool unlit, bool depthBiased) {
|
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transparent, bool culled, bool unlit, bool depthBiased) {
|
||||||
SimpleProgramKey config { textured, culled, unlit, depthBiased };
|
SimpleProgramKey config { textured, transparent, culled, unlit, depthBiased };
|
||||||
|
|
||||||
// Compile the shaders
|
// Compile the shaders
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
|
@ -1831,7 +1844,7 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled
|
||||||
state->setDepthBias(1.0f);
|
state->setDepthBias(1.0f);
|
||||||
state->setDepthBiasSlopeScale(1.0f);
|
state->setDepthBiasSlopeScale(1.0f);
|
||||||
}
|
}
|
||||||
state->setBlendFunction(false,
|
state->setBlendFunction(config.isTransparent(),
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
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);
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
|
||||||
|
|
|
@ -152,16 +152,17 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// Bind the pipeline and get the state to render static geometry
|
// Bind the pipeline and get the state to render static geometry
|
||||||
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool transparent = false, bool culled = true,
|
||||||
bool unlit = false, bool depthBias = false);
|
bool unlit = false, bool depthBias = false);
|
||||||
// Get the pipeline to render static geometry
|
// Get the pipeline to render static geometry
|
||||||
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool culled = true,
|
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true,
|
||||||
bool unlit = false, bool depthBias = false);
|
bool unlit = false, bool depthBias = false);
|
||||||
|
|
||||||
void bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(gpu::Batch& batch);
|
void bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(gpu::Batch& batch);
|
||||||
gpu::PipelinePointer getSimpleSRGBTexturedUnlitNoTexAlphaPipeline();
|
gpu::PipelinePointer getSimpleSRGBTexturedUnlitNoTexAlphaPipeline();
|
||||||
|
|
||||||
render::ShapePipelinePointer getShapePipeline() { return GeometryCache::_simplePipeline; }
|
render::ShapePipelinePointer getOpaqueShapePipeline() { return GeometryCache::_simpleOpaquePipeline; }
|
||||||
|
render::ShapePipelinePointer getTransparentShapePipeline() { return GeometryCache::_simpleTransparentPipeline; }
|
||||||
render::ShapePipelinePointer getWireShapePipeline() { return GeometryCache::_simpleWirePipeline; }
|
render::ShapePipelinePointer getWireShapePipeline() { return GeometryCache::_simpleWirePipeline; }
|
||||||
|
|
||||||
// Static (instanced) geometry
|
// Static (instanced) geometry
|
||||||
|
@ -169,42 +170,42 @@ public:
|
||||||
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||||
|
|
||||||
void renderSolidShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
void renderSolidShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||||
void renderSolidShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
void renderSolidShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||||
renderSolidShapeInstance(batch, shape, glm::vec4(color, 1.0f), pipeline);
|
renderSolidShapeInstance(batch, shape, glm::vec4(color, 1.0f), pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderWireShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
void renderWireShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||||
void renderWireShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
void renderWireShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||||
renderWireShapeInstance(batch, shape, glm::vec4(color, 1.0f), pipeline);
|
renderWireShapeInstance(batch, shape, glm::vec4(color, 1.0f), pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||||
renderSolidSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
renderSolidSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline);
|
||||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) {
|
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) {
|
||||||
renderWireSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
renderWireSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||||
renderSolidCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
renderSolidCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline);
|
||||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||||
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) {
|
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) {
|
||||||
renderWireCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
renderWireCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||||
|
@ -416,7 +417,8 @@ private:
|
||||||
|
|
||||||
gpu::ShaderPointer _simpleShader;
|
gpu::ShaderPointer _simpleShader;
|
||||||
gpu::ShaderPointer _unlitShader;
|
gpu::ShaderPointer _unlitShader;
|
||||||
static render::ShapePipelinePointer _simplePipeline;
|
static render::ShapePipelinePointer _simpleOpaquePipeline;
|
||||||
|
static render::ShapePipelinePointer _simpleTransparentPipeline;
|
||||||
static render::ShapePipelinePointer _simpleWirePipeline;
|
static render::ShapePipelinePointer _simpleWirePipeline;
|
||||||
gpu::PipelinePointer _glowLinePipeline;
|
gpu::PipelinePointer _glowLinePipeline;
|
||||||
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
||||||
|
|
|
@ -352,7 +352,6 @@ void ModelMeshPartPayload::initCache() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ModelMeshPartPayload::notifyLocationChanged() {
|
void ModelMeshPartPayload::notifyLocationChanged() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -392,6 +391,10 @@ ItemKey ModelMeshPartPayload::getKey() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_hasFinishedFade) {
|
||||||
|
builder.withTransparent();
|
||||||
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +446,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey::Builder builder;
|
ShapeKey::Builder builder;
|
||||||
if (isTranslucent) {
|
if (isTranslucent || !_hasFinishedFade) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
if (hasTangents) {
|
if (hasTangents) {
|
||||||
|
@ -484,9 +487,9 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) const {
|
||||||
batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2));
|
batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get rid of that extra call
|
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||||
if (!_hasColorAttrib) {
|
if (!_hasColorAttrib || fadeRatio < 1.0f) {
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,14 +516,30 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline:
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelMeshPartPayload::startFade() {
|
||||||
|
_fadeStartTime = usecTimestampNow();
|
||||||
|
_hasStartedFade = true;
|
||||||
|
_prevHasStartedFade = false;
|
||||||
|
_hasFinishedFade = false;
|
||||||
|
}
|
||||||
|
|
||||||
void ModelMeshPartPayload::render(RenderArgs* args) const {
|
void ModelMeshPartPayload::render(RenderArgs* args) const {
|
||||||
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
||||||
|
|
||||||
if (!_model->_readyWhenAdded || !_model->_isVisible) {
|
if (!_model->_readyWhenAdded || !_model->_isVisible || !_hasStartedFade) {
|
||||||
return; // bail asap
|
return; // bail asap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When an individual mesh parts like this finishes its fade, we will mark the Model as
|
||||||
|
// having render items that need updating
|
||||||
|
bool nextIsFading = _isFading ? isStillFading() : false;
|
||||||
|
if (_isFading != nextIsFading || _prevHasStartedFade != _hasStartedFade) {
|
||||||
|
_isFading = nextIsFading || _prevHasStartedFade != _hasStartedFade;
|
||||||
|
_hasFinishedFade = _prevHasStartedFade == _hasStartedFade && !_isFading;
|
||||||
|
_prevHasStartedFade = _hasStartedFade;
|
||||||
|
_model->setRenderItemsNeedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
gpu::Batch& batch = *(args->_batch);
|
gpu::Batch& batch = *(args->_batch);
|
||||||
|
|
||||||
if (!getShapeKey().isValid()) {
|
if (!getShapeKey().isValid()) {
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_MeshPartPayload_h
|
#ifndef hifi_MeshPartPayload_h
|
||||||
#define hifi_MeshPartPayload_h
|
#define hifi_MeshPartPayload_h
|
||||||
|
|
||||||
|
#include <Interpolate.h>
|
||||||
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
#include <render/Scene.h>
|
#include <render/Scene.h>
|
||||||
|
@ -81,6 +83,11 @@ public:
|
||||||
void notifyLocationChanged() override;
|
void notifyLocationChanged() override;
|
||||||
void updateTransformForSkinnedMesh(const Transform& transform, const Transform& offsetTransform, const QVector<glm::mat4>& clusterMatrices);
|
void updateTransformForSkinnedMesh(const Transform& transform, const Transform& offsetTransform, const QVector<glm::mat4>& clusterMatrices);
|
||||||
|
|
||||||
|
// Entity fade in
|
||||||
|
void startFade();
|
||||||
|
bool hasStartedFade() { return _hasStartedFade; }
|
||||||
|
bool isStillFading() const { return Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f; }
|
||||||
|
|
||||||
// Render Item interface
|
// Render Item interface
|
||||||
render::ItemKey getKey() const override;
|
render::ItemKey getKey() const override;
|
||||||
render::ShapeKey getShapeKey() const override; // shape interface
|
render::ShapeKey getShapeKey() const override; // shape interface
|
||||||
|
@ -99,6 +106,13 @@ public:
|
||||||
|
|
||||||
bool _isSkinned{ false };
|
bool _isSkinned{ false };
|
||||||
bool _isBlendShaped{ false };
|
bool _isBlendShaped{ false };
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint64 _fadeStartTime { 0 };
|
||||||
|
bool _hasStartedFade { false };
|
||||||
|
mutable bool _prevHasStartedFade{ false };
|
||||||
|
mutable bool _hasFinishedFade { false };
|
||||||
|
mutable bool _isFading { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
|
@ -174,6 +174,7 @@ void Model::setOffset(const glm::vec3& offset) {
|
||||||
void Model::updateRenderItems() {
|
void Model::updateRenderItems() {
|
||||||
|
|
||||||
_needsUpdateClusterMatrices = true;
|
_needsUpdateClusterMatrices = true;
|
||||||
|
_renderItemsNeedUpdate = false;
|
||||||
|
|
||||||
// queue up this work for later processing, at the end of update and just before rendering.
|
// queue up this work for later processing, at the end of update and just before rendering.
|
||||||
// the application will ensure only the last lambda is actually invoked.
|
// the application will ensure only the last lambda is actually invoked.
|
||||||
|
@ -211,6 +212,9 @@ void Model::updateRenderItems() {
|
||||||
render::PendingChanges pendingChanges;
|
render::PendingChanges pendingChanges;
|
||||||
foreach (auto itemID, self->_modelMeshRenderItems.keys()) {
|
foreach (auto itemID, self->_modelMeshRenderItems.keys()) {
|
||||||
pendingChanges.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, modelMeshOffset, deleteGeometryCounter](ModelMeshPartPayload& data) {
|
pendingChanges.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, modelMeshOffset, deleteGeometryCounter](ModelMeshPartPayload& data) {
|
||||||
|
if (!data.hasStartedFade() && data._model && data._model->isLoaded() && data._model->getGeometry()->areTexturesLoaded()) {
|
||||||
|
data.startFade();
|
||||||
|
}
|
||||||
// Ensure the model geometry was not reset between frames
|
// Ensure the model geometry was not reset between frames
|
||||||
if (data._model && data._model->isLoaded() && deleteGeometryCounter == data._model->_deleteGeometryCounter) {
|
if (data._model && data._model->isLoaded() && deleteGeometryCounter == data._model->_deleteGeometryCounter) {
|
||||||
// lazy update of cluster matrices used for rendering. We need to update them here, so we can correctly update the bounding box.
|
// lazy update of cluster matrices used for rendering. We need to update them here, so we can correctly update the bounding box.
|
||||||
|
|
|
@ -103,6 +103,8 @@ public:
|
||||||
bool isVisible() const { return _isVisible; }
|
bool isVisible() const { return _isVisible; }
|
||||||
|
|
||||||
void updateRenderItems();
|
void updateRenderItems();
|
||||||
|
void setRenderItemsNeedUpdate() { _renderItemsNeedUpdate = true; }
|
||||||
|
bool getRenderItemsNeedUpdate() { return _renderItemsNeedUpdate; }
|
||||||
AABox getRenderableMeshBound() const;
|
AABox getRenderableMeshBound() const;
|
||||||
|
|
||||||
bool maybeStartBlender();
|
bool maybeStartBlender();
|
||||||
|
@ -408,6 +410,8 @@ protected:
|
||||||
bool _visualGeometryRequestFailed { false };
|
bool _visualGeometryRequestFailed { false };
|
||||||
bool _collisionGeometryRequestFailed { false };
|
bool _collisionGeometryRequestFailed { false };
|
||||||
|
|
||||||
|
bool _renderItemsNeedUpdate { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _loadingPriority { 0.0f };
|
float _loadingPriority { 0.0f };
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ void main() {
|
||||||
|
|
||||||
packDeferredFragmentTranslucent(
|
packDeferredFragmentTranslucent(
|
||||||
normalize(_normal),
|
normalize(_normal),
|
||||||
a,
|
a * Color.a,
|
||||||
Color.rgb,
|
Color.rgb,
|
||||||
DEFAULT_FRESNEL,
|
DEFAULT_FRESNEL,
|
||||||
DEFAULT_ROUGHNESS);
|
DEFAULT_ROUGHNESS);
|
||||||
|
|
|
@ -49,11 +49,43 @@ void main(void) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (emissiveAmount > 0.0) {
|
const float ALPHA_THRESHOLD = 0.999;
|
||||||
packDeferredFragmentLightmap(
|
if (_color.a < ALPHA_THRESHOLD) {
|
||||||
normal, 1.0, diffuse, max(0, 1.0 - shininess / 128.0), DEFAULT_METALLIC, specular, specular);
|
if (emissiveAmount > 0.0) {
|
||||||
|
packDeferredFragmentTranslucent(
|
||||||
|
normal,
|
||||||
|
_color.a,
|
||||||
|
specular,
|
||||||
|
DEFAULT_FRESNEL,
|
||||||
|
DEFAULT_ROUGHNESS);
|
||||||
|
} else {
|
||||||
|
packDeferredFragmentTranslucent(
|
||||||
|
normal,
|
||||||
|
_color.a,
|
||||||
|
diffuse,
|
||||||
|
DEFAULT_FRESNEL,
|
||||||
|
DEFAULT_ROUGHNESS);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
packDeferredFragment(
|
if (emissiveAmount > 0.0) {
|
||||||
normal, 1.0, diffuse, max(0, 1.0 - shininess / 128.0), length(specular), DEFAULT_EMISSIVE, DEFAULT_OCCLUSION, DEFAULT_SCATTERING);
|
packDeferredFragmentLightmap(
|
||||||
|
normal,
|
||||||
|
1.0,
|
||||||
|
diffuse,
|
||||||
|
max(0, 1.0 - shininess / 128.0),
|
||||||
|
DEFAULT_METALLIC,
|
||||||
|
specular,
|
||||||
|
specular);
|
||||||
|
} else {
|
||||||
|
packDeferredFragment(
|
||||||
|
normal,
|
||||||
|
1.0,
|
||||||
|
diffuse,
|
||||||
|
max(0, 1.0 - shininess / 128.0),
|
||||||
|
length(specular),
|
||||||
|
DEFAULT_EMISSIVE,
|
||||||
|
DEFAULT_OCCLUSION,
|
||||||
|
DEFAULT_SCATTERING);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,18 @@ void main(void) {
|
||||||
vec4 texel = texture(originalTexture, _texCoord0.st);
|
vec4 texel = texture(originalTexture, _texCoord0.st);
|
||||||
texel = colorToLinearRGBA(texel);
|
texel = colorToLinearRGBA(texel);
|
||||||
|
|
||||||
packDeferredFragmentUnlit(
|
const float ALPHA_THRESHOLD = 0.999;
|
||||||
normalize(_normal),
|
if (_color.a < ALPHA_THRESHOLD) {
|
||||||
1.0,
|
packDeferredFragmentTranslucent(
|
||||||
_color.rgb * texel.rgb);
|
normalize(_normal),
|
||||||
|
_color.a,
|
||||||
|
_color.rgb * texel.rgb,
|
||||||
|
DEFAULT_FRESNEL,
|
||||||
|
DEFAULT_ROUGHNESS);
|
||||||
|
} else {
|
||||||
|
packDeferredFragmentUnlit(
|
||||||
|
normalize(_normal),
|
||||||
|
1.0,
|
||||||
|
_color.rgb * texel.rgb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,13 +29,24 @@ void main(void) {
|
||||||
if (_color.a <= 0.0) {
|
if (_color.a <= 0.0) {
|
||||||
texel = colorToLinearRGBA(texel);
|
texel = colorToLinearRGBA(texel);
|
||||||
}
|
}
|
||||||
packDeferredFragment(
|
|
||||||
normalize(_normal.xyz),
|
const float ALPHA_THRESHOLD = 0.999;
|
||||||
texel.a,
|
if (_color.a * texel.a < ALPHA_THRESHOLD) {
|
||||||
_color.rgb * texel.rgb,
|
packDeferredFragmentTranslucent(
|
||||||
DEFAULT_ROUGHNESS,
|
normalize(_normal),
|
||||||
DEFAULT_METALLIC,
|
_color.a * texel.a,
|
||||||
DEFAULT_EMISSIVE,
|
_color.rgb * texel.rgb,
|
||||||
DEFAULT_OCCLUSION,
|
DEFAULT_FRESNEL,
|
||||||
DEFAULT_SCATTERING);
|
DEFAULT_ROUGHNESS);
|
||||||
|
} else {
|
||||||
|
packDeferredFragment(
|
||||||
|
normalize(_normal),
|
||||||
|
1.0,
|
||||||
|
_color.rgb * texel.rgb,
|
||||||
|
DEFAULT_ROUGHNESS,
|
||||||
|
DEFAULT_METALLIC,
|
||||||
|
DEFAULT_EMISSIVE,
|
||||||
|
DEFAULT_OCCLUSION,
|
||||||
|
DEFAULT_SCATTERING);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -29,8 +29,18 @@ void main(void) {
|
||||||
texel = colorToLinearRGBA(texel);
|
texel = colorToLinearRGBA(texel);
|
||||||
}
|
}
|
||||||
|
|
||||||
packDeferredFragmentUnlit(
|
const float ALPHA_THRESHOLD = 0.999;
|
||||||
normalize(_normal),
|
if (_color.a * texel.a < ALPHA_THRESHOLD) {
|
||||||
texel.a,
|
packDeferredFragmentTranslucent(
|
||||||
_color.rgb * texel.rgb);
|
normalize(_normal),
|
||||||
|
_color.a * texel.a,
|
||||||
|
_color.rgb * texel.rgb,
|
||||||
|
DEFAULT_FRESNEL,
|
||||||
|
DEFAULT_ROUGHNESS);
|
||||||
|
} else {
|
||||||
|
packDeferredFragmentUnlit(
|
||||||
|
normalize(_normal),
|
||||||
|
1.0,
|
||||||
|
_color.rgb * texel.rgb);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,8 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "NumericalConstants.h"
|
||||||
|
|
||||||
float Interpolate::bezierInterpolate(float y1, float y2, float y3, float u) {
|
float Interpolate::bezierInterpolate(float y1, float y2, float y3, float u) {
|
||||||
// https://en.wikipedia.org/wiki/Bezier_curve
|
// https://en.wikipedia.org/wiki/Bezier_curve
|
||||||
assert(0.0f <= u && u <= 1.0f);
|
assert(0.0f <= u && u <= 1.0f);
|
||||||
|
@ -58,3 +60,13 @@ float Interpolate::interpolate3Points(float y1, float y2, float y3, float u) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Interpolate::calculateFadeRatio(quint64 start) {
|
||||||
|
const float FADE_TIME = 1.0f;
|
||||||
|
float t = 2.0f * std::min(((float)(usecTimestampNow() - start)) / ((float)(FADE_TIME * USECS_PER_SECOND)), 1.0f);
|
||||||
|
float fadeRatio = (t < 1.0f) ? 0.5f * powf(2.0f, 10.0f * (t - 1.0f)) : 0.5f * (-powf(2.0f, -10.0f * (t - 1.0f)) + 2.0f);
|
||||||
|
|
||||||
|
// The easing function isn't exactly 1 at t = 2, so we need to scale the whole function up slightly
|
||||||
|
const float EASING_SCALE = 1.001f;
|
||||||
|
return std::min(EASING_SCALE * fadeRatio, 1.0f);
|
||||||
|
}
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_Interpolate_h
|
#ifndef hifi_Interpolate_h
|
||||||
#define hifi_Interpolate_h
|
#define hifi_Interpolate_h
|
||||||
|
|
||||||
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
class Interpolate {
|
class Interpolate {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -22,6 +24,8 @@ public:
|
||||||
// Interpolate at position u [0.0 - 1.0] between y values equally spaced along the x-axis such that the interpolated values
|
// Interpolate at position u [0.0 - 1.0] between y values equally spaced along the x-axis such that the interpolated values
|
||||||
// pass through all three y values. Return value lies wholly within the range of y values passed in.
|
// pass through all three y values. Return value lies wholly within the range of y values passed in.
|
||||||
static float interpolate3Points(float y1, float y2, float y3, float u);
|
static float interpolate3Points(float y1, float y2, float y3, float u);
|
||||||
|
|
||||||
|
static float calculateFadeRatio(quint64 start);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Interpolate_h
|
#endif // hifi_Interpolate_h
|
||||||
|
|
|
@ -1109,9 +1109,6 @@ SelectionDisplay = (function() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entities.editEntity(entityID, {
|
|
||||||
localRenderAlpha: 0.1
|
|
||||||
});
|
|
||||||
Overlays.editOverlay(highlightBox, {
|
Overlays.editOverlay(highlightBox, {
|
||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,7 +78,7 @@ void FloorTextureTest::renderTest(size_t testId, RenderArgs* args) {
|
||||||
texture->incremementMinMip();
|
texture->incremementMinMip();
|
||||||
}
|
}
|
||||||
|
|
||||||
geometryCache->bindSimpleProgram(batch, true, true, true);
|
geometryCache->bindSimpleProgram(batch, true, false, true, true);
|
||||||
batch.setInputBuffer(0, vertexBuffer, 0, sizeof(Vertex));
|
batch.setInputBuffer(0, vertexBuffer, 0, sizeof(Vertex));
|
||||||
batch.setInputFormat(vertexFormat);
|
batch.setInputFormat(vertexFormat);
|
||||||
batch.setIndexBuffer(gpu::UINT16, indexBuffer, 0);
|
batch.setIndexBuffer(gpu::UINT16, indexBuffer, 0);
|
||||||
|
|
Loading…
Reference in a new issue