mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-26 00:55:10 +02:00
cache bounds with item ids in DrawTask
This commit is contained in:
parent
08ea3368d7
commit
46a8b831fc
3 changed files with 57 additions and 94 deletions
|
@ -58,7 +58,7 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon
|
||||||
Job::~Job() {
|
Job::~Job() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outItems) {
|
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
|
||||||
PerformanceTimer perfTimer("cullItems");
|
PerformanceTimer perfTimer("cullItems");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
@ -70,8 +70,8 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
|
||||||
renderDetails->_considered += inItems.size();
|
renderDetails->_considered += inItems.size();
|
||||||
|
|
||||||
// Culling / LOD
|
// Culling / LOD
|
||||||
for (auto id : inItems) {
|
for (auto itemDetails : inItems) {
|
||||||
auto item = scene->getItem(id);
|
auto item = scene->getItem(itemDetails.id);
|
||||||
AABox bound;
|
AABox bound;
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("getBound");
|
PerformanceTimer perfTimer("getBound");
|
||||||
|
@ -80,7 +80,7 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bound.isNull()) {
|
if (bound.isNull()) {
|
||||||
outItems.push_back(id); // One more Item to render
|
outItems.push_back(ItemIDAndBounds(itemDetails.id)); // One more Item to render
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
|
||||||
bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, bound) : true;
|
bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, bound) : true;
|
||||||
}
|
}
|
||||||
if (bigEnoughToRender) {
|
if (bigEnoughToRender) {
|
||||||
outItems.push_back(id); // One more Item to render
|
outItems.push_back(ItemIDAndBounds(itemDetails.id, bound)); // One more Item to render
|
||||||
} else {
|
} else {
|
||||||
renderDetails->_tooSmall++;
|
renderDetails->_tooSmall++;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ struct BackToFrontSort {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& outItems) {
|
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
|
||||||
PerformanceTimer perfTimer("depthSortItems");
|
PerformanceTimer perfTimer("depthSortItems");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
@ -144,95 +144,47 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende
|
||||||
outItems.reserve(inItems.size());
|
outItems.reserve(inItems.size());
|
||||||
|
|
||||||
|
|
||||||
#if 0 /// NEW WAY
|
// Make a local dataset of the center distance and closest point distance
|
||||||
{
|
std::vector<ItemBound> itemBounds;
|
||||||
PerformanceTimer perfTimer("newWay");
|
itemBounds.reserve(outItems.size());
|
||||||
|
|
||||||
// TODO: use a QMap<depth,item> which would give us automatic sorting.
|
|
||||||
QMap<float, ItemID> depths;
|
|
||||||
QList<ItemID> sortedItems;
|
|
||||||
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("part1");
|
|
||||||
|
|
||||||
for (auto id : inItems) {
|
for (auto itemDetails : inItems) {
|
||||||
auto item = scene->getItem(id);
|
auto item = scene->getItem(itemDetails.id);
|
||||||
auto bound = item.getBound();
|
auto bound = itemDetails.bounds; // item.getBound();
|
||||||
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
||||||
float key = frontToBack ? -distance : distance;
|
|
||||||
|
|
||||||
depths.insertMulti(key, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("part2");
|
|
||||||
sortedItems = depths.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("part3");
|
|
||||||
for ( auto sortedID : sortedItems) {
|
|
||||||
outItems.emplace_back(sortedID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
itemBounds.emplace_back(ItemBound(distance, distance, distance, itemDetails.id));
|
||||||
}
|
}
|
||||||
#else /// OLD WAY
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("oldWay");
|
|
||||||
|
|
||||||
// Make a local dataset of the center distance and closest point distance
|
// sort against Z
|
||||||
std::vector<ItemBound> itemBounds;
|
if (frontToBack) {
|
||||||
{
|
FrontToBackSort frontToBackSort;
|
||||||
PerformanceTimer perfTimer("part1");
|
std::sort (itemBounds.begin(), itemBounds.end(), frontToBackSort);
|
||||||
itemBounds.reserve(outItems.size());
|
} else {
|
||||||
|
BackToFrontSort backToFrontSort;
|
||||||
for (auto id : inItems) {
|
std::sort (itemBounds.begin(), itemBounds.end(), backToFrontSort);
|
||||||
auto item = scene->getItem(id);
|
}
|
||||||
auto bound = item.getBound();
|
|
||||||
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
// FInally once sorted result to a list of itemID
|
||||||
|
for (auto& itemBound : itemBounds) {
|
||||||
itemBounds.emplace_back(ItemBound(distance, distance, distance, id));
|
outItems.emplace_back(itemBound._id);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("part2");
|
|
||||||
// sort against Z
|
|
||||||
if (frontToBack) {
|
|
||||||
FrontToBackSort frontToBackSort;
|
|
||||||
std::sort (itemBounds.begin(), itemBounds.end(), frontToBackSort);
|
|
||||||
} else {
|
|
||||||
BackToFrontSort backToFrontSort;
|
|
||||||
std::sort (itemBounds.begin(), itemBounds.end(), backToFrontSort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("part3");
|
|
||||||
// FInally once sorted result to a list of itemID
|
|
||||||
for (auto& itemBound : itemBounds) {
|
|
||||||
outItems.emplace_back(itemBound._id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, int maxDrawnItems) {
|
void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems) {
|
||||||
PerformanceTimer perfTimer("renderItems");
|
PerformanceTimer perfTimer("renderItems");
|
||||||
auto& scene = sceneContext->_scene;
|
auto& scene = sceneContext->_scene;
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
// render
|
// render
|
||||||
if ((maxDrawnItems < 0) || (maxDrawnItems > inItems.size())) {
|
if ((maxDrawnItems < 0) || (maxDrawnItems > inItems.size())) {
|
||||||
for (auto id : inItems) {
|
for (auto itemDetails : inItems) {
|
||||||
auto item = scene->getItem(id);
|
auto item = scene->getItem(itemDetails.id);
|
||||||
item.render(args);
|
item.render(args);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int numItems = 0;
|
int numItems = 0;
|
||||||
for (auto id : inItems) {
|
for (auto itemDetails : inItems) {
|
||||||
auto item = scene->getItem(id);
|
auto item = scene->getItem(itemDetails.id);
|
||||||
item.render(args);
|
item.render(args);
|
||||||
numItems++;
|
numItems++;
|
||||||
if (numItems >= maxDrawnItems) {
|
if (numItems >= maxDrawnItems) {
|
||||||
|
@ -294,16 +246,16 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer
|
||||||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape());
|
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape());
|
||||||
auto& renderDetails = renderContext->args->_details;
|
auto& renderDetails = renderContext->args->_details;
|
||||||
|
|
||||||
ItemIDs inItems;
|
ItemIDsBounds inItems;
|
||||||
inItems.reserve(items.size());
|
inItems.reserve(items.size());
|
||||||
for (auto id : items) {
|
for (auto id : items) {
|
||||||
inItems.push_back(id);
|
inItems.push_back(ItemIDAndBounds(id));
|
||||||
}
|
}
|
||||||
ItemIDs& renderedItems = inItems;
|
ItemIDsBounds& renderedItems = inItems;
|
||||||
|
|
||||||
renderContext->_numFeedOpaqueItems = renderedItems.size();
|
renderContext->_numFeedOpaqueItems = renderedItems.size();
|
||||||
|
|
||||||
ItemIDs culledItems;
|
ItemIDsBounds culledItems;
|
||||||
if (renderContext->_cullOpaque) {
|
if (renderContext->_cullOpaque) {
|
||||||
renderDetails.pointTo(RenderDetails::OPAQUE_ITEM);
|
renderDetails.pointTo(RenderDetails::OPAQUE_ITEM);
|
||||||
cullItems(sceneContext, renderContext, renderedItems, culledItems);
|
cullItems(sceneContext, renderContext, renderedItems, culledItems);
|
||||||
|
@ -314,7 +266,7 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer
|
||||||
renderContext->_numDrawnOpaqueItems = renderedItems.size();
|
renderContext->_numDrawnOpaqueItems = renderedItems.size();
|
||||||
|
|
||||||
|
|
||||||
ItemIDs sortedItems;
|
ItemIDsBounds sortedItems;
|
||||||
if (renderContext->_sortOpaque) {
|
if (renderContext->_sortOpaque) {
|
||||||
depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items!
|
depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items!
|
||||||
renderedItems = sortedItems;
|
renderedItems = sortedItems;
|
||||||
|
@ -360,16 +312,16 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo
|
||||||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape());
|
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape());
|
||||||
auto& renderDetails = renderContext->args->_details;
|
auto& renderDetails = renderContext->args->_details;
|
||||||
|
|
||||||
ItemIDs inItems;
|
ItemIDsBounds inItems;
|
||||||
inItems.reserve(items.size());
|
inItems.reserve(items.size());
|
||||||
for (auto id : items) {
|
for (auto id : items) {
|
||||||
inItems.push_back(id);
|
inItems.push_back(id);
|
||||||
}
|
}
|
||||||
ItemIDs& renderedItems = inItems;
|
ItemIDsBounds& renderedItems = inItems;
|
||||||
|
|
||||||
renderContext->_numFeedTransparentItems = renderedItems.size();
|
renderContext->_numFeedTransparentItems = renderedItems.size();
|
||||||
|
|
||||||
ItemIDs culledItems;
|
ItemIDsBounds culledItems;
|
||||||
if (renderContext->_cullTransparent) {
|
if (renderContext->_cullTransparent) {
|
||||||
renderDetails.pointTo(RenderDetails::TRANSLUCENT_ITEM);
|
renderDetails.pointTo(RenderDetails::TRANSLUCENT_ITEM);
|
||||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
cullItems(sceneContext, renderContext, inItems, culledItems);
|
||||||
|
@ -379,7 +331,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo
|
||||||
|
|
||||||
renderContext->_numDrawnTransparentItems = renderedItems.size();
|
renderContext->_numDrawnTransparentItems = renderedItems.size();
|
||||||
|
|
||||||
ItemIDs sortedItems;
|
ItemIDsBounds sortedItems;
|
||||||
if (renderContext->_sortTransparent) {
|
if (renderContext->_sortTransparent) {
|
||||||
depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items!
|
depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items!
|
||||||
renderedItems = sortedItems;
|
renderedItems = sortedItems;
|
||||||
|
@ -440,13 +392,13 @@ template <> void render::jobRun(const DrawLight& job, const SceneContextPointer&
|
||||||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::light());
|
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::light());
|
||||||
|
|
||||||
|
|
||||||
ItemIDs inItems;
|
ItemIDsBounds inItems;
|
||||||
inItems.reserve(items.size());
|
inItems.reserve(items.size());
|
||||||
for (auto id : items) {
|
for (auto id : items) {
|
||||||
inItems.push_back(id);
|
inItems.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemIDs culledItems;
|
ItemIDsBounds culledItems;
|
||||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
cullItems(sceneContext, renderContext, inItems, culledItems);
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
@ -467,7 +419,7 @@ template <> void render::jobRun(const DrawBackground& job, const SceneContextPoi
|
||||||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background());
|
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background());
|
||||||
|
|
||||||
|
|
||||||
ItemIDs inItems;
|
ItemIDsBounds inItems;
|
||||||
inItems.reserve(items.size());
|
inItems.reserve(items.size());
|
||||||
for (auto id : items) {
|
for (auto id : items) {
|
||||||
inItems.push_back(id);
|
inItems.push_back(id);
|
||||||
|
|
|
@ -57,9 +57,9 @@ protected:
|
||||||
|
|
||||||
typedef std::vector<Job> Jobs;
|
typedef std::vector<Job> Jobs;
|
||||||
|
|
||||||
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outITems);
|
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
|
||||||
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& 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 ItemIDs& inItems, int maxDrawnItems = -1);
|
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1);
|
||||||
|
|
||||||
|
|
||||||
class DrawOpaque {
|
class DrawOpaque {
|
||||||
|
|
|
@ -333,6 +333,17 @@ typedef Item::ID ItemID;
|
||||||
typedef std::vector<ItemID> ItemIDs;
|
typedef std::vector<ItemID> ItemIDs;
|
||||||
typedef std::set<ItemID> ItemIDSet;
|
typedef std::set<ItemID> ItemIDSet;
|
||||||
|
|
||||||
|
class ItemIDAndBounds {
|
||||||
|
public:
|
||||||
|
ItemIDAndBounds(ItemID id) : id(id) { }
|
||||||
|
ItemIDAndBounds(ItemID id, const AABox& bounds) : id(id), bounds(bounds) { }
|
||||||
|
|
||||||
|
ItemID id;
|
||||||
|
AABox bounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector< ItemIDAndBounds > ItemIDsBounds;
|
||||||
|
|
||||||
// A map of ItemIDSets allowing to create bucket lists of items which are filtering correctly
|
// A map of ItemIDSets allowing to create bucket lists of items which are filtering correctly
|
||||||
class ItemBucketMap : public std::map<ItemFilter, ItemIDSet, ItemFilter::Less> {
|
class ItemBucketMap : public std::map<ItemFilter, ItemIDSet, ItemFilter::Less> {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue