mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 20:34:07 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into hdr
This commit is contained in:
commit
4e5869b247
15 changed files with 81 additions and 61 deletions
|
@ -672,7 +672,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
initializeGL();
|
||||
|
||||
// Start rendering
|
||||
_renderEngine->addTask(make_shared<RenderDeferredTask>());
|
||||
_renderEngine->addTask(make_shared<RenderDeferredTask>(LODManager::shouldRender));
|
||||
_renderEngine->registerScene(_main3DScene);
|
||||
|
||||
_offscreenContext->makeCurrent();
|
||||
|
@ -3826,7 +3826,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
auto renderInterface = DependencyManager::get<RenderScriptingInterface>();
|
||||
auto renderContext = renderInterface->getRenderContext();
|
||||
|
||||
renderArgs->_shouldRender = LODManager::shouldRender;
|
||||
renderArgs->_viewFrustum = getDisplayViewFrustum();
|
||||
renderContext.setArgs(renderArgs);
|
||||
|
||||
|
|
|
@ -1291,12 +1291,13 @@ void EntityTree::remapIDs() {
|
|||
recurseTreeWithOperator(&theOperator);
|
||||
}
|
||||
|
||||
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) {
|
||||
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues,
|
||||
bool skipThoseWithBadParents) {
|
||||
if (! entityDescription.contains("Entities")) {
|
||||
entityDescription["Entities"] = QVariantList();
|
||||
}
|
||||
QScriptEngine scriptEngine;
|
||||
RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine, skipDefaultValues);
|
||||
RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine, skipDefaultValues, skipThoseWithBadParents);
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -199,7 +199,8 @@ public:
|
|||
|
||||
void remapIDs();
|
||||
|
||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) override;
|
||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues,
|
||||
bool skipThoseWithBadParents) override;
|
||||
virtual bool readFromMap(QVariantMap& entityDescription) override;
|
||||
|
||||
float getContentsLargestDimension();
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
RecurseOctreeToMapOperator::RecurseOctreeToMapOperator(QVariantMap& map,
|
||||
OctreeElementPointer top,
|
||||
QScriptEngine* engine,
|
||||
bool skipDefaultValues) :
|
||||
bool skipDefaultValues,
|
||||
bool skipThoseWithBadParents) :
|
||||
RecurseOctreeOperator(),
|
||||
_map(map),
|
||||
_top(top),
|
||||
_engine(engine),
|
||||
_skipDefaultValues(skipDefaultValues)
|
||||
_skipDefaultValues(skipDefaultValues),
|
||||
_skipThoseWithBadParents(skipThoseWithBadParents)
|
||||
{
|
||||
// if some element "top" was given, only save information for that element and its children.
|
||||
if (_top) {
|
||||
|
@ -47,6 +49,10 @@ bool RecurseOctreeToMapOperator::postRecursion(OctreeElementPointer element) {
|
|||
QVariantList entitiesQList = qvariant_cast<QVariantList>(_map["Entities"]);
|
||||
|
||||
entityTreeElement->forEachEntity([&](EntityItemPointer entityItem) {
|
||||
if (_skipThoseWithBadParents && !entityItem->isParentIDValid()) {
|
||||
return; // we weren't able to resolve a parent from _parentID, so don't save this entity.
|
||||
}
|
||||
|
||||
EntityItemProperties properties = entityItem->getProperties();
|
||||
QScriptValue qScriptValues;
|
||||
if (_skipDefaultValues) {
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
class RecurseOctreeToMapOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
RecurseOctreeToMapOperator(QVariantMap& map, OctreeElementPointer top, QScriptEngine* engine, bool skipDefaultValues);
|
||||
RecurseOctreeToMapOperator(QVariantMap& map, OctreeElementPointer top, QScriptEngine* engine, bool skipDefaultValues,
|
||||
bool skipThoseWithBadParents);
|
||||
bool preRecursion(OctreeElementPointer element);
|
||||
bool postRecursion(OctreeElementPointer element);
|
||||
private:
|
||||
|
@ -22,4 +23,5 @@ public:
|
|||
QScriptEngine* _engine;
|
||||
bool _withinTop;
|
||||
bool _skipDefaultValues;
|
||||
bool _skipThoseWithBadParents;
|
||||
};
|
||||
|
|
|
@ -1919,7 +1919,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElementPointer element,
|
|||
entityDescription["Version"] = (int) expectedVersion;
|
||||
|
||||
// store the entity data
|
||||
bool entityDescriptionSuccess = writeToMap(entityDescription, top, true);
|
||||
bool entityDescriptionSuccess = writeToMap(entityDescription, top, true, true);
|
||||
if (!entityDescriptionSuccess) {
|
||||
qCritical("Failed to convert Entities to QVariantMap while saving to json.");
|
||||
return;
|
||||
|
|
|
@ -304,7 +304,8 @@ public:
|
|||
void writeToFile(const char* filename, OctreeElementPointer element = NULL, QString persistAsFileType = "svo");
|
||||
void writeToJSONFile(const char* filename, OctreeElementPointer element = NULL, bool doGzip = false);
|
||||
void writeToSVOFile(const char* filename, OctreeElementPointer element = NULL);
|
||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) = 0;
|
||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues,
|
||||
bool skipThoseWithBadParents) = 0;
|
||||
|
||||
// Octree importers
|
||||
bool readFromFile(const char* filename);
|
||||
|
|
|
@ -71,7 +71,9 @@ void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const Ren
|
|||
_toneMappingEffect.render(renderContext->getArgs());
|
||||
}
|
||||
|
||||
RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||
RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) : Task() {
|
||||
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
|
||||
|
||||
// Prepare the ShapePipelines
|
||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||
initDeferredPipelines(*shapePlumber);
|
||||
|
@ -80,7 +82,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
auto fetchedOpaques = addJob<FetchItems>("FetchOpaque", FetchItems([](const RenderContextPointer& context, int count) {
|
||||
context->getItemsConfig().opaque.numFeed = count;
|
||||
}));
|
||||
auto culledOpaques = addJob<CullItems<RenderDetails::OPAQUE_ITEM>>("CullOpaque", fetchedOpaques);
|
||||
auto culledOpaques = addJob<CullItems<RenderDetails::OPAQUE_ITEM>>("CullOpaque", fetchedOpaques, cullFunctor);
|
||||
auto opaques = addJob<DepthSortItems>("DepthSortOpaque", culledOpaques);
|
||||
|
||||
// CPU only, create the list of renderedTransparents items
|
||||
|
@ -90,7 +92,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
context->getItemsConfig().transparent.numFeed = count;
|
||||
}
|
||||
));
|
||||
auto culledTransparents = addJob<CullItems<RenderDetails::TRANSLUCENT_ITEM>>("CullTransparent", fetchedTransparents);
|
||||
auto culledTransparents = addJob<CullItems<RenderDetails::TRANSLUCENT_ITEM>>("CullTransparent", fetchedTransparents, cullFunctor);
|
||||
auto transparents = addJob<DepthSortItems>("DepthSortTransparent", culledTransparents, DepthSortItems(false));
|
||||
|
||||
// GPU Jobs: Start preparing the deferred and lighting buffer
|
||||
|
@ -111,7 +113,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_occlusionJobIndex = (int)_jobs.size() - 1;
|
||||
|
||||
// Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now.
|
||||
addJob<DrawLight>("DrawLight");
|
||||
addJob<DrawLight>("DrawLight", cullFunctor);
|
||||
|
||||
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
|
||||
addJob<RenderDeferred>("RenderDeferred");
|
||||
|
@ -186,6 +188,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
|||
setAntialiasingStatus(renderContext->getFxaaStatus());
|
||||
setToneMappingExposure(renderContext->getTone().exposure);
|
||||
setToneMappingToneCurve(renderContext->getTone().toneCurve);
|
||||
// TODO: Allow runtime manipulation of culling ShouldRenderFunctor
|
||||
|
||||
renderContext->getArgs()->_context->syncCache();
|
||||
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
#ifndef hifi_RenderDeferredTask_h
|
||||
#define hifi_RenderDeferredTask_h
|
||||
|
||||
#include "render/Engine.h"
|
||||
|
||||
#include "gpu/Pipeline.h"
|
||||
|
||||
#include "render/DrawTask.h"
|
||||
|
||||
#include "ToneMappingEffect.h"
|
||||
|
||||
class SetupDeferred {
|
||||
|
@ -113,15 +113,8 @@ public:
|
|||
|
||||
class RenderDeferredTask : public render::Task {
|
||||
public:
|
||||
RenderDeferredTask();
|
||||
RenderDeferredTask(render::CullFunctor cullFunctor);
|
||||
|
||||
int _drawDebugDeferredBufferIndex;
|
||||
int _drawStatusJobIndex;
|
||||
int _drawHitEffectJobIndex;
|
||||
int _occlusionJobIndex;
|
||||
int _antialiasingJobIndex;
|
||||
int _toneMappingJobIndex;
|
||||
|
||||
void setDrawDebugDeferredBuffer(int draw) { enableJob(_drawDebugDeferredBufferIndex, draw >= 0); }
|
||||
bool doDrawDebugDeferredBuffer() const { return getEnableJob(_drawDebugDeferredBufferIndex); }
|
||||
|
||||
|
@ -147,6 +140,14 @@ public:
|
|||
int getToneMappingToneCurve() const;
|
||||
|
||||
virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
int _drawDebugDeferredBufferIndex;
|
||||
int _drawStatusJobIndex;
|
||||
int _drawHitEffectJobIndex;
|
||||
int _occlusionJobIndex;
|
||||
int _antialiasingJobIndex;
|
||||
int _toneMappingJobIndex;
|
||||
};
|
||||
|
||||
#endif // hifi_RenderDeferredTask_h
|
||||
|
|
|
@ -78,7 +78,9 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const
|
|||
});
|
||||
}
|
||||
|
||||
RenderShadowTask::RenderShadowTask() : Task() {
|
||||
RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) : Task() {
|
||||
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
|
||||
|
||||
// Prepare the ShapePipeline
|
||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||
{
|
||||
|
@ -105,7 +107,7 @@ RenderShadowTask::RenderShadowTask() : Task() {
|
|||
auto fetchedItems = addJob<FetchItems>("FetchShadowMap");
|
||||
|
||||
// CPU: Cull against KeyLight frustum (nearby viewing camera)
|
||||
auto culledItems = addJob<CullItems<RenderDetails::SHADOW_ITEM>>("CullShadowMap", fetchedItems);
|
||||
auto culledItems = addJob<CullItems<RenderDetails::SHADOW_ITEM>>("CullShadowMap", fetchedItems, cullFunctor);
|
||||
|
||||
// CPU: Sort by pipeline
|
||||
auto sortedShapes = addJob<PipelineSortShapes>("PipelineSortShadowSort", culledItems);
|
||||
|
@ -143,6 +145,7 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render
|
|||
|
||||
// Set the keylight frustum
|
||||
args->_viewFrustum = globalLight->shadow.getFrustum().get();
|
||||
// TODO: Allow runtime manipulation of culling ShouldRenderFunctor
|
||||
|
||||
for (auto job : _jobs) {
|
||||
job.run(sceneContext, renderContext);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <gpu/Framebuffer.h>
|
||||
#include <gpu/Pipeline.h>
|
||||
|
||||
#include <render/Scene.h>
|
||||
#include <render/DrawTask.h>
|
||||
|
||||
class ViewFrustum;
|
||||
|
@ -33,7 +32,7 @@ protected:
|
|||
|
||||
class RenderShadowTask : public render::Task {
|
||||
public:
|
||||
RenderShadowTask();
|
||||
RenderShadowTask(render::CullFunctor shouldRender);
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
};
|
||||
|
|
|
@ -20,14 +20,15 @@
|
|||
|
||||
using namespace render;
|
||||
|
||||
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
|
||||
void render::cullItems(const RenderContextPointer& renderContext, const CullFunctor& cullFunctor, RenderDetails::Item& details,
|
||||
const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
|
||||
assert(renderContext->getArgs());
|
||||
assert(renderContext->getArgs()->_viewFrustum);
|
||||
|
||||
RenderArgs* args = renderContext->getArgs();
|
||||
auto renderDetails = renderContext->getArgs()->_details._item;
|
||||
ViewFrustum* frustum = args->_viewFrustum;
|
||||
|
||||
renderDetails->_considered += inItems.size();
|
||||
details._considered += inItems.size();
|
||||
|
||||
// Culling / LOD
|
||||
for (auto item : inItems) {
|
||||
|
@ -41,24 +42,24 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
|
|||
bool outOfView;
|
||||
{
|
||||
PerformanceTimer perfTimer("boxInFrustum");
|
||||
outOfView = args->_viewFrustum->boxInFrustum(item.bounds) == ViewFrustum::OUTSIDE;
|
||||
outOfView = frustum->boxInFrustum(item.bounds) == ViewFrustum::OUTSIDE;
|
||||
}
|
||||
if (!outOfView) {
|
||||
bool bigEnoughToRender;
|
||||
{
|
||||
PerformanceTimer perfTimer("shouldRender");
|
||||
bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, item.bounds) : true;
|
||||
bigEnoughToRender = cullFunctor(args, item.bounds);
|
||||
}
|
||||
if (bigEnoughToRender) {
|
||||
outItems.emplace_back(item); // One more Item to render
|
||||
} else {
|
||||
renderDetails->_tooSmall++;
|
||||
details._tooSmall++;
|
||||
}
|
||||
} else {
|
||||
renderDetails->_outOfView++;
|
||||
details._outOfView++;
|
||||
}
|
||||
}
|
||||
renderDetails->_rendered += outItems.size();
|
||||
details._rendered += outItems.size();
|
||||
}
|
||||
|
||||
struct ItemBound {
|
||||
|
@ -202,10 +203,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
|
|||
|
||||
RenderArgs* args = renderContext->getArgs();
|
||||
|
||||
auto& details = args->_details.edit(RenderDetails::OTHER_ITEM);
|
||||
ItemIDsBounds culledItems;
|
||||
culledItems.reserve(inItems.size());
|
||||
args->_details.pointTo(RenderDetails::OTHER_ITEM);
|
||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
||||
cullItems(renderContext, _cullFunctor, details, inItems, culledItems);
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
args->_batch = &batch;
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
|
||||
namespace render {
|
||||
|
||||
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
|
||||
using CullFunctor = std::function<bool(const RenderArgs*, const AABox&)>;
|
||||
|
||||
void cullItems(const RenderContextPointer& renderContext, const CullFunctor& cullFunctor, RenderDetails::Item& details,
|
||||
const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
|
||||
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
|
||||
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems);
|
||||
void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1);
|
||||
|
@ -41,14 +44,20 @@ public:
|
|||
template<RenderDetails::Type T = RenderDetails::Type::OTHER_ITEM>
|
||||
class CullItems {
|
||||
public:
|
||||
CullItems(CullFunctor cullFunctor) : _cullFunctor{ cullFunctor } {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
|
||||
const auto& args = renderContext->getArgs();
|
||||
auto& details = args->_details.edit(T);
|
||||
outItems.clear();
|
||||
outItems.reserve(inItems.size());
|
||||
renderContext->getArgs()->_details.pointTo(T);
|
||||
render::cullItems(sceneContext, renderContext, inItems, outItems);
|
||||
render::cullItems(renderContext, _cullFunctor, details, inItems, outItems);
|
||||
}
|
||||
|
||||
using JobModel = Task::Job::ModelIO<CullItems<T>, ItemIDsBounds, ItemIDsBounds>;
|
||||
|
||||
protected:
|
||||
CullFunctor _cullFunctor;
|
||||
};
|
||||
|
||||
class DepthSortItems {
|
||||
|
@ -62,8 +71,12 @@ public:
|
|||
|
||||
class DrawLight {
|
||||
public:
|
||||
DrawLight(CullFunctor cullFunctor) : _cullFunctor{ cullFunctor } {}
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||
using JobModel = Task::Job::Model<DrawLight>;
|
||||
|
||||
protected:
|
||||
CullFunctor _cullFunctor;
|
||||
};
|
||||
|
||||
class PipelineSortShapes {
|
||||
|
|
|
@ -56,34 +56,25 @@ public:
|
|||
Item _translucent;
|
||||
Item _other;
|
||||
|
||||
Item* _item = &_other;
|
||||
|
||||
void pointTo(Type type) {
|
||||
Item& edit(Type type) {
|
||||
switch (type) {
|
||||
case OPAQUE_ITEM:
|
||||
_item = &_opaque;
|
||||
break;
|
||||
return _opaque;
|
||||
case SHADOW_ITEM:
|
||||
_item = &_shadow;
|
||||
break;
|
||||
return _shadow;
|
||||
case TRANSLUCENT_ITEM:
|
||||
_item = &_translucent;
|
||||
break;
|
||||
return _translucent;
|
||||
case OTHER_ITEM:
|
||||
_item = &_other;
|
||||
break;
|
||||
default:
|
||||
return _other;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class RenderArgs {
|
||||
public:
|
||||
typedef std::function<bool(const RenderArgs* args, const AABox& bounds)> ShoudRenderFunctor;
|
||||
|
||||
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE };
|
||||
|
||||
enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT };
|
||||
|
||||
enum DebugFlags {
|
||||
RENDER_DEBUG_NONE = 0,
|
||||
RENDER_DEBUG_HULLS = 1
|
||||
|
@ -97,8 +88,7 @@ public:
|
|||
RenderMode renderMode = DEFAULT_RENDER_MODE,
|
||||
RenderSide renderSide = MONO,
|
||||
DebugFlags debugFlags = RENDER_DEBUG_NONE,
|
||||
gpu::Batch* batch = nullptr,
|
||||
ShoudRenderFunctor shouldRender = nullptr) :
|
||||
gpu::Batch* batch = nullptr) :
|
||||
_context(context),
|
||||
_renderer(renderer),
|
||||
_viewFrustum(viewFrustum),
|
||||
|
@ -107,8 +97,7 @@ public:
|
|||
_renderMode(renderMode),
|
||||
_renderSide(renderSide),
|
||||
_debugFlags(debugFlags),
|
||||
_batch(batch),
|
||||
_shouldRender(shouldRender) {
|
||||
_batch(batch) {
|
||||
}
|
||||
|
||||
std::shared_ptr<gpu::Context> _context = nullptr;
|
||||
|
@ -123,7 +112,6 @@ public:
|
|||
RenderSide _renderSide = MONO;
|
||||
DebugFlags _debugFlags = RENDER_DEBUG_NONE;
|
||||
gpu::Batch* _batch = nullptr;
|
||||
ShoudRenderFunctor _shouldRender;
|
||||
|
||||
std::shared_ptr<gpu::Texture> _whiteTexture;
|
||||
|
||||
|
|
|
@ -118,6 +118,8 @@ public:
|
|||
void die() { _isDead = true; }
|
||||
bool isDead() const { return _isDead; }
|
||||
|
||||
bool isParentIDValid() const { bool success = false; getParentPointer(success); return success; }
|
||||
|
||||
protected:
|
||||
const NestableType _nestableType; // EntityItem or an AvatarData
|
||||
QUuid _id;
|
||||
|
|
Loading…
Reference in a new issue