mirror of
https://github.com/overte-org/overte.git
synced 2025-07-25 02:03:42 +02:00
Merge pull request #5070 from ZappoMan/team-teaching-drawperf
TEAM TEACHING - cache the Item bounds across sub tasks
This commit is contained in:
commit
cc55056eef
3 changed files with 63 additions and 38 deletions
|
@ -9,6 +9,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
#include "DrawTask.h"
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
@ -19,9 +22,6 @@
|
|||
#include "ViewFrustum.h"
|
||||
#include "RenderArgs.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace render;
|
||||
|
||||
DrawSceneTask::DrawSceneTask() : Task() {
|
||||
|
@ -56,7 +56,7 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon
|
|||
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");
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
@ -68,22 +68,35 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
|
|||
renderDetails->_considered += inItems.size();
|
||||
|
||||
// Culling / LOD
|
||||
for (auto id : inItems) {
|
||||
auto item = scene->getItem(id);
|
||||
auto bound = item.getBound();
|
||||
for (auto itemDetails : inItems) {
|
||||
auto item = scene->getItem(itemDetails.id);
|
||||
AABox bound;
|
||||
{
|
||||
PerformanceTimer perfTimer("getBound");
|
||||
|
||||
bound = item.getBound();
|
||||
}
|
||||
|
||||
if (bound.isNull()) {
|
||||
outItems.push_back(id); // One more Item to render
|
||||
outItems.push_back(ItemIDAndBounds(itemDetails.id)); // One more Item to render
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: some entity types (like lights) might want to be rendered even
|
||||
// when they are outside of the view frustum...
|
||||
bool outOfView = args->_viewFrustum->boxInFrustum(bound) == ViewFrustum::OUTSIDE;
|
||||
bool outOfView;
|
||||
{
|
||||
PerformanceTimer perfTimer("boxInFrustum");
|
||||
outOfView = args->_viewFrustum->boxInFrustum(bound) == ViewFrustum::OUTSIDE;
|
||||
}
|
||||
if (!outOfView) {
|
||||
bool bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, bound) : true;
|
||||
bool bigEnoughToRender;
|
||||
{
|
||||
PerformanceTimer perfTimer("shouldRender");
|
||||
bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, bound) : true;
|
||||
}
|
||||
if (bigEnoughToRender) {
|
||||
outItems.push_back(id); // One more Item to render
|
||||
outItems.push_back(ItemIDAndBounds(itemDetails.id, bound)); // One more Item to render
|
||||
} else {
|
||||
renderDetails->_tooSmall++;
|
||||
}
|
||||
|
@ -116,28 +129,29 @@ 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");
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
||||
// Allocate and simply copy
|
||||
outItems.reserve(inItems.size());
|
||||
|
||||
|
||||
|
||||
// Make a local dataset of the center distance and closest point distance
|
||||
std::vector<ItemBound> itemBounds;
|
||||
itemBounds.reserve(outItems.size());
|
||||
|
||||
for (auto id : inItems) {
|
||||
auto item = scene->getItem(id);
|
||||
auto bound = item.getBound();
|
||||
for (auto itemDetails : inItems) {
|
||||
auto item = scene->getItem(itemDetails.id);
|
||||
auto bound = itemDetails.bounds; // item.getBound();
|
||||
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
||||
|
||||
itemBounds.emplace_back(ItemBound(distance, distance, distance, id));
|
||||
|
||||
itemBounds.emplace_back(ItemBound(distance, distance, distance, itemDetails.id));
|
||||
}
|
||||
|
||||
// sort against Z
|
||||
|
@ -155,20 +169,20 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende
|
|||
}
|
||||
}
|
||||
|
||||
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");
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
// render
|
||||
if ((maxDrawnItems < 0) || (maxDrawnItems > inItems.size())) {
|
||||
for (auto id : inItems) {
|
||||
auto item = scene->getItem(id);
|
||||
for (auto itemDetails : inItems) {
|
||||
auto item = scene->getItem(itemDetails.id);
|
||||
item.render(args);
|
||||
}
|
||||
} else {
|
||||
int numItems = 0;
|
||||
for (auto id : inItems) {
|
||||
auto item = scene->getItem(id);
|
||||
for (auto itemDetails : inItems) {
|
||||
auto item = scene->getItem(itemDetails.id);
|
||||
item.render(args);
|
||||
numItems++;
|
||||
if (numItems >= maxDrawnItems) {
|
||||
|
@ -230,16 +244,16 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer
|
|||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape());
|
||||
auto& renderDetails = renderContext->args->_details;
|
||||
|
||||
ItemIDs inItems;
|
||||
ItemIDsBounds inItems;
|
||||
inItems.reserve(items.size());
|
||||
for (auto id : items) {
|
||||
inItems.push_back(id);
|
||||
inItems.push_back(ItemIDAndBounds(id));
|
||||
}
|
||||
ItemIDs& renderedItems = inItems;
|
||||
ItemIDsBounds& renderedItems = inItems;
|
||||
|
||||
renderContext->_numFeedOpaqueItems = renderedItems.size();
|
||||
|
||||
ItemIDs culledItems;
|
||||
ItemIDsBounds culledItems;
|
||||
if (renderContext->_cullOpaque) {
|
||||
renderDetails.pointTo(RenderDetails::OPAQUE_ITEM);
|
||||
cullItems(sceneContext, renderContext, renderedItems, culledItems);
|
||||
|
@ -250,7 +264,7 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer
|
|||
renderContext->_numDrawnOpaqueItems = renderedItems.size();
|
||||
|
||||
|
||||
ItemIDs sortedItems;
|
||||
ItemIDsBounds sortedItems;
|
||||
if (renderContext->_sortOpaque) {
|
||||
depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items!
|
||||
renderedItems = sortedItems;
|
||||
|
@ -296,16 +310,16 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo
|
|||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape());
|
||||
auto& renderDetails = renderContext->args->_details;
|
||||
|
||||
ItemIDs inItems;
|
||||
ItemIDsBounds inItems;
|
||||
inItems.reserve(items.size());
|
||||
for (auto id : items) {
|
||||
inItems.push_back(id);
|
||||
}
|
||||
ItemIDs& renderedItems = inItems;
|
||||
ItemIDsBounds& renderedItems = inItems;
|
||||
|
||||
renderContext->_numFeedTransparentItems = renderedItems.size();
|
||||
|
||||
ItemIDs culledItems;
|
||||
ItemIDsBounds culledItems;
|
||||
if (renderContext->_cullTransparent) {
|
||||
renderDetails.pointTo(RenderDetails::TRANSLUCENT_ITEM);
|
||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
||||
|
@ -315,7 +329,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo
|
|||
|
||||
renderContext->_numDrawnTransparentItems = renderedItems.size();
|
||||
|
||||
ItemIDs sortedItems;
|
||||
ItemIDsBounds sortedItems;
|
||||
if (renderContext->_sortTransparent) {
|
||||
depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items!
|
||||
renderedItems = sortedItems;
|
||||
|
@ -376,13 +390,13 @@ template <> void render::jobRun(const DrawLight& job, const SceneContextPointer&
|
|||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::light());
|
||||
|
||||
|
||||
ItemIDs inItems;
|
||||
ItemIDsBounds inItems;
|
||||
inItems.reserve(items.size());
|
||||
for (auto id : items) {
|
||||
inItems.push_back(id);
|
||||
}
|
||||
|
||||
ItemIDs culledItems;
|
||||
ItemIDsBounds culledItems;
|
||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
@ -403,7 +417,7 @@ template <> void render::jobRun(const DrawBackground& job, const SceneContextPoi
|
|||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background());
|
||||
|
||||
|
||||
ItemIDs inItems;
|
||||
ItemIDsBounds inItems;
|
||||
inItems.reserve(items.size());
|
||||
for (auto id : items) {
|
||||
inItems.push_back(id);
|
||||
|
|
|
@ -57,9 +57,9 @@ protected:
|
|||
|
||||
typedef std::vector<Job> Jobs;
|
||||
|
||||
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outITems);
|
||||
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& outITems);
|
||||
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, int maxDrawnItems = -1);
|
||||
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, 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, int maxDrawnItems = -1);
|
||||
|
||||
|
||||
class DrawOpaque {
|
||||
|
|
|
@ -333,6 +333,17 @@ typedef Item::ID ItemID;
|
|||
typedef std::vector<ItemID> ItemIDs;
|
||||
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
|
||||
class ItemBucketMap : public std::map<ItemFilter, ItemIDSet, ItemFilter::Less> {
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue