void render::renderStateSortShapes(const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems, const ShapeKey& globalKey) { auto& scene = renderContext->_scene; RenderArgs* args = renderContext->args; int numItemsToDraw = (int)inItems.size(); if (maxDrawnItems != -1) { numItemsToDraw = glm::min(numItemsToDraw, maxDrawnItems); } using SortedPipelines = std::vector<render::ShapeKey>; using SortedShapes = std::unordered_map<render::ShapeKey, std::vector<Item>, render::ShapeKey::Hash, render::ShapeKey::KeyEqual>; SortedPipelines sortedPipelines; SortedShapes sortedShapes; std::vector< std::tuple<Item,ShapeKey> > ownPipelineBucket; for (auto i = 0; i < numItemsToDraw; ++i) { auto& item = scene->getItem(inItems[i].id); { assert(item.getKey().isShape()); auto key = item.getShapeKey() | globalKey; if (key.isValid() && !key.hasOwnPipeline()) { auto& bucket = sortedShapes[key]; if (bucket.empty()) { sortedPipelines.push_back(key); } bucket.push_back(item); } else if (key.hasOwnPipeline()) { ownPipelineBucket.push_back( std::make_tuple(item, key) ); } else { std::call_once(messageIDFlag, [](int* id) { *id = LogHandler::getInstance().newRepeatedMessageID(); }, &repeatedInvalidKeyMessageID); HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } } } // Then render for (auto& pipelineKey : sortedPipelines) { auto& bucket = sortedShapes[pipelineKey]; args->_shapePipeline = shapeContext->pickPipeline(args, pipelineKey); if (!args->_shapePipeline) { continue; } args->_itemShapeKey = pipelineKey._flags.to_ulong(); for (auto& item : bucket) { args->_shapePipeline->prepareShapeItem(args, pipelineKey, item); item.render(args); } } args->_shapePipeline = nullptr; for (auto& itemAndKey : ownPipelineBucket) { auto& item = std::get<0>(itemAndKey); args->_itemShapeKey = std::get<1>(itemAndKey)._flags.to_ulong(); item.render(args); } args->_itemShapeKey = 0; }
void render::renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems) { auto& scene = sceneContext->_scene; RenderArgs* args = renderContext->args; int numItemsToDraw = (int)inItems.size(); if (maxDrawnItems != -1) { numItemsToDraw = glm::min(numItemsToDraw, maxDrawnItems); } using SortedPipelines = std::vector<render::ShapeKey>; using SortedShapes = std::unordered_map<render::ShapeKey, std::vector<Item>, render::ShapeKey::Hash, render::ShapeKey::KeyEqual>; SortedPipelines sortedPipelines; SortedShapes sortedShapes; std::vector<Item> ownPipelineBucket; for (auto i = 0; i < numItemsToDraw; ++i) { auto item = scene->getItem(inItems[i].id); { assert(item.getKey().isShape()); const auto& key = item.getShapeKey(); if (key.isValid() && !key.hasOwnPipeline()) { auto& bucket = sortedShapes[key]; if (bucket.empty()) { sortedPipelines.push_back(key); } bucket.push_back(item); } else if (key.hasOwnPipeline()) { ownPipelineBucket.push_back(item); } else { qDebug() << "Item could not be rendered with invalid key" << key; } } } // Then render for (auto& pipelineKey : sortedPipelines) { auto& bucket = sortedShapes[pipelineKey]; args->_pipeline = shapeContext->pickPipeline(args, pipelineKey); if (!args->_pipeline) { continue; } for (auto& item : bucket) { item.render(args); } } args->_pipeline = nullptr; for (auto& item : ownPipelineBucket) { item.render(args); } }
void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item) { assert(item.getKey().isShape()); const auto& key = item.getShapeKey(); if (key.isValid() && !key.hasOwnPipeline()) { args->_pipeline = shapeContext->pickPipeline(args, key); if (args->_pipeline) { item.render(args); } args->_pipeline = nullptr; } else if (key.hasOwnPipeline()) { item.render(args); } else { qDebug() << "Item could not be rendered with invalid key" << key; } }
void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item, const ShapeKey& globalKey) { assert(item.getKey().isShape()); auto key = item.getShapeKey() | globalKey; args->_itemShapeKey = key._flags.to_ulong(); if (key.isValid() && !key.hasOwnPipeline()) { args->_shapePipeline = shapeContext->pickPipeline(args, key); if (args->_shapePipeline) { args->_shapePipeline->prepareShapeItem(args, key, item); item.render(args); } args->_shapePipeline = nullptr; } else if (key.hasOwnPipeline()) { item.render(args); } else { std::call_once(messageIDFlag, [](int* id) { *id = LogHandler::getInstance().newRepeatedMessageID(); }, &repeatedInvalidKeyMessageID); HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } args->_itemShapeKey = 0; }