diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 429a375f03..9656fa45fd 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -581,9 +581,11 @@ void Avatar::simulateAttachments(float deltaTime) { void Avatar::renderAttachments(RenderArgs* args) { // RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ? // RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE; + /* foreach (Model* model, _attachmentModels) { model->render(args, 1.0f); } + */ } void Avatar::updateJointMappings() { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8407824750..8a49d69129 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1580,12 +1580,16 @@ void MyAvatar::renderAttachments(RenderArgs* args) { QString headJointName = (geometry.headJointIndex == -1) ? QString() : geometry.joints.at(geometry.headJointIndex).name; // RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ? // RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE; + + // FIX ME - attachments need to be added to scene too... + /* for (int i = 0; i < _attachmentData.size(); i++) { const QString& jointName = _attachmentData.at(i).jointName; if (jointName != headJointName && jointName != "Head") { _attachmentModels.at(i)->render(args, 1.0f); } } + */ } //Renders sixense laser pointers for UI selection with controllers diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 73774759e7..822fff9808 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include "ModelOverlay.h" @@ -54,11 +55,34 @@ void ModelOverlay::update(float deltatime) { _isLoaded = _model.isActive(); } +bool ModelOverlay::addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges) { + Base3DOverlay::addToScene(overlay, scene, pendingChanges); + _model.addToScene(scene, pendingChanges); + return true; +} + +void ModelOverlay::removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges) { + Base3DOverlay::removeFromScene(overlay, scene, pendingChanges); + _model.removeFromScene(scene, pendingChanges); +} + void ModelOverlay::render(RenderArgs* args) { + + // check to see if when we added our model to the scene they were ready, if they were not ready, then + // fix them up in the scene + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::PendingChanges pendingChanges; + if (_model.needsFixupInScene()) { + _model.removeFromScene(scene, pendingChanges); + _model.addToScene(scene, pendingChanges); + } + scene->enqueuePendingChanges(pendingChanges); + if (!_visible) { return; } - + + /* if (_model.isActive()) { if (_model.isRenderable()) { float glowLevel = getGlowLevel(); @@ -72,6 +96,7 @@ void ModelOverlay::render(RenderArgs* args) { } } } + */ } void ModelOverlay::setProperties(const QScriptValue &properties) { diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 8cd095f778..a81cae530a 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -32,6 +32,9 @@ public: virtual ModelOverlay* createClone() const; + virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges); + virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges); + private: Model _model; diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 99f59810cb..745c2b4a10 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -228,3 +228,15 @@ float Overlay::updatePulse() { return _pulse; } +bool Overlay::addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges) { + auto overlayPayload = new Overlay::Payload(overlay); + auto overlayPayloadPointer = Overlay::PayloadPointer(overlayPayload); + _renderItemID = scene->allocateID(); + pendingChanges.resetItem(_renderItemID, overlayPayloadPointer); + return true; +} + +void Overlay::removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges) { + pendingChanges.removeItem(_renderItemID); +} + diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 74ffff9d24..1a808bc15c 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -48,6 +48,9 @@ public: virtual void update(float deltatime) {} virtual void render(RenderArgs* args) = 0; + virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges); + virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges); + // getters virtual bool is3D() const = 0; bool isLoaded() { return _isLoaded; } @@ -117,5 +120,11 @@ protected: QScriptEngine* _scriptEngine; }; +namespace render { + template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay); + template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay); + template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args); +} + #endif // hifi_Overlay_h diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 5964596395..6e579ed4c4 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -33,49 +33,6 @@ #include "Text3DOverlay.h" -namespace render { - template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) { - if (overlay->is3D() && !static_cast(overlay.get())->getDrawOnHUD()) { - if (static_cast(overlay.get())->getDrawInFront()) { - return ItemKey::Builder().withTypeShape().withNoDepthSort().build(); - } else { - return ItemKey::Builder::opaqueShape(); - } - } else { - return ItemKey::Builder().withTypeShape().withViewSpace().build(); - } - } - template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay) { - if (overlay->is3D()) { - return static_cast(overlay.get())->getBounds(); - } else { - QRect bounds = static_cast(overlay.get())->getBounds(); - return AABox(glm::vec3(bounds.x(), bounds.y(), 0.0f), glm::vec3(bounds.width(), bounds.height(), 0.1f)); - } - } - template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) { - if (args) { - args->_elementsTouched++; - - glPushMatrix(); - if (overlay->getAnchor() == Overlay::MY_AVATAR) { - MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); - glm::quat myAvatarRotation = avatar->getOrientation(); - glm::vec3 myAvatarPosition = avatar->getPosition(); - float angle = glm::degrees(glm::angle(myAvatarRotation)); - glm::vec3 axis = glm::axis(myAvatarRotation); - float myAvatarScale = avatar->getScale(); - - glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z); - glRotatef(angle, axis.x, axis.y, axis.z); - glScalef(myAvatarScale, myAvatarScale, myAvatarScale); - } - overlay->render(args); - glPopMatrix(); - } - } -} - Overlays::Overlays() : _nextOverlayID(1) { } @@ -118,6 +75,7 @@ void Overlays::update(float deltatime) { void Overlays::cleanupOverlaysToDelete() { if (!_overlaysToDelete.isEmpty()) { + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; { @@ -128,13 +86,12 @@ void Overlays::cleanupOverlaysToDelete() { auto itemID = overlay->getRenderItemID(); if (itemID != render::Item::INVALID_ITEM_ID) { - pendingChanges.removeItem(itemID); + overlay->removeFromScene(overlay, scene, pendingChanges); } } while (!_overlaysToDelete.isEmpty()); } if (pendingChanges._removedItems.size() > 0) { - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); scene->enqueuePendingChanges(pendingChanges); } } @@ -216,13 +173,9 @@ unsigned int Overlays::addOverlay(Overlay* overlay) { _overlaysWorld[thisID] = overlayPointer; render::ScenePointer scene = Application::getInstance()->getMain3DScene(); - auto overlayPayload = new Overlay::Payload(overlayPointer); - auto overlayPayloadPointer = Overlay::PayloadPointer(overlayPayload); - render::ItemID itemID = scene->allocateID(); - overlay->setRenderItemID(itemID); - render::PendingChanges pendingChanges; - pendingChanges.resetItem(itemID, overlayPayloadPointer); + + overlayPointer->addToScene(overlayPointer, scene, pendingChanges); scene->enqueuePendingChanges(pendingChanges); } diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp new file mode 100644 index 0000000000..b4be515a46 --- /dev/null +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -0,0 +1,77 @@ +// +// OverlaysPayload.cpp +// interface/src/ui/overlays +// +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include +#include + +#include +#include +#include +#include + +#include "BillboardOverlay.h" +#include "Circle3DOverlay.h" +#include "Cube3DOverlay.h" +#include "ImageOverlay.h" +#include "Line3DOverlay.h" +#include "LocalModelsOverlay.h" +#include "ModelOverlay.h" +#include "Overlays.h" +#include "Rectangle3DOverlay.h" +#include "Sphere3DOverlay.h" +#include "Grid3DOverlay.h" +#include "TextOverlay.h" +#include "Text3DOverlay.h" + + +namespace render { + template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) { + if (overlay->is3D() && !static_cast(overlay.get())->getDrawOnHUD()) { + if (static_cast(overlay.get())->getDrawInFront()) { + return ItemKey::Builder().withTypeShape().withNoDepthSort().build(); + } else { + return ItemKey::Builder::opaqueShape(); + } + } else { + return ItemKey::Builder().withTypeShape().withViewSpace().build(); + } + } + template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay) { + if (overlay->is3D()) { + return static_cast(overlay.get())->getBounds(); + } else { + QRect bounds = static_cast(overlay.get())->getBounds(); + return AABox(glm::vec3(bounds.x(), bounds.y(), 0.0f), glm::vec3(bounds.width(), bounds.height(), 0.1f)); + } + } + template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) { + if (args) { + args->_elementsTouched++; + + glPushMatrix(); + if (overlay->getAnchor() == Overlay::MY_AVATAR) { + MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); + glm::quat myAvatarRotation = avatar->getOrientation(); + glm::vec3 myAvatarPosition = avatar->getPosition(); + float angle = glm::degrees(glm::angle(myAvatarRotation)); + glm::vec3 axis = glm::axis(myAvatarRotation); + float myAvatarScale = avatar->getScale(); + + glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z); + glRotatef(angle, axis.x, axis.y, axis.z); + glScalef(myAvatarScale, myAvatarScale, myAvatarScale); + } + overlay->render(args); + glPopMatrix(); + } + } +} diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index cc6693133f..213a8de9a0 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -493,45 +493,22 @@ void EntityTreeRenderer::render(RenderArgs* renderArgs) { if (_tree && !_shuttingDown) { renderArgs->_renderer = this; - checkPendingAddToScene(renderArgs); - - Model::startScene(renderArgs->_renderSide); - - ViewFrustum* frustum = (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) ? - _viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum(); - - // Setup batch transform matrices - gpu::Batch batch; // FIX ME - this is very suspicious! - glm::mat4 projMat; - Transform viewMat; - frustum->evalProjectionMatrix(projMat); - frustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - - renderArgs->_batch = &batch; // FIX ME - this is very suspicious! - _tree->lockForRead(); // Whenever you're in an intersection between zones, we will always choose the smallest zone. _bestZone = NULL; // NOTE: Is this what we want? _bestZoneVolume = std::numeric_limits::max(); + + // FIX ME: right now the renderOperation does the following: + // 1) determining the best zone (not really rendering) + // 2) render the debug cell details + // we should clean this up _tree->recurseTreeWithOperation(renderOperation, renderArgs); applyZonePropertiesToScene(_bestZone); - // we must call endScene while we still have the tree locked so that no one deletes a model - // on us while rendering the scene - Model::endScene(renderArgs); _tree->unlock(); - // FIX ME - this is very suspicious! - // glPushMatrix(); - // renderArgs->_context->render(batch); - // glPopMatrix(); - - renderArgs->_batch = nullptr; - // stats... _meshesConsidered = renderArgs->_meshesConsidered; _meshesRendered = renderArgs->_meshesRendered; @@ -715,39 +692,6 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) } } } - - // hack for models and other entities that don't yet play well with others. :( - if (!entityItem->canRenderInScene()) { - // render entityItem - AABox entityBox = entityItem->getAABox(); - - // TODO: some entity types (like lights) might want to be rendered even - // when they are outside of the view frustum... - float distance = args->_viewFrustum->distanceToCamera(entityBox.calcCenter()); - - bool outOfView = args->_viewFrustum->boxInFrustum(entityBox) == ViewFrustum::OUTSIDE; - if (!outOfView) { - bool bigEnoughToRender = _viewState->shouldRenderMesh(entityBox.getLargestDimension(), distance); - - if (bigEnoughToRender) { - renderProxies(entityItem, args); - - Glower* glower = NULL; - if (entityItem->getGlowLevel() > 0.0f) { - glower = new Glower(args, entityItem->getGlowLevel()); - } - entityItem->render(args); - args->_itemsRendered++; - if (glower) { - delete glower; - } - } else { - args->_itemsTooSmall++; - } - } else { - args->_itemsOutOfView++; - } - } } } } @@ -1093,34 +1037,14 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) { // here's where we add the entity payload to the scene - if (entity && entity->canRenderInScene()) { - if (entity->readyToAddToScene()) { - render::PendingChanges pendingChanges; - auto scene = _viewState->getMain3DScene(); - if (entity->addToScene(entity, scene, pendingChanges)) { - _entitiesInScene.insert(entity); - } - scene->enqueuePendingChanges(pendingChanges); - } else { - if (!_pendingAddToScene.contains(entity)) { - _pendingAddToScene << entity; - } - } + render::PendingChanges pendingChanges; + auto scene = _viewState->getMain3DScene(); + if (entity->addToScene(entity, scene, pendingChanges)) { + _entitiesInScene.insert(entity); } + scene->enqueuePendingChanges(pendingChanges); } -void EntityTreeRenderer::checkPendingAddToScene(RenderArgs* renderArgs) { - QSet addedToScene; - foreach (auto entity, _pendingAddToScene) { - if (entity->readyToAddToScene(renderArgs)) { - addEntityToScene(entity); - addedToScene << entity; - } - } - foreach (auto addedEntity, addedToScene) { - _pendingAddToScene.remove(addedEntity); - } -} void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) { if (_tree && !_shuttingDown) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 2c1c5ef928..55c889d1c1 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -123,9 +123,7 @@ protected: virtual Octree* createTree() { return new EntityTree(true); } private: - void checkPendingAddToScene(RenderArgs* renderArgs); void addEntityToScene(EntityItemPointer entity); - QSet _pendingAddToScene; void applyZonePropertiesToScene(std::shared_ptr zone); void renderElementProxy(EntityTreeElement* entityTreeElement, RenderArgs* args); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 926889ccac..e5e0f2ff85 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -32,9 +32,7 @@ namespace render { if (args) { args->_elementsTouched++; if (payload && payload->entity) { - if (payload->entity->getType() != EntityTypes::Model) { - payload->entity->render(args); - } + payload->entity->render(args); } } } diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 92eef7e8ea..2037788ace 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -56,7 +56,6 @@ private: #define SIMPLE_RENDERABLE() \ public: \ - virtual bool canRenderInScene() { return true; } \ virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { return _renderHelper.addToScene(self, scene, pendingChanges); } \ virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { _renderHelper.removeFromScene(self, scene, pendingChanges); } \ private: \ diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.h b/libraries/entities-renderer/src/RenderableLightEntityItem.h index a90bb0baad..a0c424e240 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.h @@ -13,6 +13,7 @@ #define hifi_RenderableLightEntityItem_h #include +#include "RenderableEntityItem.h" class RenderableLightEntityItem : public LightEntityItem { public: @@ -22,12 +23,13 @@ public: LightEntityItem(entityItemID, properties) { } - virtual bool canRenderInScene() { return false; } // we don't yet play well with others virtual void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face, void** intersectedObject, bool precisionPicking) const; + + SIMPLE_RENDERABLE(); }; diff --git a/libraries/entities-renderer/src/RenderableLineEntityItem.h b/libraries/entities-renderer/src/RenderableLineEntityItem.h index 3c12f28b90..09f98ca364 100644 --- a/libraries/entities-renderer/src/RenderableLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLineEntityItem.h @@ -28,7 +28,7 @@ public: virtual void render(RenderArgs* args); - SIMPLE_RENDERABLE() + SIMPLE_RENDERABLE(); protected: void updateGeometry(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c4930f1225..29da23702c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -210,6 +211,19 @@ void RenderableModelEntityItem::render(RenderArgs* args) { } if (hasModel()) { + if (_model) { + // check to see if when we added our models to the scene they were ready, if they were not ready, then + // fix them up in the scene + render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + render::PendingChanges pendingChanges; + if (_model->needsFixupInScene()) { + _model->removeFromScene(scene, pendingChanges); + _model->addToScene(scene, pendingChanges); + } + scene->enqueuePendingChanges(pendingChanges); + } + + remapTextures(); { float alpha = getLocalRenderAlpha(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 837890a960..ac1d4b494f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -43,7 +43,6 @@ public: virtual void somethingChangedNotification() { _needsInitialSimulation = true; } - virtual bool canRenderInScene() { return true; } virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr); virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h index 66505a2cd2..4ecea45ad0 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h @@ -23,7 +23,7 @@ public: void updateQuads(RenderArgs* args, bool textured); - SIMPLE_RENDERABLE() + SIMPLE_RENDERABLE(); protected: diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index c8f1b4a49d..77aeb24f2a 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -16,6 +16,7 @@ #include "PolyVoxEntityItem.h" #include "RenderableDebugableEntityItem.h" +#include "RenderableEntityItem.h" class RenderablePolyVoxEntityItem : public PolyVoxEntityItem { public: @@ -70,6 +71,8 @@ public: virtual void setAll(uint8_t toValue); virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue); + + SIMPLE_RENDERABLE(); private: // The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.h b/libraries/entities-renderer/src/RenderableSphereEntityItem.h index b6f7ff996e..6331b35706 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.h +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.h @@ -26,7 +26,7 @@ public: virtual void render(RenderArgs* args); - SIMPLE_RENDERABLE() + SIMPLE_RENDERABLE(); }; diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index 5db22f3045..de1d745875 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -15,6 +15,8 @@ #include #include +#include "RenderableEntityItem.h" + const int FIXED_FONT_POINT_SIZE = 40; class RenderableTextEntityItem : public TextEntityItem { @@ -27,7 +29,8 @@ public: ~RenderableTextEntityItem() { delete _textRenderer; } virtual void render(RenderArgs* args); - virtual bool canRenderInScene() { return false; } // we don't yet play well with others + + SIMPLE_RENDERABLE(); private: TextRenderer3D* _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE / 2.0f); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 2ad4d799b6..05ad3a4088 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -13,6 +13,8 @@ #include +#include "RenderableEntityItem.h" + class OffscreenQmlSurface; class RenderableWebEntityItem : public WebEntityItem { @@ -24,7 +26,8 @@ public: virtual void render(RenderArgs* args); virtual void setSourceUrl(const QString& value); - virtual bool canRenderInScene() { return false; } // we don't yet play well with others + + SIMPLE_RENDERABLE(); private: OffscreenQmlSurface* _webSurface{ nullptr }; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index e320925045..9c4f8ae0bb 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -102,7 +102,8 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { updateGeometry(); if (_model && _model->isActive()) { - _model->renderInScene(getLocalRenderAlpha(), args); + // FIX ME: this is no longer available... we need to switch to payloads + //_model->renderInScene(getLocalRenderAlpha(), args); } break; } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 878d0bed7c..a189c944ae 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -157,8 +157,6 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { return 0; } - virtual bool canRenderInScene() { return false; } // does your entity property render using Render Items and Payloads - virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return true; } // we assume you're ready to add virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { return false; } // by default entity items don't add to scene virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 312890a188..451f3d8cd5 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -925,6 +925,7 @@ void Model::removeFromScene(std::shared_ptr scene, render::Pendin } bool Model::render(RenderArgs* renderArgs, float alpha) { + return true; // PROFILE_RANGE(__FUNCTION__); // render the attachments @@ -1994,15 +1995,6 @@ void Model::deleteGeometry() { _blendedBlendshapeCoefficients.clear(); } -// Scene rendering support -QVector Model::_modelsInScene; -gpu::Batch Model::_sceneRenderBatch; -void Model::startScene(RenderArgs::RenderSide renderSide) { - if (renderSide != RenderArgs::STEREO_RIGHT) { - _modelsInScene.clear(); - } -} - void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) { // Capture the view matrix once for the rendering of this model @@ -2019,231 +2011,6 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) { batch.setViewTransform(_transforms[0]); } -void Model::endScene(RenderArgs* args) { - // Now that we migrated everything to the new RENDER/SCENE no more work to do! - return; - PROFILE_RANGE(__FUNCTION__); - - - -#if (GPU_TRANSFORM_PROFILE == GPU_LEGACY) - // with legacy transform profile, we still to protect that transform stack... - glPushMatrix(); -#endif - - auto mode = args->_renderMode; - - RenderArgs::RenderSide renderSide = RenderArgs::MONO; - if (args) { - renderSide = args->_renderSide; - } - - - gpu::GLBackend backend; - backend.syncCache(); // force sync with gl state here - - if (args) { - glm::mat4 proj; - // If for easier debug depending on the pass - if (mode == RenderArgs::SHADOW_RENDER_MODE) { - args->_viewFrustum->evalProjectionMatrix(proj); - } else { - args->_viewFrustum->evalProjectionMatrix(proj); - } - gpu::Batch batch; - batch.setProjectionTransform(proj); - backend.render(batch); - } - - // Do the rendering batch creation for mono or left eye, not for right eye - if (renderSide != RenderArgs::STEREO_RIGHT) { - // Let's introduce a gpu::Batch to capture all the calls to the graphics api - _sceneRenderBatch.clear(); - gpu::Batch& batch = _sceneRenderBatch; - - /*DependencyManager::get()->setPrimaryDrawBuffers( - mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE, - mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE, - mode == RenderArgs::DEFAULT_RENDER_MODE); - */ - - /* if (mode != RenderArgs::SHADOW_RENDER_MODE) */{ - GLenum buffers[3]; - - int bufferCount = 0; - // if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) { - if (mode != RenderArgs::SHADOW_RENDER_MODE) { - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - } - //if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE) { - if (mode != RenderArgs::SHADOW_RENDER_MODE) { - buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - } - // if (mode == RenderArgs::DEFAULT_RENDER_MODE) { - if (mode != RenderArgs::SHADOW_RENDER_MODE) { - buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - } - GLBATCH(glDrawBuffers)(bufferCount, buffers); - - // batch.setFramebuffer(DependencyManager::get()->getPrimaryOpaqueFramebuffer()); - } - - const float DEFAULT_ALPHA_THRESHOLD = 0.5f; - - int opaqueMeshPartsRendered = 0; - - // now, for each model in the scene, render the mesh portions - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, false, args); - - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, false, args); - - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, true, args); - - // render translucent meshes afterwards - { - GLenum buffers[2]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - GLBATCH(glDrawBuffers)(bufferCount, buffers); - } - - int translucentParts = 0; - const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, false, args); - - - { - GLenum buffers[1]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - GLBATCH(glDrawBuffers)(bufferCount, buffers); - // batch.setFramebuffer(DependencyManager::get()->getPrimaryTransparentFramebuffer()); - } - - // if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) { - if (mode != RenderArgs::SHADOW_RENDER_MODE) { - // batch.setFramebuffer(DependencyManager::get()->getPrimaryTransparentFramebuffer()); - - const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, false, args); - - // batch.setFramebuffer(DependencyManager::get()->getPrimaryOpaqueFramebuffer()); - } - - GLBATCH(glDepthMask)(true); - GLBATCH(glDepthFunc)(GL_LESS); - GLBATCH(glDisable)(GL_CULL_FACE); - - if (mode == RenderArgs::SHADOW_RENDER_MODE) { - GLBATCH(glCullFace)(GL_BACK); - } - - - GLBATCH(glActiveTexture)(GL_TEXTURE0 + 1); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - GLBATCH(glActiveTexture)(GL_TEXTURE0 + 2); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - GLBATCH(glActiveTexture)(GL_TEXTURE0 + 3); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - GLBATCH(glActiveTexture)(GL_TEXTURE0); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - - - // deactivate vertex arrays after drawing - GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY); - GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY); - GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY); - GLBATCH(glDisableClientState)(GL_COLOR_ARRAY); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::TANGENT); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_INDEX); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_WEIGHT); - - // bind with 0 to switch back to normal operation - GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0); - GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - - // Back to no program - GLBATCH(glUseProgram)(0); - - if (args) { - args->_translucentMeshPartsRendered = translucentParts; - args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered; - } - - } - - // Render! - { - PROFILE_RANGE("render Batch"); - backend.render(_sceneRenderBatch); - } - - -#if (GPU_TRANSFORM_PROFILE == GPU_LEGACY) - // with legacy transform profile, we still to protect that transform stack... - glPopMatrix(); -#endif - - // restore all the default material settings - _viewState->setupWorldLight(); - -} - -bool Model::renderInScene(float alpha, RenderArgs* args) { - // render the attachments - foreach (Model* attachment, _attachments) { - attachment->renderInScene(alpha); - } - if (_meshStates.isEmpty()) { - return false; - } - - if (args->_debugFlags == RenderArgs::RENDER_DEBUG_HULLS && _renderCollisionHull == false) { - // turning collision hull rendering on - _renderCollisionHull = true; - _nextGeometry = _collisionGeometry; - _saveNonCollisionGeometry = _geometry; - updateGeometry(); - simulate(0.0, true); - } else if (args->_debugFlags != RenderArgs::RENDER_DEBUG_HULLS && _renderCollisionHull == true) { - // turning collision hull rendering off - _renderCollisionHull = false; - _nextGeometry = _saveNonCollisionGeometry; - _saveNonCollisionGeometry.clear(); - updateGeometry(); - simulate(0.0, true); - } - - renderSetup(args); - _modelsInScene.push_back(this); - return true; -} AABox Model::getPartBounds(int meshIndex, int partIndex) { if (!_calculatedMeshPartBoxesValid) { @@ -2329,21 +2096,17 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran return; // FIXME! } - if (state.clusterMatrices.size() > 1) { + if (isSkinned) { GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false, (const float*)state.clusterMatrices.constData()); - // batch.setModelTransform(Transform()); - _transforms[0].setTranslation(_translation); - + _transforms[0] = Transform(); + _transforms[0].preTranslate(_translation); } else { _transforms[0] = Transform(state.clusterMatrices[0]); _transforms[0].preTranslate(_translation); - - //batch.setModelTransform(Transform(state.clusterMatrices[0])); } batch.setModelTransform(_transforms[0]); - if (mesh.blendshapes.isEmpty()) { batch.setInputFormat(networkMesh._vertexFormat); batch.setInputStream(0, *networkMesh._vertexStream); @@ -2588,34 +2351,6 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f } } -int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, - bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args) { - - PROFILE_RANGE(__FUNCTION__); - int meshPartsRendered = 0; - - bool pickProgramsNeeded = true; - Locations* locations = nullptr; - - foreach(Model* model, _modelsInScene) { - QVector* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); - if (whichList) { - QVector& list = *whichList; - if (list.size() > 0) { - if (pickProgramsNeeded) { - pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe, args, locations); - pickProgramsNeeded = false; - } - - model->setupBatchTransform(batch, args); - meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations); - } - } - } - - return meshPartsRendered; -} - int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, bool forceRenderSomeMeshes) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 08385ffb61..3795dc8731 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -114,14 +114,8 @@ public: void reset(); virtual void simulate(float deltaTime, bool fullUpdate = true); - bool render(RenderArgs* renderArgs, float alpha = 1.0f); void renderSetup(RenderArgs* args); - // Scene rendering support - static void startScene(RenderArgs::RenderSide renderSide); - bool renderInScene(float alpha = 1.0f, RenderArgs* args = NULL); - static void endScene(RenderArgs* args); - // new Scene/Engine rendering support bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); } bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return isRenderable() && isActive() && isLoadedWithTextures(); } @@ -393,13 +387,6 @@ private: void renderDebugMeshBoxes(); int _debugMeshBoxesID = GeometryCache::UNKNOWN_ID; - // Scene rendering support - static QVector _modelsInScene; - static gpu::Batch _sceneRenderBatch; - - static void endSceneSimple(RenderArgs::RenderMode mode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs* args = NULL); - static void endSceneSplitPass(RenderArgs::RenderMode mode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs* args = NULL); - // helper functions used by render() or renderInScene() bool renderCore(RenderArgs* args, float alpha); int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold, @@ -417,10 +404,6 @@ private: bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, Locations*& locations); - static int renderMeshesForModelsInScene(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold, - bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args); - - static AbstractViewStateInterface* _viewState; class RenderKey { @@ -547,6 +530,14 @@ private: QSet> _opaqueRenderItems; QSet _renderItems; bool _readyWhenAdded = false; + + +private: + // FIX ME - We want to get rid of this interface for rendering... + // right now the only remaining user are Avatar attachments. + // that usage has been temporarily disabled... + bool render(RenderArgs* renderArgs, float alpha = 1.0f); + }; Q_DECLARE_METATYPE(QPointer)