mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Improving the design of the Jobs and varying
This commit is contained in:
parent
fb5738ecab
commit
9be87758fd
8 changed files with 310 additions and 127 deletions
|
@ -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) {
|
||||
|
|
|
@ -516,6 +516,24 @@ QVector<glm::vec4> createVec4Vector(const QVector<double>& doubleVector) {
|
|||
return values;
|
||||
}
|
||||
|
||||
|
||||
QVector<glm::vec4> createVec4VectorRGBA(const QVector<double>& doubleVector, glm::vec4& average) {
|
||||
QVector<glm::vec4> 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<glm::vec3> createVec3Vector(const QVector<double>& doubleVector) {
|
||||
QVector<glm::vec3> values;
|
||||
for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 3 * 3); it != end; ) {
|
||||
|
@ -799,6 +817,7 @@ public:
|
|||
QVector<int> normalIndices;
|
||||
|
||||
bool colorsByVertex;
|
||||
glm::vec4 averageColor{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
QVector<glm::vec4> colors;
|
||||
QVector<int> 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) {
|
||||
|
|
|
@ -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>();
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<DeferredLightingEffect>()->prepare();
|
||||
DependencyManager::get<DeferredLightingEffect>()->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<DeferredLightingEffect>()->render();
|
||||
DependencyManager::get<DeferredLightingEffect>()->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<DeferredLightingEffect>()->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;
|
||||
|
||||
|
|
|
@ -16,39 +16,47 @@
|
|||
|
||||
class PrepareDeferred {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<PrepareDeferred> 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<RenderDeferred> 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<ResolveDeferred> JobModel;
|
||||
};
|
||||
|
||||
class DrawOpaqueDeferred {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
|
||||
|
||||
typedef render::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds> 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<DrawOpaqueDeferred> JobModel;
|
||||
};
|
||||
*/
|
||||
|
||||
class DrawTransparentDeferred {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<DrawTransparentDeferred> JobModel;
|
||||
};
|
||||
namespace render {
|
||||
template <> void jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||
}
|
||||
|
||||
class RenderDeferredTask : public render::Task {
|
||||
public:
|
||||
|
|
|
@ -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<DrawOpaque>()));
|
||||
_jobs.push_back(Job(new Job::Model<DrawLight>()));
|
||||
_jobs.push_back(Job(new Job::Model<DrawTransparent>()));
|
||||
_jobs.push_back(Job(new Job::Model<ResetGLState>()));
|
||||
}
|
||||
|
||||
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<ItemBound> 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()) {
|
||||
|
|
|
@ -20,22 +20,35 @@ namespace render {
|
|||
|
||||
|
||||
|
||||
template <class T> void jobRun(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { }
|
||||
template <class T, class I> void jobRunI(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) { }
|
||||
template <class T, class O> void jobRunO(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) {
|
||||
template <class T> void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
jobModel.run(sceneContext, renderContext);
|
||||
}
|
||||
template <class T, class I> void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) {
|
||||
jobModel.run(sceneContext, renderContext, input);
|
||||
}
|
||||
template <class T, class O> void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) {
|
||||
jobModel.run(sceneContext, renderContext, output);
|
||||
}
|
||||
template <class T, class I, class O> void jobRunIO(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) { }
|
||||
template <class T, class I, class O> 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 <class T>
|
||||
Varying(T data) : _concept(new Model<T>(data)) {}
|
||||
Varying(const T& data) : _concept(new Job::Varying::Model<T>(data)) {}
|
||||
|
||||
// Access the _data contained win the concept explicitely
|
||||
template <class T> T& edit() { return (static_cast<Model<T>*> (_concept.get())->_data); }
|
||||
template <class T> const T& get() const { return (static_cast<const Model<T>*> (_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> _concept;
|
||||
};
|
||||
typedef std::shared_ptr<Varying> VaryingPointer;
|
||||
|
||||
template <class T>
|
||||
Job(T data) : _concept(new Model<T>(data)) {}
|
||||
|
||||
|
||||
template <class T, class O>
|
||||
static Job* createO(T data) { return new Job(new ModelO<T, O>(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 T> 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 T, class I> 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<I>()); }
|
||||
};
|
||||
|
||||
template <class T, class O> 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<O>(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<O>());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I, class O> 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<O>(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<I>(), _output.edit<O>()); }
|
||||
};
|
||||
|
||||
std::shared_ptr<Concept> _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<FetchItems, ItemIDsBounds> 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<FetchCullItems, CulledItems> JobModel;
|
||||
typedef Job::ModelIO<CullItems, ItemIDsBounds, ItemIDsBounds> JobModel;
|
||||
};
|
||||
|
||||
class DepthSortItems {
|
||||
public:
|
||||
bool _frontToBack = true;
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
|
||||
|
||||
typedef Job::ModelIO<DepthSortItems, ItemIDsBounds, ItemIDsBounds> 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<DrawLight> 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<DrawBackground> 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<DrawPostLayered> 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<ResetGLState> 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);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue