void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { assert(renderContext->args); assert(renderContext->args->_viewFrustum); // render backgrounds auto& scene = sceneContext->_scene; auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered()); ItemIDsBounds inItems; inItems.reserve(items.size()); for (auto id : items) { auto& item = scene->getItem(id); if (item.getKey().isVisible() && (item.getLayer() == 1)) { inItems.emplace_back(id); } } renderContext->_numFeedOverlay3DItems = inItems.size(); renderContext->_numDrawnOverlay3DItems = inItems.size(); if (!inItems.empty()) { RenderArgs* args = renderContext->args; // Clear the framebuffer without stereo // Needs to be distinct from the other batch because using the clear call // while stereo is enabled triggers a warning { gpu::Batch batch; batch.enableStereo(false); batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, true); args->_context->render(batch); } // Render the items gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; args->_whiteTexture = DependencyManager::get<TextureCache>()->getWhiteTexture(); glm::mat4 projMat; Transform viewMat; args->_viewFrustum->evalProjectionMatrix(projMat); args->_viewFrustum->evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, args->_whiteTexture); renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems); }); args->_batch = nullptr; args->_whiteTexture.reset(); } }
void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { assert(renderContext->args); assert(renderContext->args->_viewFrustum); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; config->numDrawn = (int)inItems.size(); glm::mat4 projMat; Transform viewMat; args->_viewFrustum->evalProjectionMatrix(projMat); args->_viewFrustum->evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn); args->_batch = nullptr; }); }
void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { assert(renderContext->args); assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; renderContext->_numDrawnTransparentItems = inItems.size(); glm::mat4 projMat; Transform viewMat; args->_viewFrustum->evalProjectionMatrix(projMat); args->_viewFrustum->evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems); args->_batch = nullptr; }); }
void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { assert(renderContext->args); assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; auto& scene = sceneContext->_scene; // FIrst thing, we collect the bound and the status for all the items we want to render int nbItems = 0; { if (!_itemBounds) { _itemBounds = std::make_shared<gpu::Buffer>(); } if (!_itemStatus) { _itemStatus = std::make_shared<gpu::Buffer>();; } _itemBounds->resize((inItems.size() * sizeof(AABox))); _itemStatus->resize((inItems.size() * sizeof(glm::vec4))); AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData()); glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData()); for (auto& item : inItems) { if (!item.bounds.isInvalid()) { if (!item.bounds.isNull()) { (*itemAABox) = item.bounds; } else { (*itemAABox).setBox(item.bounds.getCorner(), 0.1f); } auto& itemScene = scene->getItem(item.id); (*itemStatus) = itemScene.getStatusPackedValues(); nbItems++; itemAABox++; itemStatus++; } } } if (nbItems == 0) { return; } // Allright, something to render let's do it gpu::Batch batch; glm::mat4 projMat; Transform viewMat; args->_viewFrustum->evalProjectionMatrix(projMat); args->_viewFrustum->evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); // bind the one gpu::Pipeline we need batch.setPipeline(getDrawItemBoundsPipeline()); AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData()); glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData()); const unsigned int VEC3_ADRESS_OFFSET = 3; for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i)); batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); batch.draw(gpu::LINES, 24, 0); } batch.setPipeline(getDrawItemStatusPipeline()); for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i)); batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i)); batch.draw(gpu::TRIANGLES, 24, 0); } args->_context->render(batch); }
void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { assert(renderContext->getArgs()); assert(renderContext->getArgs()->_viewFrustum); RenderArgs* args = renderContext->getArgs(); auto& scene = sceneContext->_scene; const int NUM_STATUS_VEC4_PER_ITEM = 2; const int VEC4_LENGTH = 4; // FIrst thing, we collect the bound and the status for all the items we want to render int nbItems = 0; { if (!_itemBounds) { _itemBounds = std::make_shared<gpu::Buffer>(); } if (!_itemStatus) { _itemStatus = std::make_shared<gpu::Buffer>();; } _itemBounds->resize((inItems.size() * sizeof(AABox))); _itemStatus->resize((inItems.size() * NUM_STATUS_VEC4_PER_ITEM * sizeof(glm::vec4))); AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData()); glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData()); for (auto& item : inItems) { if (!item.bounds.isInvalid()) { if (!item.bounds.isNull()) { (*itemAABox) = item.bounds; } else { (*itemAABox).setBox(item.bounds.getCorner(), 0.1f); } auto& itemScene = scene->getItem(item.id); auto itemStatusPointer = itemScene.getStatus(); if (itemStatusPointer) { // Query the current status values, this is where the statusGetter lambda get called auto&& currentStatusValues = itemStatusPointer->getCurrentValues(); int valueNum = 0; for (int vec4Num = 0; vec4Num < NUM_STATUS_VEC4_PER_ITEM; vec4Num++) { (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); for (int component = 0; component < VEC4_LENGTH; component++) { valueNum = vec4Num * VEC4_LENGTH + component; if (valueNum < (int)currentStatusValues.size()) { (*itemStatus)[component] = currentStatusValues[valueNum].getPackedData(); } } itemStatus++; } } else { (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); itemStatus++; (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); itemStatus++; } nbItems++; itemAABox++; } } } if (nbItems == 0) { return; } // Allright, something to render let's do it gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->_viewFrustum->evalProjectionMatrix(projMat); args->_viewFrustum->evalViewTransform(viewMat); batch.setViewportTransform(args->_viewport); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); // bind the one gpu::Pipeline we need batch.setPipeline(getDrawItemBoundsPipeline()); AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData()); glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData()); const unsigned int VEC3_ADRESS_OFFSET = 3; if ((renderContext->getDrawStatus() & showDisplayStatusFlag) > 0) { for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i)); batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); batch.draw(gpu::LINES, 24, 0); } } batch.setResourceTexture(0, gpu::TextureView(getStatusIconMap(), 0)); batch.setPipeline(getDrawItemStatusPipeline()); if ((renderContext->getDrawStatus() & showNetworkStatusFlag) > 0) { for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i)); batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); batch._glUniform4iv(_drawItemStatusValue0Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i)); batch._glUniform4iv(_drawItemStatusValue1Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i + 1)); batch.draw(gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM, 0); } } batch.setResourceTexture(0, 0); }); }