diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 2aa08d36f3..9497e2099d 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -260,7 +260,8 @@ void SkeletonModel::updateJointState(int index) { } JointState& state = _jointStates[index]; const FBXJoint& joint = state.getFBXJoint(); - if (joint.parentIndex != -1 && joint.parentIndex <= _jointStates.size()) { + // if (joint.parentIndex != -1 && joint.parentIndex <= _jointStates.size()) { + if (joint.parentIndex > -1 && joint.parentIndex <= _jointStates.size()) { const JointState& parentState = _jointStates.at(joint.parentIndex); const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (index == geometry.leanJointIndex) { diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index de8f53c503..764ef5bc93 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -516,6 +516,24 @@ QVector createVec4Vector(const QVector& doubleVector) { return values; } + +QVector createVec4VectorRGBA(const QVector& doubleVector, glm::vec4& average) { + QVector values; + for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 4 * 4); it != end; ) { + float x = *it++; + float y = *it++; + float z = *it++; + float w = *it++; + auto val = glm::vec4(x, y, z, w); + values.append(val); + average += val; + } + if (!values.isEmpty()) { + average *= (1.0f / float(values.size())); + } + return values; +} + QVector createVec3Vector(const QVector& doubleVector) { QVector values; for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 3 * 3); it != end; ) { @@ -799,6 +817,7 @@ public: QVector normalIndices; bool colorsByVertex; + glm::vec4 averageColor{1.0f, 1.0f, 1.0f, 1.0f}; QVector colors; QVector colorIndices; @@ -940,8 +959,7 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) { bool indexToDirect = false; foreach (const FBXNode& subdata, child.children) { if (subdata.name == "Colors") { - data.colors = createVec4Vector(getDoubleVector(subdata)); - + data.colors = createVec4VectorRGBA(getDoubleVector(subdata), data.averageColor); } else if (subdata.name == "ColorsIndex") { data.colorIndices = getIntVector(subdata); @@ -956,6 +974,19 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) { // hack to work around wacky Makehuman exports data.colorsByVertex = true; } + +#if defined(FBXREADER_KILL_BLACK_COLOR_ATTRIBUTE) + // Potential feature where we decide to kill the color attribute is to dark? + // Tested with the model: + // https://hifi-public.s3.amazonaws.com/ryan/gardenLight2.fbx + // let's check if we did have true data ? + if (glm::all(glm::lessThanEqual(data.averageColor, glm::vec4(0.09f)))) { + data.colors.clear(); + data.colorIndices.clear(); + data.colorsByVertex = false; + qCDebug(modelformat) << "LayerElementColor has an average value of 0.0f... let's forget it."; + } +#endif } else if (child.name == "LayerElementUV") { if (child.properties.at(0).toInt() == 0) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index f0a52af086..569892f6e8 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -191,7 +191,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu } } -void DeferredLightingEffect::prepare() { +void DeferredLightingEffect::prepare(RenderArgs* args) { // clear the normal and specular buffers auto textureCache = DependencyManager::get(); textureCache->setPrimaryDrawBuffers(false, true, false); @@ -205,7 +205,7 @@ void DeferredLightingEffect::prepare() { textureCache->setPrimaryDrawBuffers(true, false, false); } -void DeferredLightingEffect::render() { +void DeferredLightingEffect::render(RenderArgs* args) { // perform deferred lighting, rendering to free fbo glDisable(GL_BLEND); glDisable(GL_LIGHTING); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index bd7fcb286b..2440c78df3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -66,8 +66,8 @@ public: void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), float intensity = 0.5f, const glm::quat& orientation = glm::quat(), float exponent = 0.0f, float cutoff = PI); - void prepare(); - void render(); + void prepare(RenderArgs* args); + void render(RenderArgs* args); void copyBack(RenderArgs* args); void setupTransparent(RenderArgs* args, int lightBufferUnit); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index d9dda279e0..978a3dede2 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -21,18 +21,18 @@ using namespace render; -template <> void render::jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("PrepareDeferred"); - DependencyManager::get()->prepare(); + DependencyManager::get()->prepare(renderContext->args); } -template <> void render::jobRun(const RenderDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("RenderDeferred"); - DependencyManager::get()->render(); + DependencyManager::get()->render(renderContext->args); // renderContext->args->_context->syncCache(); } -template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("ResolveDeferred"); DependencyManager::get()->copyBack(renderContext->args); renderContext->args->_context->syncCache(); @@ -40,7 +40,7 @@ template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPo } - +/* RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(PrepareDeferred())); _jobs.push_back(Job(DrawBackground())); @@ -53,6 +53,22 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(DrawPostLayered())); _jobs.push_back(Job(ResetGLState())); } +*/ +RenderDeferredTask::RenderDeferredTask() : Task() { + _jobs.push_back(Job(new PrepareDeferred::JobModel())); + _jobs.push_back(Job(new DrawBackground::JobModel())); + _jobs.push_back(Job(new FetchItems::JobModel())); + _jobs.push_back(Job(new CullItems::JobModel(_jobs.back().getOutput()))); + _jobs.push_back(Job(new DepthSortItems::JobModel(_jobs.back().getOutput()))); + _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel(_jobs.back().getOutput()))); + _jobs.push_back(Job(new DrawLight::JobModel())); + _jobs.push_back(Job(new ResetGLState::JobModel())); + _jobs.push_back(Job(new RenderDeferred::JobModel())); + _jobs.push_back(Job(new ResolveDeferred::JobModel())); + _jobs.push_back(Job(new DrawTransparentDeferred::JobModel())); + _jobs.push_back(Job(new DrawPostLayered::JobModel())); + _jobs.push_back(Job(new ResetGLState::JobModel())); +} RenderDeferredTask::~RenderDeferredTask() { } @@ -77,9 +93,8 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend } }; - - -template <> void render::jobRun(const DrawOpaqueDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +/* +void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawOpaqueDeferred"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -126,7 +141,7 @@ template <> void render::jobRun(const DrawOpaqueDeferred& job, const SceneContex } } */ - +/* if (renderContext->_renderOpaque) { RenderArgs* args = renderContext->args; gpu::Batch batch; @@ -153,13 +168,49 @@ template <> void render::jobRun(const DrawOpaqueDeferred& job, const SceneContex renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnOpaqueItems); + renderContext->args->_context->syncCache(); args->_context->render((*args->_batch)); args->_batch = nullptr; } } +*/ +void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { + PerformanceTimer perfTimer("DrawOpaqueDeferred"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); -template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_batch = &batch; + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + if (args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) { + viewMat.postScale(glm::vec3(-1.0f, 1.0f, 1.0f)); + } + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + batch._glDrawBuffers(bufferCount, buffers); + } + + renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems); + + renderContext->args->_context->syncCache(); + args->_context->render((*args->_batch)); + args->_batch = nullptr; +} + +void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawTransparentDeferred"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -172,7 +223,13 @@ template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneC ItemIDsBounds inItems; inItems.reserve(items.size()); for (auto id : items) { - inItems.push_back(id); + auto item = scene->getItem(id); + AABox bound; + { + PerformanceTimer perfTimer("getBound"); + bound = item.getBound(); + } + inItems.emplace_back(ItemIDAndBounds(id, bound)); } ItemIDsBounds& renderedItems = inItems; diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index e2cac53c0d..b587c7526b 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -16,39 +16,47 @@ class PrepareDeferred { public: + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; }; -namespace render { -template <> void jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); -} + class RenderDeferred { public: + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; }; -namespace render { -template <> void jobRun(const RenderDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); -} class ResolveDeferred { public: -}; -namespace render { -template <> void jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); -} + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + typedef render::Job::Model JobModel; +}; class DrawOpaqueDeferred { public: + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems); + + typedef render::Job::ModelI JobModel; }; -namespace render { -template <> void jobRun(const DrawOpaqueDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); -} + +/*class DrawOpaqueDeferred { +public: + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; +}; +*/ class DrawTransparentDeferred { public: + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; }; -namespace render { -template <> void jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); -} class RenderDeferredTask : public render::Task { public: diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 1ab8c29294..743d19765a 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -26,10 +26,10 @@ using namespace render; DrawSceneTask::DrawSceneTask() : Task() { - _jobs.push_back(Job(DrawOpaque())); - _jobs.push_back(Job(DrawLight())); - _jobs.push_back(Job(DrawTransparent())); - _jobs.push_back(Job(ResetGLState())); + _jobs.push_back(Job(new Job::Model())); + _jobs.push_back(Job(new Job::Model())); + _jobs.push_back(Job(new Job::Model())); + _jobs.push_back(Job(new Job::Model())); } DrawSceneTask::~DrawSceneTask() { @@ -58,24 +58,6 @@ Job::~Job() { -void FetchCullItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, CulledItems& outItems) { - PerformanceTimer perfTimer("FetchCullItems::run"); - - auto& scene = sceneContext->_scene; - auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape()); - auto& renderDetails = renderContext->args->_details; - - ItemIDsBounds inItems; - inItems.reserve(items.size()); - for (auto id : items) { - inItems.emplace_back(id); - } - - ItemIDsBounds& renderedItems = inItems; - - outItems._items.reserve(inItems.size()); - cullItems(sceneContext, renderContext, renderedItems, outItems._items); -} void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { @@ -90,17 +72,9 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont renderDetails->_considered += inItems.size(); // Culling / LOD - for (auto itemDetails : inItems) { - auto item = scene->getItem(itemDetails.id); - AABox bound; - { - PerformanceTimer perfTimer("getBound"); - - bound = item.getBound(); - } - - if (bound.isNull()) { - outItems.emplace_back(ItemIDAndBounds(itemDetails.id)); // One more Item to render + for (auto item : inItems) { + if (item.bounds.isNull()) { + outItems.emplace_back(item); // One more Item to render continue; } @@ -109,16 +83,16 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont bool outOfView; { PerformanceTimer perfTimer("boxInFrustum"); - outOfView = args->_viewFrustum->boxInFrustum(bound) == ViewFrustum::OUTSIDE; + outOfView = args->_viewFrustum->boxInFrustum(item.bounds) == ViewFrustum::OUTSIDE; } if (!outOfView) { bool bigEnoughToRender; { PerformanceTimer perfTimer("shouldRender"); - bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, bound) : true; + bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, item.bounds) : true; } if (bigEnoughToRender) { - outItems.emplace_back(ItemIDAndBounds(itemDetails.id, bound)); // One more Item to render + outItems.emplace_back(item); // One more Item to render } else { renderDetails->_tooSmall++; } @@ -129,6 +103,36 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont renderDetails->_rendered += outItems.size(); } + +void FetchItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemIDsBounds& outItems) { + PerformanceTimer perfTimer("FetchCullItems::run"); + + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(_filter); + auto& renderDetails = renderContext->args->_details; + + outItems.clear(); + outItems.reserve(items.size()); + for (auto id : items) { + auto item = scene->getItem(id); + AABox bound; + { + PerformanceTimer perfTimer("getBound"); + bound = item.getBound(); + } + outItems.emplace_back(ItemIDAndBounds(id, bound)); + } +} + +void CullItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { + PerformanceTimer perfTimer("CullItems::run"); + + outItems.clear(); + outItems.reserve(inItems.size()); + cullItems(sceneContext, renderContext, inItems, outItems); +} + + struct ItemBound { float _centerDepth = 0.0f; float _nearDepth = 0.0f; @@ -161,9 +165,10 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende // Allocate and simply copy + outItems.clear(); outItems.reserve(inItems.size()); - + // Make a local dataset of the center distance and closest point distance std::vector itemBounds; itemBounds.reserve(outItems.size()); @@ -191,6 +196,13 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende } } + +void DepthSortItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { + outItems.clear(); + outItems.reserve(inItems.size()); + depthSortItems(sceneContext, renderContext, _frontToBack, inItems, outItems); +} + void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems) { PerformanceTimer perfTimer("renderItems"); auto& scene = sceneContext->_scene; @@ -205,6 +217,11 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo int numItems = 0; for (auto itemDetails : inItems) { auto item = scene->getItem(itemDetails.id); + if (numItems + 1 >= maxDrawnItems) { + item.render(args); + + return; + } item.render(args); numItems++; if (numItems >= maxDrawnItems) { @@ -246,8 +263,7 @@ void addClearStateCommands(gpu::Batch& batch) { // Back to no program batch._glUseProgram(0); } - -template <> void render::jobRun(const ResetGLState& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +void ResetGLState::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { gpu::Batch theBatch; addClearStateCommands(theBatch); @@ -255,7 +271,7 @@ template <> void render::jobRun(const ResetGLState& job, const SceneContextPoint renderContext->args->_context->render(theBatch); } -template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +template <> void render::jobRun(DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawOpaque"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -268,7 +284,13 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer ItemIDsBounds inItems; inItems.reserve(items.size()); for (auto id : items) { - inItems.emplace_back(ItemIDAndBounds(id)); + auto item = scene->getItem(id); + AABox bound; + { + PerformanceTimer perfTimer("getBound"); + bound = item.getBound(); + } + inItems.emplace_back(ItemIDAndBounds(id, bound)); } ItemIDsBounds& renderedItems = inItems; @@ -324,7 +346,7 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer } -template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +template <> void render::jobRun(DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawTransparent"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -337,7 +359,13 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo ItemIDsBounds inItems; inItems.reserve(items.size()); for (auto id : items) { - inItems.emplace_back(id); + auto item = scene->getItem(id); + AABox bound; + { + PerformanceTimer perfTimer("getBound"); + bound = item.getBound(); + } + inItems.emplace_back(ItemIDAndBounds(id, bound)); } ItemIDsBounds& renderedItems = inItems; @@ -407,7 +435,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo } } -template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawLight"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -420,7 +448,13 @@ template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& ItemIDsBounds inItems; inItems.reserve(items.size()); for (auto id : items) { - inItems.emplace_back(id); + auto item = scene->getItem(id); + AABox bound; + { + PerformanceTimer perfTimer("getBound"); + bound = item.getBound(); + } + inItems.emplace_back(ItemIDAndBounds(id, bound)); } ItemIDsBounds culledItems; @@ -435,7 +469,7 @@ template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& args->_batch = nullptr; } -template <> void render::jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawBackground"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -472,7 +506,7 @@ template <> void render::jobRun(const DrawBackground& job, const SceneContextPoi args->_context->syncCache(); } -template <> void render::jobRun(const DrawPostLayered& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { +void DrawPostLayered::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawPostLayered"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -487,7 +521,13 @@ template <> void render::jobRun(const DrawPostLayered& job, const SceneContextPo for (auto id : items) { auto& item = scene->getItem(id); if (item.getKey().isVisible() && (item.getLayer() > 0)) { - inItems.emplace_back(id); + auto item = scene->getItem(id); + AABox bound; + { + PerformanceTimer perfTimer("getBound"); + bound = item.getBound(); + } + inItems.emplace_back(ItemIDAndBounds(id, bound)); } } if (inItems.empty()) { diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 37fff55245..d81dee2b37 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -20,22 +20,35 @@ namespace render { -template void jobRun(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { } -template void jobRunI(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) { } -template void jobRunO(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) { +template void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + jobModel.run(sceneContext, renderContext); +} +template void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) { + jobModel.run(sceneContext, renderContext, input); +} +template void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) { jobModel.run(sceneContext, renderContext, output); } -template void jobRunIO(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) { } +template void jobRunIO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) { + jobModel.run(sceneContext, renderContext, input, output); +} class Job { public: + // Varying represent a varying piece of data class Varying { public: + Varying(const Varying& var): _concept(var._concept) {} + Varying() {} template - Varying(T data) : _concept(new Model(data)) {} + Varying(const T& data) : _concept(new Job::Varying::Model(data)) {} + + // Access the _data contained win the concept explicitely + template T& edit() { return (static_cast*> (_concept.get())->_data); } + template const T& get() const { return (static_cast*> (_concept.get())->_data); } protected: friend class Job; @@ -54,64 +67,66 @@ public: public: typedef T Data; Data _data; - Model(Data data): _data(data) {} + Model(const Model& source): _data(source.data) {} + Model(const Data& data): _data(data) {} + virtual ~Model() {} }; + + std::shared_ptr _concept; }; - typedef std::shared_ptr VaryingPointer; - - template - Job(T data) : _concept(new Model(data)) {} - - - template - static Job* createO(T data) { return new Job(new ModelO(data)); } Job(const Job& other) : _concept(other._concept) {} ~Job(); - const VaryingPointer& getInput() const { return _concept->getInput(); } - const VaryingPointer& getOutput() const { return _concept->getOutput(); } + const Varying getInput() const { return _concept->getInput(); } + const Varying getOutput() const { return _concept->getOutput(); } - virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { if (_concept) { _concept->run(sceneContext, renderContext); } } protected: +public: class Concept { public: virtual ~Concept() = default; - virtual const VaryingPointer& getInput() const { return VaryingPointer(); } - virtual const VaryingPointer& getOutput() const { return VaryingPointer(); } + virtual const Varying getInput() const { return Varying(); } + virtual const Varying getOutput() const { return Varying(); } virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0; }; Job(Concept* concept) : _concept(concept) {} +public: template class Model : public Concept { public: typedef T Data; Data _data; + Model() {} Model(Data data): _data(data) {} void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRun(_data, sceneContext, renderContext); } }; -public: + template class ModelI : public Concept { public: typedef T Data; typedef I Input; Data _data; - VaryingPointer _intput; + Varying _input; + const Varying getInput() const { return _input; } + + ModelI(const Varying& input): _input(input) {} ModelI(Data data): _data(data) {} - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRunI(_data, sceneContext, renderContext, _input); } + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRunI(_data, sceneContext, renderContext, _input.get()); } }; template class ModelO : public Concept { @@ -120,11 +135,19 @@ public: typedef O Output; Data _data; - VaryingPointer _output; + Varying _output; - ModelO(Data data): _data(data), _output(new Varying::Model(Output())) {} + const Varying getOutput() const { return _output; } - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRunO(_data, sceneContext, renderContext, _output); } + ModelO() : _output(Output()) { + + } + + ModelO(Data data): _data(data), _output(Output()) {} + + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + jobRunO(_data, sceneContext, renderContext, _output.edit()); + } }; template class ModelIO : public Concept { @@ -134,14 +157,18 @@ public: typedef O Output; Data _data; - VaryingPointer _intput; - VaryingPointer _output; + Varying _input; + Varying _output; - ModelIO(Data data, Output output): _data(data), _output(new Varying::Model(output)) {} + const Varying getInput() const { return _input; } + const Varying getOutput() const { return _output; } - void setInput(const VaryingPointer& input) { _input = input; } + ModelIO(const Varying& input): _input(input), _output(Output()) {} + ModelIO(Data data, Output output): _data(data), _output(output) {} - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRunIO(_data, sceneContext, renderContext, _input, _output); } + void setInput(const Varying& input) { _input = input; } + + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRunIO(_data, sceneContext, renderContext, _input.get(), _output.edit()); } }; std::shared_ptr _concept; @@ -156,56 +183,74 @@ void cullItems(const SceneContextPointer& sceneContext, const RenderContextPoint 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 CulledItems { + +class FetchItems { public: - ItemIDsBounds _items; + ItemFilter _filter = ItemFilter::Builder::opaqueShape().withoutLayered(); + + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemIDsBounds& outItems); + + typedef Job::ModelO JobModel; }; -class FetchCullItems { +class CullItems { public: - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, CulledItems& outItems); + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); - typedef Job::ModelO JobModel; + typedef Job::ModelIO JobModel; }; +class DepthSortItems { +public: + bool _frontToBack = true; + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems); + + typedef Job::ModelIO JobModel; +}; -void materialSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); class DrawOpaque { public: }; -template <> void jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +template <> void jobRun(DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); class DrawTransparent { public: }; -template <> void jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +template <> void jobRun(DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); class DrawLight { public: + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + typedef Job::Model JobModel; }; -template <> void jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); class DrawBackground { public: + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + typedef Job::Model JobModel; }; -template <> void jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); class DrawPostLayered { public: + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + typedef Job::Model JobModel; }; -template <> void jobRun(const DrawPostLayered& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); - - class ResetGLState { public: + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + typedef Job::Model JobModel; }; -template <> void jobRun(const ResetGLState& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + class DrawSceneTask : public Task { @@ -233,6 +278,7 @@ public: // standard builders allocating the main buckets void allocateStandardMaterialBuckets(); }; +void materialSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); }