void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& inputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); const auto& inItems = inputs.get0(); const auto& lightingModel = inputs.get1(); RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; // Setup camera, projection and viewport for all items batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); // Setup lighting model for all items; batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn); args->_batch = nullptr; }); config->setNumDrawn((int)inItems.size()); }
void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) { assert(renderContext->args); assert(renderContext->args->_context); RenderArgs* args = renderContext->args; // Return view frustum auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>(); if (!viewFrustum) { viewFrustum = std::make_shared<ViewFrustum>(args->getViewFrustum()); } else { *viewFrustum = args->getViewFrustum(); } // Return shadow frustum auto lightStage = args->_scene->getStage<LightStage>(LightStage::getName()); for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) { auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>(); if (lightStage) { auto globalShadow = lightStage->getCurrentKeyShadow(); if (globalShadow && i<(int)globalShadow->getCascadeCount()) { auto& cascade = globalShadow->getCascade(i); shadowFrustum = cascade.getFrustum(); } else { shadowFrustum.reset(); } } else { shadowFrustum.reset(); } } }
void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& inputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); const auto& inItems = inputs.get0(); const auto& lightingModel = inputs.get1(); if (!lightingModel->isBackgroundEnabled()) { return; } RenderArgs* args = renderContext->args; doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; // _gpuTimer.begin(batch); batch.enableSkybox(true); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); renderItems(sceneContext, renderContext, inItems); // _gpuTimer.end(batch); }); args->_batch = nullptr; // std::static_pointer_cast<Config>(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage(); }
void DrawQuadVolume::run(const render::RenderContextPointer& renderContext, const glm::vec3 vertices[8], const gpu::BufferView& indices, int indexCount) { assert(renderContext->args); assert(renderContext->args->_context); if (_isUpdateEnabled) { auto& streamVertices = _meshVertices.edit<std::array<glm::vec3, 8U> >(); std::copy(vertices, vertices + 8, streamVertices.begin()); } RenderArgs* args = renderContext->args; gpu::doInBatch("DrawQuadVolume::run", args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setPipeline(getPipeline()); batch.setIndexBuffer(indices); batch._glUniform4f(0, _color.x, _color.y, _color.z, 1.0f); batch.setInputStream(0, _meshStream); batch.drawIndexed(gpu::LINES, indexCount, 0U); args->_batch = nullptr; }); }
void ExtractFrustums::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) { assert(renderContext->args); assert(renderContext->args->_context); RenderArgs* args = renderContext->args; const auto& shadowFrame = inputs; // Return view frustum auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>(); if (!viewFrustum) { viewFrustum = std::make_shared<ViewFrustum>(args->getViewFrustum()); } else { *viewFrustum = args->getViewFrustum(); } // Return shadow frustum LightStage::ShadowPointer globalShadow; if (shadowFrame && !shadowFrame->_objects.empty() && shadowFrame->_objects[0]) { globalShadow = shadowFrame->_objects[0]; } for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) { auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>(); if (globalShadow && i<(int)globalShadow->getCascadeCount()) { auto& cascade = globalShadow->getCascade(i); shadowFrustum = cascade.getFrustum(); } else { shadowFrustum.reset(); } } }
void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& SourceAndDepth, gpu::FramebufferPointer& blurredFramebuffer) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; auto& sourceFramebuffer = SourceAndDepth.get0(); auto& depthTexture = SourceAndDepth.get1(); BlurInOutResource::Resources blurringResources; if (!_inOutResources.updateResources(sourceFramebuffer, blurringResources)) { // early exit if no valid blurring resources return; } blurredFramebuffer = blurringResources.finalFramebuffer; auto blurVPipeline = getBlurVPipeline(); auto blurHPipeline = getBlurHPipeline(); auto sourceViewport = args->_viewport; _parameters->setWidthHeight(sourceViewport.z, sourceViewport.w, args->_context->isStereo()); glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions()); _parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, sourceViewport)); _parameters->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]); _parameters->setLinearDepthPosFar(args->getViewFrustum().getFarClip()); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); batch.setViewportTransform(sourceViewport); batch.setUniformBuffer(BlurTask_ParamsSlot, _parameters->_parametersBuffer); batch.setResourceTexture(BlurTask_DepthSlot, depthTexture); batch.setFramebuffer(blurringResources.blurringFramebuffer); // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); batch.setPipeline(blurVPipeline); batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.sourceTexture); batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setFramebuffer(blurringResources.finalFramebuffer); if (_inOutResources._generateOutputFramebuffer) { // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); } batch.setPipeline(blurHPipeline); batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.blurringTexture); batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(BlurTask_SourceSlot, nullptr); batch.setResourceTexture(BlurTask_DepthSlot, nullptr); batch.setUniformBuffer(BlurTask_ParamsSlot, nullptr); }); }
void DrawLayered3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); const auto& inItems = inputs.get0(); const auto& lightingModel = inputs.get1(); const auto jitter = inputs.get2(); config->setNumDrawn((int)inItems.size()); emit config->numDrawnChanged(); 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 if (_opaquePass) { gpu::doInBatch("DrawLayered3D::run::clear", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, false); }); } if (!inItems.empty()) { // Render the items gpu::doInBatch("DrawLayered3D::main", args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setProjectionJitter(jitter.x, jitter.y); batch.setViewTransform(viewMat); // Setup lighting model for all items; batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setResourceTexture(ru::Texture::AmbientFresnel, lightingModel->getAmbientFresnelLUT()); if (_opaquePass) { renderStateSortShapes(renderContext, _shapePlumber, inItems, _maxDrawn); } else { renderShapes(renderContext, _shapePlumber, inItems, _maxDrawn); } args->_batch = nullptr; }); } }
bool OctreeRenderer::renderOperation(OctreeElementPointer element, void* extraData) { RenderArgs* args = static_cast<RenderArgs*>(extraData); if (element->isInView(args->getViewFrustum())) { if (element->hasContent()) { if (element->calculateShouldRender(args->getViewFrustum(), args->_sizeScale, args->_boundaryLevelAdjust)) { args->_renderer->renderElement(element, args); } else { return false; // if we shouldn't render, then we also should stop recursing. } } return true; // continue recursing } // if not in view stop recursing return false; }
void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& inputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); const auto& inItems = inputs.get0(); const auto& lightingModel = inputs.get1(); config->setNumDrawn((int)inItems.size()); emit config->numDrawnChanged(); 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 if (_opaquePass) { 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; batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); // Setup lighting model for all items; batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn); args->_batch = nullptr; }); } }
void RenderShadowSetup::run(const SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, Output& output) { auto lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage(); const auto globalShadow = lightStage->getShadow(0); // Cache old render args RenderArgs* args = renderContext->args; output = args->_renderMode; auto nearClip = args->getViewFrustum().getNearClip(); float nearDepth = -args->_boomOffset.z; const int SHADOW_FAR_DEPTH = 20; globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH); // Set the keylight render args args->pushViewFrustum(*(globalShadow->getFrustum())); args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; }
void DrawBounds::run(const RenderContextPointer& renderContext, const Inputs& items) { RenderArgs* args = renderContext->args; uint32_t numItems = (uint32_t) items.size(); if (numItems == 0) { return; } static const uint32_t sizeOfItemBound = sizeof(ItemBound); if (!_drawBuffer) { _drawBuffer = std::make_shared<gpu::Buffer>(sizeOfItemBound); } _drawBuffer->setData(numItems * sizeOfItemBound, (const gpu::Byte*) items.data()); gpu::doInBatch("DrawBounds::run", args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; // Setup projection glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); // Bind program batch.setPipeline(getPipeline()); glm::vec4 color(glm::vec3(0.0f), -(float) numItems); batch._glUniform4fv(_colorLocation, 1, (const float*)(&color)); batch.setResourceBuffer(0, _drawBuffer); static const int NUM_VERTICES_PER_CUBE = 24; batch.draw(gpu::LINES, NUM_VERTICES_PER_CUBE * numItems, 0); }); }
void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { assert(sceneContext); RenderArgs* args = renderContext->args; // sanity checks if (!sceneContext->_scene || !args) { return; } auto lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage(); const auto globalShadow = lightStage->getShadow(0); // If the global light is not set, bail if (!globalShadow) { return; } // Cache old render args RenderArgs::RenderMode mode = args->_renderMode; auto nearClip = args->getViewFrustum().getNearClip(); float nearDepth = -args->_boomOffset.z; const int SHADOW_FAR_DEPTH = 20; globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH); // Set the keylight render args args->pushViewFrustum(*(globalShadow->getFrustum())); args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; // TODO: Allow runtime manipulation of culling ShouldRenderFunctor for (auto job : _jobs) { job.run(sceneContext, renderContext); } // Reset the render args args->popViewFrustum(); args->_renderMode = mode; };
void HitEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); batch.setPipeline(getHitEffectPipeline()); glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); glm::vec2 bottomLeft(-1.0f, -1.0f); glm::vec2 topRight(1.0f, 1.0f); DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color); }); }
void DrawForward::run(const RenderContextPointer& renderContext, const Inputs& inputs) { RenderArgs* args = renderContext->args; const auto& inItems = inputs.get0(); const auto& lightingModel = inputs.get1(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; // Setup projection glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); // Setup lighting model for all items; batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); // From the lighting model define a global shapeKey ORED with individiual keys ShapeKey::Builder keyBuilder; if (lightingModel->isWireframeEnabled()) { keyBuilder.withWireframe(); } ShapeKey globalKey = keyBuilder.build(); args->_globalShapeKey = globalKey._flags.to_ulong(); // Render items renderStateSortShapes(renderContext, _shapePlumber, inItems, -1, globalKey); args->_batch = nullptr; args->_globalShapeKey = 0; }); }
void DrawSceneOctree::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; auto& scene = sceneContext->_scene; std::static_pointer_cast<Config>(renderContext->jobConfig)->numAllocatedCells = (int)scene->getSpatialTree().getNumAllocatedCells(); std::static_pointer_cast<Config>(renderContext->jobConfig)->numFreeCells = (int)scene->getSpatialTree().getNumFreeCells(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setViewportTransform(args->_viewport); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); // bind the one gpu::Pipeline we need batch.setPipeline(getDrawCellBoundsPipeline()); if (_showVisibleCells) { for (const auto& cellID : inSelection.cellSelection.insideCells) { auto cell = scene->getSpatialTree().getConcreteCell(cellID); auto cellLoc = cell.getlocation(); glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth); bool doDraw = true; if (cell.isBrickEmpty() || !cell.hasBrick()) { if (!_showEmptyCells) { doDraw = false; } cellLocation.w *= -1; } if (doDraw) { batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation))); batch.draw(gpu::LINES, 24, 0); } } for (const auto& cellID : inSelection.cellSelection.partialCells) { auto cell = scene->getSpatialTree().getConcreteCell(cellID); auto cellLoc = cell.getlocation(); glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth); bool doDraw = true; if (cell.isBrickEmpty() || !cell.hasBrick()) { if (!_showEmptyCells) { doDraw = false; } cellLocation.w *= -1; } if (doDraw) { batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation))); batch.draw(gpu::LINES, 24, 0); } } } // Draw the LOD Reticle { float angle = glm::degrees(getAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust)); Transform crosshairModel; crosshairModel.setTranslation(glm::vec3(0.0, 0.0, -1000.0)); crosshairModel.setScale(1000.0 * tan(glm::radians(angle))); // Scaling at the actual tan of the lod angle => Multiplied by TWO batch.setViewTransform(Transform()); batch.setModelTransform(crosshairModel); batch.setPipeline(getDrawLODReticlePipeline()); batch.draw(gpu::TRIANGLE_STRIP, 4, 0); } }); }
void Antialiasing::run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceBuffer) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; gpu::doInBatch("Antialiasing::run", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); batch.setViewportTransform(args->_viewport); // FIXME: NEED to simplify that code to avoid all the GeometryCahce call, this is purely pixel manipulation float fbWidth = renderContext->args->_viewport.z; float fbHeight = renderContext->args->_viewport.w; // float sMin = args->_viewport.x / fbWidth; // float sWidth = args->_viewport.z / fbWidth; // float tMin = args->_viewport.y / fbHeight; // float tHeight = args->_viewport.w / fbHeight; glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat, true); batch.setModelTransform(Transform()); // FXAA step auto pipeline = getAntialiasingPipeline(renderContext->args); batch.setResourceTexture(0, sourceBuffer->getRenderBuffer(0)); batch.setFramebuffer(_antialiasingBuffer); batch.setPipeline(pipeline); // initialize the view-space unpacking uniforms using frustum data float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; args->getViewFrustum().computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); // float depthScale = (farVal - nearVal) / farVal; // float nearScale = -1.0f / nearVal; // float depthTexCoordScaleS = (right - left) * nearScale / sWidth; // float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; // float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; // float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight); glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); glm::vec2 bottomLeft(-1.0f, -1.0f); glm::vec2 topRight(1.0f, 1.0f); glm::vec2 texCoordTopLeft(0.0f, 0.0f); glm::vec2 texCoordBottomRight(1.0f, 1.0f); DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); // Blend step batch.setResourceTexture(0, _antialiasingTexture); batch.setFramebuffer(sourceBuffer); batch.setPipeline(getBlendPipeline()); DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); }); }
void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; auto& scene = renderContext->_scene; std::static_pointer_cast<Config>(renderContext->jobConfig)->numAllocatedCells = (int)scene->getSpatialTree().getNumAllocatedCells(); std::static_pointer_cast<Config>(renderContext->jobConfig)->numFreeCells = (int)scene->getSpatialTree().getNumFreeCells(); gpu::doInBatch("DrawSceneOctree::run", args->_context, [&](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setViewportTransform(args->_viewport); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat, true); batch.setModelTransform(Transform()); // bind the one gpu::Pipeline we need batch.setPipeline(getDrawCellBoundsPipeline()); batch.setInputFormat(_cellBoundsFormat); std::vector<ivec4> cellBounds; auto drawCellBounds = [this, &cellBounds, &scene](const std::vector<gpu::Stamp>& cells) { cellBounds.reserve(cellBounds.size() + cells.size()); for (const auto& cellID : cells) { auto cell = scene->getSpatialTree().getConcreteCell(cellID); auto cellLoc = cell.getlocation(); glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth); bool empty = cell.isBrickEmpty() || !cell.hasBrick(); if (empty) { if (!_showEmptyCells) { continue; } cellLocation.w *= -1.0; } else if (!empty && !_showVisibleCells) { continue; } cellBounds.push_back(cellLocation); } }; drawCellBounds(inSelection.cellSelection.insideCells); drawCellBounds(inSelection.cellSelection.partialCells); auto size = cellBounds.size() * sizeof(ivec4); if (size > _cellBoundsBuffer->getSize()) { _cellBoundsBuffer->resize(size); } _cellBoundsBuffer->setSubData(0, cellBounds); batch.setInputBuffer(0, _cellBoundsBuffer, 0, sizeof(ivec4)); batch.drawInstanced((uint32_t)cellBounds.size(), gpu::LINES, 24); // Draw the LOD Reticle { float angle = glm::degrees(getPerspectiveAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust)); Transform crosshairModel; crosshairModel.setTranslation(glm::vec3(0.0, 0.0, -1000.0)); crosshairModel.setScale(1000.0f * tanf(glm::radians(angle))); // Scaling at the actual tan of the lod angle => Multiplied by TWO batch.resetViewTransform(); batch.setModelTransform(crosshairModel); batch.setPipeline(getDrawLODReticlePipeline()); batch.draw(gpu::TRIANGLE_STRIP, 4, 0); } }); }
void DrawItemSelection::run(const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; auto& scene = renderContext->_scene; if (!_boundsBufferInside) { _boundsBufferInside = std::make_shared<gpu::Buffer>(sizeof(render::ItemBound)); } if (!_boundsBufferInsideSubcell) { _boundsBufferInsideSubcell = std::make_shared<gpu::Buffer>(sizeof(render::ItemBound)); } if (!_boundsBufferPartial) { _boundsBufferPartial = std::make_shared<gpu::Buffer>(sizeof(render::ItemBound)); } if (!_boundsBufferPartialSubcell) { _boundsBufferPartialSubcell = std::make_shared<gpu::Buffer>(sizeof(render::ItemBound)); } gpu::doInBatch("DrawItemSelection::run", args->_context, [&](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setViewportTransform(args->_viewport); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat, true); batch.setModelTransform(Transform()); // bind the one gpu::Pipeline we need batch.setPipeline(getDrawItemBoundPipeline()); auto drawItemBounds = [&](const render::ItemIDs itemIDs, const gpu::BufferPointer buffer) { render::ItemBounds itemBounds; for (const auto& itemID : itemIDs) { auto& item = scene->getItem(itemID); auto itemBound = item.getBound(); if (!itemBound.isInvalid()) { itemBounds.emplace_back(itemID, itemBound); } } if (itemBounds.size() > 0) { buffer->setData(itemBounds.size() * sizeof(render::ItemBound), (const gpu::Byte*) itemBounds.data()); batch.setResourceBuffer(0, buffer); batch.draw(gpu::LINES, (gpu::uint32) itemBounds.size() * 24, 0); } }; if (_showInsideItems) { drawItemBounds(inSelection.insideItems, _boundsBufferInside); } if (_showInsideSubcellItems) { drawItemBounds(inSelection.insideSubcellItems, _boundsBufferInsideSubcell); } if (_showPartialItems) { drawItemBounds(inSelection.partialItems, _boundsBufferPartial); } if (_showPartialSubcellItems) { drawItemBounds(inSelection.partialSubcellItems, _boundsBufferPartialSubcell); } batch.setResourceBuffer(0, 0); }); }
void DrawItemSelection::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; auto& scene = sceneContext->_scene; gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setViewportTransform(args->_viewport); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); // bind the one gpu::Pipeline we need batch.setPipeline(getDrawItemBoundPipeline()); if (_showInsideItems) { for (const auto& itemID : inSelection.insideItems) { auto& item = scene->getItem(itemID); auto itemBound = item.getBound(); auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell()); glm::ivec4 cellLocation(0, 0, 0, itemCell.depth); batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation))); batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner())); batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale())); batch.draw(gpu::LINES, 24, 0); } } if (_showInsideSubcellItems) { for (const auto& itemID : inSelection.insideSubcellItems) { auto& item = scene->getItem(itemID); auto itemBound = item.getBound(); auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell()); glm::ivec4 cellLocation(0, 0, 1, itemCell.depth); batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation))); batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner())); batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale())); batch.draw(gpu::LINES, 24, 0); } } if (_showPartialItems) { for (const auto& itemID : inSelection.partialItems) { auto& item = scene->getItem(itemID); auto itemBound = item.getBound(); auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell()); glm::ivec4 cellLocation(0, 0, 0, itemCell.depth); batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation))); batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner())); batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale())); batch.draw(gpu::LINES, 24, 0); } } if (_showPartialSubcellItems) { for (const auto& itemID : inSelection.partialSubcellItems) { auto& item = scene->getItem(itemID); auto itemBound = item.getBound(); auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell()); glm::ivec4 cellLocation(0, 0, 1, itemCell.depth); batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation))); batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner())); batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale())); batch.draw(gpu::LINES, 24, 0); } } }); }