mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 16:43:33 +02:00
Cleaning up the basic jobs of render
This commit is contained in:
parent
58cec3fb96
commit
e6844f4294
10 changed files with 253 additions and 114 deletions
|
@ -19,6 +19,7 @@
|
|||
#include <gpu/Context.h>
|
||||
|
||||
#include <render/CullTask.h>
|
||||
#include <render/FilterTask.h>
|
||||
#include <render/SortTask.h>
|
||||
#include <render/DrawTask.h>
|
||||
#include <render/DrawStatus.h>
|
||||
|
@ -66,7 +67,7 @@ RenderDeferredTask::RenderDeferredTask(RenderFetchCullSortTask::Output items) {
|
|||
|
||||
// Filter the non antialiaased overlays
|
||||
const int LAYER_NO_AA = 3;
|
||||
const auto nonAAOverlays = addJob<FilterItemLayer>("Filter2DWebOverlays", overlayOpaques, LAYER_NO_AA);
|
||||
const auto nonAAOverlays = addJob<FilterLayeredItems>("Filter2DWebOverlays", overlayOpaques, LAYER_NO_AA);
|
||||
|
||||
// Prepare deferred, generate the shared Deferred Frame Transform
|
||||
const auto deferredFrameTransform = addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform");
|
||||
|
@ -184,7 +185,7 @@ RenderDeferredTask::RenderDeferredTask(RenderFetchCullSortTask::Output items) {
|
|||
const auto debugAmbientOcclusionInputs = DebugAmbientOcclusion::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget, ambientOcclusionUniforms).hasVarying();
|
||||
addJob<DebugAmbientOcclusion>("DebugAmbientOcclusion", debugAmbientOcclusionInputs);
|
||||
|
||||
addJob<ZoneRenderer>("ZoneRenderer", opaques);
|
||||
addJob<ZoneRendererTask>("ZoneRenderer", opaques);
|
||||
|
||||
// Scene Octree Debugging job
|
||||
{
|
||||
|
|
|
@ -10,15 +10,19 @@
|
|||
//
|
||||
#include "ZoneRenderer.h"
|
||||
|
||||
const render::Selection::Name ZoneRenderer::ZONES_SELECTION { "RankedZones" };
|
||||
#include <render/FilterTask.h>
|
||||
#include <render/DrawTask.h>
|
||||
|
||||
using namespace render;
|
||||
|
||||
void ZoneRenderer::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" };
|
||||
|
||||
auto zones = scene->getSelection(ZONES_SELECTION);
|
||||
ZoneRendererTask::ZoneRendererTask(const Inputs& inputs) {
|
||||
|
||||
const auto zoneItems = addJob<SelectItems>("FilterZones", inputs, ZONES_SELECTION);
|
||||
|
||||
// just draw them...
|
||||
addJob<DrawBounds>("DrawZones", zoneItems);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -27,19 +27,19 @@ signals:
|
|||
protected:
|
||||
};
|
||||
|
||||
class ZoneRenderer {
|
||||
class ZoneRendererTask : public render::Task {
|
||||
public:
|
||||
|
||||
static const render::Selection::Name ZONES_SELECTION;
|
||||
|
||||
|
||||
using Inputs = render::ItemBounds;
|
||||
using Config = ZoneRendererConfig;
|
||||
using JobModel = render::Job::ModelI<ZoneRenderer, Inputs, Config>;
|
||||
using JobModel = Model<ZoneRendererTask, Config>;
|
||||
|
||||
ZoneRenderer() {}
|
||||
ZoneRendererTask(const Inputs& inputs);
|
||||
|
||||
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||
|
||||
protected:
|
||||
int _maxDrawn; // initialized by Config
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#include <OctreeUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
using namespace render;
|
||||
|
||||
|
@ -306,19 +304,3 @@ void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const Re
|
|||
|
||||
std::static_pointer_cast<Config>(renderContext->jobConfig)->numItems = (int)outItems.size();
|
||||
}
|
||||
|
||||
|
||||
void FilterItemLayer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
// Clear previous values
|
||||
outItems.clear();
|
||||
|
||||
// For each item, filter it into one bucket
|
||||
for (auto itemBound : inItems) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
if (item.getLayer() == _keepLayer) {
|
||||
outItems.emplace_back(itemBound);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -109,85 +109,6 @@ namespace render {
|
|||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection, ItemBounds& outItems);
|
||||
};
|
||||
|
||||
class FilterItemSelectionConfig : public Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int numItems READ getNumItems)
|
||||
public:
|
||||
int numItems{ 0 };
|
||||
int getNumItems() { return numItems; }
|
||||
};
|
||||
|
||||
class FilterItemSelection {
|
||||
public:
|
||||
using Config = FilterItemSelectionConfig;
|
||||
using JobModel = Job::ModelIO<FilterItemSelection, ItemBounds, ItemBounds, Config>;
|
||||
|
||||
FilterItemSelection() {}
|
||||
FilterItemSelection(const ItemFilter& filter) :
|
||||
_filter(filter) {}
|
||||
|
||||
ItemFilter _filter{ ItemFilter::Builder::opaqueShape().withoutLayered() };
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
};
|
||||
|
||||
class MultiFilterItemConfig : public Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int numItems READ getNumItems)
|
||||
public:
|
||||
int numItems{ 0 };
|
||||
int getNumItems() { return numItems; }
|
||||
};
|
||||
|
||||
template <int NUM_FILTERS>
|
||||
class MultiFilterItem {
|
||||
public:
|
||||
using ItemFilterArray = std::array<ItemFilter, NUM_FILTERS>;
|
||||
using ItemBoundsArray = VaryingArray<ItemBounds, NUM_FILTERS>;
|
||||
using Config = MultiFilterItemConfig;
|
||||
using JobModel = Job::ModelIO<MultiFilterItem, ItemBounds, ItemBoundsArray, Config>;
|
||||
|
||||
MultiFilterItem() {}
|
||||
MultiFilterItem(const ItemFilterArray& filters) :
|
||||
_filters(filters) {}
|
||||
|
||||
ItemFilterArray _filters;
|
||||
|
||||
void configure(const Config& config) {}
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBoundsArray& outItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
// Clear previous values
|
||||
for (size_t i = 0; i < NUM_FILTERS; i++) {
|
||||
outItems[i].template edit<ItemBounds>().clear();
|
||||
}
|
||||
|
||||
// For each item, filter it into one bucket
|
||||
for (auto itemBound : inItems) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
auto itemKey = item.getKey();
|
||||
for (size_t i = 0; i < NUM_FILTERS; i++) {
|
||||
if (_filters[i].test(itemKey)) {
|
||||
outItems[i].template edit<ItemBounds>().emplace_back(itemBound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FilterItemLayer {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<FilterItemLayer, ItemBounds, ItemBounds>;
|
||||
|
||||
FilterItemLayer() {}
|
||||
FilterItemLayer(int keepLayer) :
|
||||
_keepLayer(keepLayer) {}
|
||||
|
||||
int _keepLayer { 0 };
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // hifi_render_CullTask_h;
|
83
libraries/render/src/render/FilterTask.cpp
Normal file
83
libraries/render/src/render/FilterTask.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// FilterTask.cpp
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 2/2/16.
|
||||
// Copyright 2016 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 "FilterTask.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
#include <OctreeUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
using namespace render;
|
||||
|
||||
void FilterLayeredItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
// Clear previous values
|
||||
outItems.clear();
|
||||
|
||||
// For each item, filter it into one bucket
|
||||
for (auto itemBound : inItems) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
if (item.getLayer() == _keepLayer) {
|
||||
outItems.emplace_back(itemBound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SliceItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
// Now we have a selection of items to render
|
||||
outItems.clear();
|
||||
std::static_pointer_cast<Config>(renderContext->jobConfig)->setNumItems((int)inItems.size());
|
||||
|
||||
if (_rangeOffset < 0) return;
|
||||
|
||||
int maxItemNum = std::min(_rangeOffset + _rangeLength, (int)inItems.size());
|
||||
|
||||
|
||||
for (int i = _rangeOffset; i < maxItemNum; i++) {
|
||||
outItems.emplace_back(inItems[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SelectItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
auto selection = scene->getSelection(_name);
|
||||
const auto& selectedItems = selection.getItems();
|
||||
if (!selectedItems.empty()) {
|
||||
for (auto src : inItems) {
|
||||
if (selection.contains(src.id)) {
|
||||
outItems.emplace_back(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MetaToSubItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemIDs& outItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
// Now we have a selection of items to render
|
||||
outItems.clear();
|
||||
|
||||
for (auto idBound : inItems) {
|
||||
auto& item = scene->getItem(idBound.id);
|
||||
|
||||
item.fetchMetaSubItems(outItems);
|
||||
}
|
||||
}
|
||||
|
136
libraries/render/src/render/FilterTask.h
Normal file
136
libraries/render/src/render/FilterTask.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
//
|
||||
// FilterTask.h
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 2/2/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_render_FilterTask_h
|
||||
#define hifi_render_FilterTask_h
|
||||
|
||||
#include "Engine.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
class MultiFilterItemsConfig : public Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int numItems READ getNumItems)
|
||||
public:
|
||||
int numItems{ 0 };
|
||||
int getNumItems() { return numItems; }
|
||||
};
|
||||
|
||||
// Filter inbound of items into multiple buckets defined from the job's Filter array
|
||||
template <int NUM_FILTERS>
|
||||
class MultiFilterItems {
|
||||
public:
|
||||
using ItemFilterArray = std::array<ItemFilter, NUM_FILTERS>;
|
||||
using ItemBoundsArray = VaryingArray<ItemBounds, NUM_FILTERS>;
|
||||
using Config = MultiFilterItemsConfig;
|
||||
using JobModel = Job::ModelIO<MultiFilterItems, ItemBounds, ItemBoundsArray, Config>;
|
||||
|
||||
MultiFilterItems() {}
|
||||
MultiFilterItems(const ItemFilterArray& filters) :
|
||||
_filters(filters) {}
|
||||
|
||||
ItemFilterArray _filters;
|
||||
|
||||
void configure(const Config& config) {}
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBoundsArray& outItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
// Clear previous values
|
||||
for (size_t i = 0; i < NUM_FILTERS; i++) {
|
||||
outItems[i].template edit<ItemBounds>().clear();
|
||||
}
|
||||
|
||||
// For each item, filter it into one bucket
|
||||
for (auto itemBound : inItems) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
auto itemKey = item.getKey();
|
||||
for (size_t i = 0; i < NUM_FILTERS; i++) {
|
||||
if (_filters[i].test(itemKey)) {
|
||||
outItems[i].template edit<ItemBounds>().emplace_back(itemBound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Filter the items belonging to the job's keep layer
|
||||
class FilterLayeredItems {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<FilterLayeredItems, ItemBounds, ItemBounds>;
|
||||
|
||||
FilterLayeredItems() {}
|
||||
FilterLayeredItems(int keepLayer) :
|
||||
_keepLayer(keepLayer) {}
|
||||
|
||||
int _keepLayer { 0 };
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
};
|
||||
|
||||
// SliceItems job config defining the slice range
|
||||
class SliceItemsConfig : public Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int rangeOffset MEMBER rangeOffset)
|
||||
Q_PROPERTY(int rangeLength MEMBER rangeLength)
|
||||
Q_PROPERTY(int numItems READ getNumItems NOTIFY dirty())
|
||||
int numItems { 0 };
|
||||
public:
|
||||
int rangeOffset{ -1 };
|
||||
int rangeLength{ 1 };
|
||||
int getNumItems() { return numItems; }
|
||||
void setNumItems(int n) { numItems = n; emit dirty(); }
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
// Keep items in the job slice (defined from config)
|
||||
class SliceItems {
|
||||
public:
|
||||
using Config = SliceItemsConfig;
|
||||
using JobModel = Job::ModelIO<SliceItems, ItemBounds, ItemBounds, Config>;
|
||||
|
||||
SliceItems() {}
|
||||
int _rangeOffset{ -1 };
|
||||
int _rangeLength{ 1 };
|
||||
|
||||
void configure(const Config& config) {
|
||||
_rangeOffset = config.rangeOffset;
|
||||
_rangeLength = config.rangeLength;
|
||||
}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
};
|
||||
|
||||
// Keep items belonging to the job selection
|
||||
class SelectItems {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<SelectItems, ItemBounds, ItemBounds>;
|
||||
|
||||
std::string _name;
|
||||
SelectItems(const Selection::Name& name) : _name(name) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
};
|
||||
|
||||
// From meta-Items, generate the sub-items
|
||||
class MetaToSubItems {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<MetaToSubItems, ItemBounds, ItemIDs>;
|
||||
|
||||
MetaToSubItems() {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemIDs& outItems);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_render_FilterTask_h;
|
|
@ -12,6 +12,7 @@
|
|||
#include "RenderFetchCullSortTask.h"
|
||||
|
||||
#include "CullTask.h"
|
||||
#include "FilterTask.h"
|
||||
#include "SortTask.h"
|
||||
|
||||
using namespace render;
|
||||
|
@ -36,23 +37,23 @@ RenderFetchCullSortTask::RenderFetchCullSortTask(CullFunctor cullFunctor) {
|
|||
const int LIGHT_BUCKET = 2;
|
||||
const int META_BUCKET = 3;
|
||||
const int BACKGROUND_BUCKET = 2;
|
||||
MultiFilterItem<NUM_SPATIAL_FILTERS>::ItemFilterArray spatialFilters = { {
|
||||
MultiFilterItems<NUM_SPATIAL_FILTERS>::ItemFilterArray spatialFilters = { {
|
||||
ItemFilter::Builder::opaqueShape(),
|
||||
ItemFilter::Builder::transparentShape(),
|
||||
ItemFilter::Builder::light(),
|
||||
ItemFilter::Builder::meta()
|
||||
} };
|
||||
MultiFilterItem<NUM_NON_SPATIAL_FILTERS>::ItemFilterArray nonspatialFilters = { {
|
||||
MultiFilterItems<NUM_NON_SPATIAL_FILTERS>::ItemFilterArray nonspatialFilters = { {
|
||||
ItemFilter::Builder::opaqueShape(),
|
||||
ItemFilter::Builder::transparentShape(),
|
||||
ItemFilter::Builder::background()
|
||||
} };
|
||||
const auto filteredSpatialBuckets =
|
||||
addJob<MultiFilterItem<NUM_SPATIAL_FILTERS>>("FilterSceneSelection", culledSpatialSelection, spatialFilters)
|
||||
.get<MultiFilterItem<NUM_SPATIAL_FILTERS>::ItemBoundsArray>();
|
||||
addJob<MultiFilterItems<NUM_SPATIAL_FILTERS>>("FilterSceneSelection", culledSpatialSelection, spatialFilters)
|
||||
.get<MultiFilterItems<NUM_SPATIAL_FILTERS>::ItemBoundsArray>();
|
||||
const auto filteredNonspatialBuckets =
|
||||
addJob<MultiFilterItem<NUM_NON_SPATIAL_FILTERS>>("FilterOverlaySelection", nonspatialSelection, nonspatialFilters)
|
||||
.get<MultiFilterItem<NUM_NON_SPATIAL_FILTERS>::ItemBoundsArray>();
|
||||
addJob<MultiFilterItems<NUM_NON_SPATIAL_FILTERS>>("FilterOverlaySelection", nonspatialSelection, nonspatialFilters)
|
||||
.get<MultiFilterItems<NUM_NON_SPATIAL_FILTERS>::ItemBoundsArray>();
|
||||
|
||||
// Extract opaques / transparents / lights / overlays
|
||||
const auto opaques = addJob<DepthSortItems>("DepthSortOpaque", filteredSpatialBuckets[OPAQUE_SHAPE_BUCKET]);
|
||||
|
|
|
@ -56,3 +56,11 @@ Selection::Selection(const Name& name, const ItemIDs& items) :
|
|||
{
|
||||
}
|
||||
|
||||
bool Selection::contains(ItemID id) const {
|
||||
for (auto selected : _items) {
|
||||
if (selected == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -33,6 +33,9 @@ namespace render {
|
|||
|
||||
const ItemIDs& getItems() const { return _items; }
|
||||
|
||||
bool isEmpty() const { return _items.empty(); }
|
||||
bool contains(ItemID id) const;
|
||||
|
||||
protected:
|
||||
Name _name;
|
||||
ItemIDs _items;
|
||||
|
|
Loading…
Reference in a new issue