more improvements

This commit is contained in:
HifiExperiments 2020-10-20 17:12:23 -07:00
parent c664991f6f
commit 2dd612b926
21 changed files with 243 additions and 378 deletions

View file

@ -16,15 +16,6 @@
using namespace render;
using namespace render::entities;
bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (resultWithReadLock<bool>([&] {
return entity->getParentID() != _parentID;
})) {
return true;
}
return false;
}
void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
@ -255,11 +246,7 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
gpu::Batch& batch = *args->_batch;
// Don't render if our parent is set or our material is null
QUuid parentID;
withReadLock([&] {
parentID = _parentID;
});
if (!parentID.isNull()) {
if (!_parentID.isNull()) {
return;
}

View file

@ -27,7 +27,6 @@ public:
~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); }
private:
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;

View file

@ -64,84 +64,7 @@ ParticleEffectEntityRenderer::ParticleEffectEntityRenderer(const EntityItemPoint
});
}
bool ParticleEffectEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([&] {
return !_textureLoaded;
})) {
return true;
}
return Parent::needsRenderUpdate();
}
void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
auto newParticleProperties = entity->getParticleProperties();
if (!newParticleProperties.valid()) {
qCWarning(entitiesrenderer) << "Bad particle properties";
}
if (resultWithReadLock<bool>([&] { return _particleProperties != newParticleProperties; })) {
_timeUntilNextEmit = 0;
withWriteLock([&] {
_particleProperties = newParticleProperties;
if (!_prevEmitterShouldTrailInitialized) {
_prevEmitterShouldTrailInitialized = true;
_prevEmitterShouldTrail = _particleProperties.emission.shouldTrail;
}
});
}
withWriteLock([&] {
_pulseProperties = entity->getPulseProperties();
_shapeType = entity->getShapeType();
QString compoundShapeURL = entity->getCompoundShapeURL();
if (_compoundShapeURL != compoundShapeURL) {
_compoundShapeURL = compoundShapeURL;
_hasComputedTriangles = false;
fetchGeometryResource();
}
});
_emitting = entity->getIsEmitting();
bool textureEmpty = resultWithReadLock<bool>([&] { return _particleProperties.textures.isEmpty(); });
if (textureEmpty) {
if (_networkTexture) {
withWriteLock([&] {
_networkTexture.reset();
});
}
withWriteLock([&] {
_textureLoaded = true;
entity->setVisuallyReady(true);
});
} else {
bool textureNeedsUpdate = resultWithReadLock<bool>([&] {
return !_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures);
});
if (textureNeedsUpdate) {
withWriteLock([&] {
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_particleProperties.textures);
_textureLoaded = false;
entity->setVisuallyReady(false);
});
}
if (!_textureLoaded) {
emit requestRenderUpdate();
}
bool textureLoaded = resultWithReadLock<bool>([&] {
return _networkTexture && (_networkTexture->isLoaded() || _networkTexture->isFailed());
});
if (textureLoaded) {
withWriteLock([&] {
entity->setVisuallyReady(true);
_textureLoaded = true;
});
}
}
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] {
withWriteLock([&] {
@ -151,20 +74,66 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
}
void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
auto newParticleProperties = entity->getParticleProperties();
if (!newParticleProperties.valid()) {
qCWarning(entitiesrenderer) << "Bad particle properties";
}
if (_particleProperties != newParticleProperties) {
_timeUntilNextEmit = 0;
_particleProperties = newParticleProperties;
if (!_prevEmitterShouldTrailInitialized) {
_prevEmitterShouldTrailInitialized = true;
_prevEmitterShouldTrail = _particleProperties.emission.shouldTrail;
}
}
_pulseProperties = entity->getPulseProperties();
_shapeType = entity->getShapeType();
QString compoundShapeURL = entity->getCompoundShapeURL();
if (_compoundShapeURL != compoundShapeURL) {
_compoundShapeURL = compoundShapeURL;
_hasComputedTriangles = false;
fetchGeometryResource();
}
_emitting = entity->getIsEmitting();
if (_particleProperties.textures.isEmpty()) {
if (_networkTexture) {
_networkTexture.reset();
}
_textureLoaded = true;
entity->setVisuallyReady(true);
} else {
if (!_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures)) {
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_particleProperties.textures);
_textureLoaded = false;
entity->setVisuallyReady(false);
}
if (!_textureLoaded) {
emit requestRenderUpdate();
}
if (_networkTexture && (_networkTexture->isLoaded() || _networkTexture->isFailed())) {
entity->setVisuallyReady(true);
_textureLoaded = true;
}
}
// Fill in Uniforms structure
ParticleUniforms particleUniforms;
withReadLock([&] {
particleUniforms.radius.start = _particleProperties.radius.range.start;
particleUniforms.radius.middle = _particleProperties.radius.gradient.target;
particleUniforms.radius.finish = _particleProperties.radius.range.finish;
particleUniforms.radius.spread = _particleProperties.radius.gradient.spread;
particleUniforms.spin.start = _particleProperties.spin.range.start;
particleUniforms.spin.middle = _particleProperties.spin.gradient.target;
particleUniforms.spin.finish = _particleProperties.spin.range.finish;
particleUniforms.spin.spread = _particleProperties.spin.gradient.spread;
particleUniforms.lifespan = _particleProperties.lifespan;
particleUniforms.rotateWithEntity = _particleProperties.rotateWithEntity ? 1 : 0;
});
particleUniforms.radius.start = _particleProperties.radius.range.start;
particleUniforms.radius.middle = _particleProperties.radius.gradient.target;
particleUniforms.radius.finish = _particleProperties.radius.range.finish;
particleUniforms.radius.spread = _particleProperties.radius.gradient.spread;
particleUniforms.spin.start = _particleProperties.spin.range.start;
particleUniforms.spin.middle = _particleProperties.spin.gradient.target;
particleUniforms.spin.finish = _particleProperties.spin.range.finish;
particleUniforms.spin.spread = _particleProperties.spin.gradient.spread;
particleUniforms.lifespan = _particleProperties.lifespan;
particleUniforms.rotateWithEntity = _particleProperties.rotateWithEntity ? 1 : 0;
// Update particle uniforms
_uniformBuffer.edit<ParticleUniforms>() = particleUniforms;
}
@ -403,27 +372,18 @@ void ParticleEffectEntityRenderer::stepSimulation() {
const auto interval = std::min<uint64_t>(USECS_PER_SECOND / 60, now - _lastSimulated);
_lastSimulated = now;
particle::Properties particleProperties;
ShapeType shapeType;
GeometryResource::Pointer geometryResource;
withReadLock([&] {
particleProperties = _particleProperties;
shapeType = _shapeType;
geometryResource = _geometryResource;
});
const auto& modelTransform = getModelTransform();
if (_emitting && particleProperties.emitting() &&
(shapeType != SHAPE_TYPE_COMPOUND || (geometryResource && geometryResource->isLoaded()))) {
uint64_t emitInterval = particleProperties.emitIntervalUsecs();
if (_emitting && _particleProperties.emitting() &&
(_shapeType != SHAPE_TYPE_COMPOUND || (_geometryResource && _geometryResource->isLoaded()))) {
uint64_t emitInterval = _particleProperties.emitIntervalUsecs();
if (emitInterval > 0 && interval >= _timeUntilNextEmit) {
auto timeRemaining = interval;
while (timeRemaining > _timeUntilNextEmit) {
if (_shapeType == SHAPE_TYPE_COMPOUND && !_hasComputedTriangles) {
computeTriangles(geometryResource->getHFMModel());
computeTriangles(_geometryResource->getHFMModel());
}
// emit particle
_cpuParticles.push_back(createParticle(modelTransform, particleProperties, shapeType, geometryResource, _triangleInfo));
_cpuParticles.push_back(createParticle(modelTransform, _particleProperties, _shapeType, _geometryResource, _triangleInfo));
_timeUntilNextEmit = emitInterval;
if (emitInterval < timeRemaining) {
timeRemaining -= emitInterval;
@ -435,14 +395,14 @@ void ParticleEffectEntityRenderer::stepSimulation() {
}
// Kill any particles that have expired or are over the max size
while (_cpuParticles.size() > particleProperties.maxParticles || (!_cpuParticles.empty() && _cpuParticles.front().expiration == 0)) {
while (_cpuParticles.size() > _particleProperties.maxParticles || (!_cpuParticles.empty() && _cpuParticles.front().expiration == 0)) {
_cpuParticles.pop_front();
}
const float deltaTime = (float)interval / (float)USECS_PER_SECOND;
// update the particles
for (auto& particle : _cpuParticles) {
if (_prevEmitterShouldTrail != particleProperties.emission.shouldTrail) {
if (_prevEmitterShouldTrail != _particleProperties.emission.shouldTrail) {
if (_prevEmitterShouldTrail) {
particle.relativePosition = particle.relativePosition + particle.basePosition - modelTransform.getTranslation();
}
@ -451,14 +411,14 @@ void ParticleEffectEntityRenderer::stepSimulation() {
particle.expiration = particle.expiration >= interval ? particle.expiration - interval : 0;
particle.integrate(deltaTime);
}
_prevEmitterShouldTrail = particleProperties.emission.shouldTrail;
_prevEmitterShouldTrail = _particleProperties.emission.shouldTrail;
// Build particle primitives
static GpuParticles gpuParticles;
gpuParticles.clear();
gpuParticles.reserve(_cpuParticles.size()); // Reserve space
std::transform(_cpuParticles.begin(), _cpuParticles.end(), std::back_inserter(gpuParticles), [&particleProperties, &modelTransform] (const CpuParticle& particle) {
glm::vec3 position = particle.relativePosition + (particleProperties.emission.shouldTrail ? particle.basePosition : modelTransform.getTranslation());
std::transform(_cpuParticles.begin(), _cpuParticles.end(), std::back_inserter(gpuParticles), [this, &modelTransform] (const CpuParticle& particle) {
glm::vec3 position = particle.relativePosition + (_particleProperties.emission.shouldTrail ? particle.basePosition : modelTransform.getTranslation());
return GpuParticle(position, glm::vec2(particle.lifetime, particle.seed));
});
@ -487,13 +447,14 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) {
// if the particles are marked rotateWithEntity
withReadLock([&] {
transform.setRotation(_renderTransform.getRotation());
auto& color = _uniformBuffer.edit<ParticleUniforms>().color;
color.start = EntityRenderer::calculatePulseColor(_particleProperties.getColorStart(), _pulseProperties, _created);
color.middle = EntityRenderer::calculatePulseColor(_particleProperties.getColorMiddle(), _pulseProperties, _created);
color.finish = EntityRenderer::calculatePulseColor(_particleProperties.getColorFinish(), _pulseProperties, _created);
color.spread = EntityRenderer::calculatePulseColor(_particleProperties.getColorSpread(), _pulseProperties, _created);
});
auto& color = _uniformBuffer.edit<ParticleUniforms>().color;
color.start = EntityRenderer::calculatePulseColor(_particleProperties.getColorStart(), _pulseProperties, _created);
color.middle = EntityRenderer::calculatePulseColor(_particleProperties.getColorMiddle(), _pulseProperties, _created);
color.finish = EntityRenderer::calculatePulseColor(_particleProperties.getColorFinish(), _pulseProperties, _created);
color.spread = EntityRenderer::calculatePulseColor(_particleProperties.getColorSpread(), _pulseProperties, _created);
batch.setModelTransform(transform);
batch.setUniformBuffer(0, _uniformBuffer);
batch.setInputFormat(_vertexFormat);

View file

@ -25,7 +25,6 @@ public:
ParticleEffectEntityRenderer(const EntityItemPointer& entity);
protected:
virtual bool needsRenderUpdate() const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;

View file

@ -121,16 +121,6 @@ ShapeKey PolyLineEntityRenderer::getShapeKey() {
return builder.build();
}
bool PolyLineEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([&] {
return (!_textureLoaded && _texture && _texture->isLoaded());
})) {
return true;
}
return Parent::needsRenderUpdate();
}
bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (entity->pointsChanged() || entity->widthsChanged() || entity->normalsChanged() || entity->texturesChanged() || entity->colorsChanged()) {
return true;
@ -140,6 +130,15 @@ bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP
}
void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] {
withWriteLock([&] {
_renderTransform = getModelTransform();
});
});
}
void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
auto pointsChanged = entity->pointsChanged();
auto widthsChanged = entity->widthsChanged();
auto normalsChanged = entity->normalsChanged();
@ -159,13 +158,15 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
if (!textures.isEmpty()) {
entityTextures = QUrl(textures);
}
withWriteLock([&] {
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
});
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
_textureAspectRatio = 1.0f;
_textureLoaded = false;
}
if (!_textureLoaded) {
emit requestRenderUpdate();
}
bool textureChanged = false;
if (!_textureLoaded && _texture && _texture->isLoaded()) {
textureChanged = true;
@ -175,13 +176,11 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
// Data
bool faceCameraChanged = faceCamera != _faceCamera;
withWriteLock([&] {
if (faceCameraChanged || glow != _glow) {
_faceCamera = faceCamera;
_glow = glow;
updateData();
}
});
if (faceCameraChanged || glow != _glow) {
_faceCamera = faceCamera;
_glow = glow;
updateData();
}
// Geometry
if (pointsChanged) {
@ -200,19 +199,10 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
bool uvModeStretchChanged = _isUVModeStretch != isUVModeStretch;
_isUVModeStretch = isUVModeStretch;
bool geometryChanged = uvModeStretchChanged || pointsChanged || widthsChanged || normalsChanged || colorsChanged || textureChanged || faceCameraChanged;
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, geometryChanged] {
withWriteLock([&] {
_renderTransform = getModelTransform();
if (geometryChanged) {
updateGeometry();
}
});
});
if (uvModeStretchChanged || pointsChanged || widthsChanged || normalsChanged || colorsChanged || textureChanged || faceCameraChanged) {
updateGeometry();
}
}
void PolyLineEntityRenderer::updateGeometry() {
@ -318,19 +308,16 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
Q_ASSERT(args->_batch);
gpu::Batch& batch = *args->_batch;
size_t numVertices;
Transform transform;
gpu::TexturePointer texture;
gpu::TexturePointer texture = _textureLoaded ? _texture->getGPUTexture() : DependencyManager::get<TextureCache>()->getWhiteTexture();
withReadLock([&] {
numVertices = _numVertices;
transform = _renderTransform;
texture = _textureLoaded ? _texture->getGPUTexture() : DependencyManager::get<TextureCache>()->getWhiteTexture();
batch.setResourceBuffer(0, _polylineGeometryBuffer);
batch.setUniformBuffer(0, _polylineDataBuffer);
});
if (numVertices < 2) {
batch.setResourceBuffer(0, _polylineGeometryBuffer);
batch.setUniformBuffer(0, _polylineDataBuffer);
if (_numVertices < 2) {
return;
}
@ -341,5 +328,5 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]);
batch.setModelTransform(transform);
batch.setResourceTexture(0, texture);
batch.draw(gpu::TRIANGLE_STRIP, (gpu::uint32)(2 * numVertices), 0);
batch.draw(gpu::TRIANGLE_STRIP, (gpu::uint32)(2 * _numVertices), 0);
}

View file

@ -30,9 +30,9 @@ public:
virtual bool isTransparent() const override;
protected:
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 doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual ItemKey getKey() override;
virtual ShapeKey getShapeKey() override;

View file

@ -1802,25 +1802,44 @@ ShapeKey PolyVoxEntityRenderer::getShapeKey() {
}
bool PolyVoxEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (entity->voxelToWorldMatrix() != _lastVoxelToWorldMatrix) {
if (resultWithReadLock<bool>([&] {
if (entity->voxelToWorldMatrix() != _lastVoxelToWorldMatrix) {
return true;
}
if (entity->_mesh != _mesh) {
return true;
}
return false;
})) {
return true;
}
if (entity->_mesh != _mesh) {
return true;
}
return false;
return Parent::needsRenderUpdateFromTypedEntity(entity);
}
void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT
if (!_hasTransitioned) {
transaction.resetTransitionOnItem(_renderItemID, render::Transition::ELEMENT_ENTER_DOMAIN);
_hasTransitioned = true;
}
#endif
}
void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
_lastVoxelToWorldMatrix = entity->voxelToWorldMatrix();
_lastVoxelVolumeSize = entity->getVoxelVolumeSize();
_params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0));
graphics::MeshPointer newMesh;
entity->withReadLock([&] {
newMesh = entity->_mesh;
});
if (newMesh && newMesh->getIndexBuffer()._buffer) {
_mesh = newMesh;
}
std::array<QString, 3> xyzTextureURLs{ {
entity->getXTextureURL(),
@ -1838,20 +1857,6 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s
}
}
void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
_lastVoxelToWorldMatrix = entity->voxelToWorldMatrix();
_lastVoxelVolumeSize = entity->getVoxelVolumeSize();
_params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0));
graphics::MeshPointer newMesh;
entity->withReadLock([&] {
newMesh = entity->_mesh;
});
if (newMesh && newMesh->getIndexBuffer()._buffer) {
_mesh = newMesh;
}
}
void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
if (!_mesh || !_mesh->getIndexBuffer()._buffer) {
return;

View file

@ -51,24 +51,7 @@ bool ShapeEntityRenderer::needsRenderUpdate() const {
return Parent::needsRenderUpdate();
}
bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (_dimensions != entity->getScaledDimensions()) {
return true;
}
if (_proceduralData != entity->getUserData()) {
return true;
}
return false;
}
void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
withWriteLock([&] {
_shape = entity->getShape();
_pulseProperties = entity->getPulseProperties();
});
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
withWriteLock([&] {
@ -86,47 +69,53 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
}
void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
_shape = entity->getShape();
_pulseProperties = entity->getPulseProperties();
bool materialChanged = false;
glm::vec3 color = toGlm(entity->getColor());
if (_color != color) {
_color = color;
_material->setAlbedo(color);
materialChanged = true;
}
float alpha = entity->getAlpha();
if (_alpha != alpha) {
_alpha = alpha;
_material->setOpacity(alpha);
materialChanged = true;
}
auto userData = entity->getUserData();
if (_proceduralData != userData) {
_proceduralData = userData;
_material->setProceduralData(_proceduralData);
materialChanged = true;
}
withReadLock([&] {
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) {
procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f);
}
}
});
withWriteLock([&] {
bool materialChanged = false;
glm::vec3 color = toGlm(entity->getColor());
if (_color != color) {
_color = color;
_material->setAlbedo(color);
materialChanged = true;
}
float alpha = entity->getAlpha();
if (_alpha != alpha) {
_alpha = alpha;
_material->setOpacity(alpha);
materialChanged = true;
}
auto userData = entity->getUserData();
if (_proceduralData != userData) {
_proceduralData = userData;
_material->setProceduralData(_proceduralData);
materialChanged = true;
}
auto materials = _materials.find("0");
if (materials != _materials.end()) {
if (materialChanged) {
materials->second.setNeedsUpdate(true);
}
bool requestUpdate = false;
if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials->second.top().material);
if (procedural->isFading()) {
procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f);
requestUpdate = true;
}
}
if (materials->second.shouldUpdate()) {
RenderPipelines::updateMultiMaterial(materials->second);
requestUpdate = true;
}
if (requestUpdate) {
emit requestRenderUpdate();
}
}
@ -231,13 +220,12 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
graphics::MultiMaterial materials;
auto geometryCache = DependencyManager::get<GeometryCache>();
GeometryCache::Shape geometryShape;
GeometryCache::Shape geometryShape = geometryCache->getShapeForEntityShape(_shape);
PrimitiveMode primitiveMode;
RenderLayer renderLayer;
glm::vec4 outColor;
Pipeline pipelineType;
withReadLock([&] {
geometryShape = geometryCache->getShapeForEntityShape(_shape);
primitiveMode = _primitiveMode;
renderLayer = _renderLayer;
batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation
@ -245,9 +233,10 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
pipelineType = getPipelineType(materials);
auto& schema = materials.getSchemaBuffer().get<graphics::MultiMaterial::Schema>();
outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity);
outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created);
});
outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created);
if (outColor.a == 0.0f) {
return;
}
@ -256,7 +245,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials.top().material);
outColor = procedural->getColor(outColor);
outColor.a *= procedural->isFading() ? Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) : 1.0f;
procedural->prepare(batch, _position, _dimensions, _orientation, _created, ProceduralProgramKey(outColor.a < 1.0f));
withReadLock([&] {
procedural->prepare(batch, _position, _dimensions, _orientation, _created, ProceduralProgramKey(outColor.a < 1.0f));
});
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || primitiveMode == PrimitiveMode::LINES) {
geometryCache->renderWireShape(batch, geometryShape, outColor);

View file

@ -30,7 +30,6 @@ protected:
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 doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;

View file

@ -92,14 +92,6 @@ uint32_t TextEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const {
return parentSubs;
}
bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (_dimensions != entity->getScaledDimensions()) {
return true;
}
return false;
}
void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
@ -112,26 +104,24 @@ void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
}
void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
withWriteLock([&] {
_pulseProperties = entity->getPulseProperties();
_text = entity->getText();
_lineHeight = entity->getLineHeight();
_textColor = toGlm(entity->getTextColor());
_textAlpha = entity->getTextAlpha();
_backgroundColor = toGlm(entity->getBackgroundColor());
_backgroundAlpha = entity->getBackgroundAlpha();
_billboardMode = entity->getBillboardMode();
_leftMargin = entity->getLeftMargin();
_rightMargin = entity->getRightMargin();
_topMargin = entity->getTopMargin();
_bottomMargin = entity->getBottomMargin();
_unlit = entity->getUnlit();
_font = entity->getFont();
_effect = entity->getTextEffect();
_effectColor = toGlm(entity->getTextEffectColor());
_effectThickness = entity->getTextEffectThickness();
updateTextRenderItem();
});
_pulseProperties = entity->getPulseProperties();
_text = entity->getText();
_lineHeight = entity->getLineHeight();
_textColor = toGlm(entity->getTextColor());
_textAlpha = entity->getTextAlpha();
_backgroundColor = toGlm(entity->getBackgroundColor());
_backgroundAlpha = entity->getBackgroundAlpha();
_billboardMode = entity->getBillboardMode();
_leftMargin = entity->getLeftMargin();
_rightMargin = entity->getRightMargin();
_topMargin = entity->getTopMargin();
_bottomMargin = entity->getBottomMargin();
_unlit = entity->getUnlit();
_font = entity->getFont();
_effect = entity->getTextEffect();
_effectColor = toGlm(entity->getTextEffectColor());
_effectThickness = entity->getTextEffectThickness();
updateTextRenderItem();
}
void TextEntityRenderer::doRender(RenderArgs* args) {
@ -141,25 +131,23 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
glm::vec4 backgroundColor;
Transform modelTransform;
BillboardMode billboardMode;
PrimitiveMode primitiveMode;
RenderLayer renderLayer;
withReadLock([&] {
modelTransform = _renderTransform;
billboardMode = _billboardMode;
primitiveMode = _primitiveMode;
renderLayer = _renderLayer;
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
backgroundColor = glm::vec4(_backgroundColor, fadeRatio * _backgroundAlpha);
backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created);
});
backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created);
if (backgroundColor.a <= 0.0f) {
return;
}
modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), billboardMode, args->getViewFrustum().getPosition()));
modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
batch.setModelTransform(modelTransform);
auto geometryCache = DependencyManager::get<GeometryCache>();
@ -323,53 +311,36 @@ void entities::TextPayload::render(RenderArgs* args) {
glm::vec3 dimensions;
BillboardMode billboardMode;
QString text;
glm::vec4 textColor;
QString font;
TextEffect effect;
glm::vec3 effectColor;
float effectThickness;
float lineHeight, leftMargin, rightMargin, topMargin, bottomMargin;
bool forward;
textRenderable->withReadLock([&] {
modelTransform = textRenderable->_renderTransform;
dimensions = textRenderable->_dimensions;
billboardMode = textRenderable->_billboardMode;
text = textRenderable->_text;
font = textRenderable->_font;
effect = textRenderable->_effect;
effectThickness = textRenderable->_effectThickness;
lineHeight = textRenderable->_lineHeight;
leftMargin = textRenderable->_leftMargin;
rightMargin = textRenderable->_rightMargin;
topMargin = textRenderable->_topMargin;
bottomMargin = textRenderable->_bottomMargin;
float fadeRatio = textRenderable->_isFading ? Interpolate::calculateFadeRatio(textRenderable->_fadeStartTime) : 1.0f;
textColor = glm::vec4(textRenderable->_textColor, fadeRatio * textRenderable->_textAlpha);
textColor = EntityRenderer::calculatePulseColor(textColor, textRenderable->_pulseProperties, textRenderable->_created);
effectColor = EntityRenderer::calculatePulseColor(textRenderable->_effectColor, textRenderable->_pulseProperties, textRenderable->_created);
forward = textRenderable->_renderLayer != RenderLayer::WORLD || args->_renderMethod == render::Args::FORWARD;
});
textColor = EntityRenderer::calculatePulseColor(textColor, textRenderable->_pulseProperties, textRenderable->_created);
glm::vec3 effectColor = EntityRenderer::calculatePulseColor(textRenderable->_effectColor, textRenderable->_pulseProperties, textRenderable->_created);
if (textColor.a <= 0.0f) {
return;
}
modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), billboardMode, args->getViewFrustum().getPosition()));
float scale = lineHeight / textRenderer->getFontSize();
float scale = textRenderable->_lineHeight / textRenderer->getFontSize();
modelTransform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z));
modelTransform.setScale(scale);
batch.setModelTransform(modelTransform);
glm::vec2 bounds = glm::vec2(dimensions.x - (leftMargin + rightMargin), dimensions.y - (topMargin + bottomMargin));
textRenderer->draw(batch, leftMargin / scale, -topMargin / scale, bounds / scale, scale,
text, font, textColor, effectColor, effectThickness, effect,
glm::vec2 bounds = glm::vec2(dimensions.x - (textRenderable->_leftMargin + textRenderable->_rightMargin), dimensions.y - (textRenderable->_topMargin + textRenderable->_bottomMargin));
textRenderer->draw(batch, textRenderable->_leftMargin / scale, -textRenderable->_topMargin / scale, bounds / scale, scale,
textRenderable->_text, textRenderable->_font, textColor, effectColor, textRenderable->_effectThickness, textRenderable->_effect,
textRenderable->_unlit, forward);
}

View file

@ -42,7 +42,6 @@ protected:
void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override;
private:
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;

View file

@ -125,16 +125,6 @@ bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointe
return false;
}
bool WebEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([this] {
return !_webSurface;
})) {
return true;
}
return Parent::needsRenderUpdate();
}
void WebEntityRenderer::onTimeout() {
uint64_t lastRenderTime;
if (!resultWithReadLock<bool>([&] {
@ -261,6 +251,8 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
_renderTransform.postScale(entity->getScaledDimensions());
});
});
} else {
emit requestRenderUpdate();
}
});
}
@ -339,8 +331,11 @@ void WebEntityRenderer::buildWebSurface(const EntityItemPointer& entity, const Q
return;
}
++_currentWebCount;
WebEntityRenderer::acquireWebSurface(newSourceURL, _contentType == ContentType::HtmlContent, _webSurface, _cachedWebSurface);
bool isHTML = _contentType == ContentType::HtmlContent;
if (isHTML) {
++_currentWebCount;
}
WebEntityRenderer::acquireWebSurface(newSourceURL, isHTML, _webSurface, _cachedWebSurface);
_fadeStartTime = usecTimestampNow();
_webSurface->resume();
@ -358,12 +353,15 @@ void WebEntityRenderer::destroyWebSurface() {
QSharedPointer<OffscreenQmlSurface> webSurface;
withWriteLock([&] {
webSurface.swap(_webSurface);
_contentType = ContentType::NoContent;
if (webSurface) {
--_currentWebCount;
if (_contentType == ContentType::HtmlContent) {
--_currentWebCount;
}
WebEntityRenderer::releaseWebSurface(webSurface, _cachedWebSurface, _connections);
}
_contentType = ContentType::NoContent;
});
}

View file

@ -55,7 +55,6 @@ public:
virtual QObject* getEventHandler() override;
protected:
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;

View file

@ -189,7 +189,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
CullTest::_containingZones.insert(_entityID);
}
void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
auto position = entity->getWorldPosition();
auto rotation = entity->getWorldOrientation();
auto dimensions = entity->getScaledDimensions();
@ -267,10 +267,6 @@ ItemKey ZoneEntityRenderer::getKey() {
}
bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (entity->getVisible() != _lastVisible) {
return true;
}
if (entity->keyLightPropertiesChanged() ||
entity->ambientLightPropertiesChanged() ||
entity->hazePropertiesChanged() ||
@ -280,29 +276,11 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
return true;
}
if (_skyboxTextureURL != entity->getSkyboxProperties().getURL()) {
return true;
}
if (entity->getWorldPosition() != _lastPosition) {
return true;
}
if (entity->getScaledDimensions() != _lastDimensions) {
return true;
}
if (entity->getWorldOrientation() != _lastRotation) {
return true;
}
if (entity->getUserData() != _proceduralUserData) {
return true;
}
return false;
}
void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity) {
setKeyLightMode((ComponentMode)entity->getKeyLightMode());
_keyLightMode = (ComponentMode)entity->getKeyLightMode();
const auto& sunLight = editSunLight();
sunLight->setType(graphics::Light::SUN);
@ -319,7 +297,7 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity
}
void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer& entity) {
setAmbientLightMode((ComponentMode)entity->getAmbientLightMode());
_ambientLightMode = (ComponentMode)entity->getAmbientLightMode();
const auto& ambientLight = editAmbientLight();
ambientLight->setType(graphics::Light::AMBIENT);
@ -339,11 +317,12 @@ void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer&
}
void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) {
setHazeMode((ComponentMode)entity->getHazeMode());
const uint32_t hazeMode = entity->getHazeMode();
_hazeMode = (ComponentMode)hazeMode;
const auto& haze = editHaze();
const uint32_t hazeMode = entity->getHazeMode();
haze->setHazeActive(hazeMode == COMPONENT_MODE_ENABLED);
haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect());
@ -367,7 +346,7 @@ void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity)
}
void ZoneEntityRenderer::updateBloomFromEntity(const TypedEntityPointer& entity) {
setBloomMode((ComponentMode)entity->getBloomMode());
_bloomMode = (ComponentMode)entity->getBloomMode();
const auto& bloom = editBloom();
@ -377,7 +356,7 @@ void ZoneEntityRenderer::updateBloomFromEntity(const TypedEntityPointer& entity)
}
void ZoneEntityRenderer::updateKeyBackgroundFromEntity(const TypedEntityPointer& entity) {
setSkyboxMode((ComponentMode)entity->getSkyboxMode());
_skyboxMode = (ComponentMode)entity->getSkyboxMode();
editBackground();
setSkyboxColor(toGlm(_skyboxProperties.getColor()));
@ -478,26 +457,6 @@ void ZoneEntityRenderer::updateSkyboxMap() {
}
}
void ZoneEntityRenderer::setHazeMode(ComponentMode mode) {
_hazeMode = mode;
}
void ZoneEntityRenderer::setKeyLightMode(ComponentMode mode) {
_keyLightMode = mode;
}
void ZoneEntityRenderer::setAmbientLightMode(ComponentMode mode) {
_ambientLightMode = mode;
}
void ZoneEntityRenderer::setSkyboxMode(ComponentMode mode) {
_skyboxMode = mode;
}
void ZoneEntityRenderer::setBloomMode(ComponentMode mode) {
_bloomMode = mode;
}
void ZoneEntityRenderer::setSkyboxColor(const glm::vec3& color) {
editSkybox()->setColor(color);
}

View file

@ -38,7 +38,7 @@ protected:
virtual ItemKey getKey() override;
virtual void doRender(RenderArgs* args) override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
private:
void updateKeyZoneItemFromEntity(const TypedEntityPointer& entity);
@ -52,12 +52,6 @@ private:
void setAmbientURL(const QString& ambientUrl);
void setSkyboxURL(const QString& skyboxUrl);
void setHazeMode(ComponentMode mode);
void setKeyLightMode(ComponentMode mode);
void setAmbientLightMode(ComponentMode mode);
void setSkyboxMode(ComponentMode mode);
void setBloomMode(ComponentMode mode);
void setSkyboxColor(const glm::vec3& color);
void setProceduralUserData(const QString& userData);

View file

@ -324,7 +324,6 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) {
withWriteLock([&] {
if (_compoundShapeURL.get() != url) {
_compoundShapeURL.set(url);
_needsRenderUpdate = true;
_flags |= Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS;
}
});

View file

@ -266,21 +266,21 @@ glm::u8vec3 PolyLineEntityItem::getColor() const {
void PolyLineEntityItem::setIsUVModeStretch(bool isUVModeStretch) {
withWriteLock([&] {
_needsRenderUpdate = _isUVModeStretch != isUVModeStretch;
_needsRenderUpdate |= _isUVModeStretch != isUVModeStretch;
_isUVModeStretch = isUVModeStretch;
});
}
void PolyLineEntityItem::setGlow(bool glow) {
withWriteLock([&] {
_needsRenderUpdate = _glow != glow;
_needsRenderUpdate |= _glow != glow;
_glow = glow;
});
}
void PolyLineEntityItem::setFaceCamera(bool faceCamera) {
withWriteLock([&] {
_needsRenderUpdate = _faceCamera != faceCamera;
_needsRenderUpdate |= _faceCamera != faceCamera;
_faceCamera = faceCamera;
});
}

View file

@ -442,4 +442,11 @@ PulsePropertyGroup ShapeEntityItem::getPulseProperties() const {
return resultWithReadLock<PulsePropertyGroup>([&] {
return _pulseProperties;
});
}
void ShapeEntityItem::setUserData(const QString& value) {
withWriteLock([&] {
_needsRenderUpdate |= _userData != value;
_userData = value;
});
}

View file

@ -101,6 +101,8 @@ public:
PulsePropertyGroup getPulseProperties() const;
void setUserData(const QString& value) override;
protected:
glm::u8vec3 _color;
float _alpha { 1.0f };

View file

@ -444,6 +444,13 @@ uint32_t ZoneEntityItem::getSkyboxMode() const {
return _skyboxMode;
}
void ZoneEntityItem::setUserData(const QString& value) {
withWriteLock([&] {
_needsRenderUpdate |= _userData != value;
_userData = value;
});
}
void ZoneEntityItem::fetchCollisionGeometryResource() {
QUrl hullURL(getCompoundShapeURL());
if (hullURL.isEmpty()) {

View file

@ -104,6 +104,8 @@ public:
uint32_t getScreenshare() const { return _screenshare; }
void setScreenshare(uint32_t value) { _screenshare = value; }
void setUserData(const QString& value) override;
bool keyLightPropertiesChanged() const { return _keyLightPropertiesChanged; }
bool ambientLightPropertiesChanged() const { return _ambientLightPropertiesChanged; }
bool skyboxPropertiesChanged() const { return _skyboxPropertiesChanged; }