in src/utils/viewer/viewer.cpp [1417:1591]
void Viewer::drawEvent() {
// Wrap profiler measurements around all methods to render images from
// RenderCamera
profiler_.beginFrame();
Mn::GL::defaultFramebuffer.clear(Mn::GL::FramebufferClear::Color |
Mn::GL::FramebufferClear::Depth);
// Agent actions should occur at a fixed rate per second
timeSinceLastSimulation += timeline_.previousFrameDuration();
int numAgentActions = timeSinceLastSimulation * agentActionsPerSecond;
moveAndLook(numAgentActions);
// occasionally a frame will pass quicker than 1/60 seconds
if (timeSinceLastSimulation >= 1.0 / 60.0) {
if (simulating_ || simulateSingleStep_) {
// step physics at a fixed rate
// In the interest of frame rate, only a single step is taken,
// even if timeSinceLastSimulation is quite large
simulator_->stepWorld(1.0 / 60.0);
simulateSingleStep_ = false;
const auto recorder = simulator_->getGfxReplayManager()->getRecorder();
if (recorder) {
recorder->saveKeyframe();
}
}
// reset timeSinceLastSimulation, accounting for potential overflow
timeSinceLastSimulation = fmod(timeSinceLastSimulation, 1.0 / 60.0);
}
uint32_t visibles = renderCamera_->getPreviousNumVisibleDrawables();
if ((visualizeMode_ == VisualizeMode::RGBA) &&
(sensorMode_ == VisualSensorMode::Camera)) {
// Visualizing RGBA pinhole camera
if (mouseGrabber_ != nullptr) {
mouseGrabber_->renderDebugLines();
}
// ============= regular RGB with object picking =================
// using polygon offset to increase mesh depth to avoid z-fighting with
// debug draw (since lines will not respond to offset).
Mn::GL::Renderer::enable(Mn::GL::Renderer::Feature::PolygonOffsetFill);
Mn::GL::Renderer::setPolygonOffset(1.0f, 0.1f);
// ONLY draw the content to the frame buffer but not immediately blit the
// result to the default main buffer
// (this is the reason we do not call displayObservation)
simulator_->drawObservation(defaultAgentId_, sensorVisID_);
Mn::GL::Renderer::setDepthFunction(
Mn::GL::Renderer::DepthFunction::LessOrEqual);
if (debugBullet_) {
Mn::Matrix4 camM(renderCamera_->cameraMatrix());
Mn::Matrix4 projM(renderCamera_->projectionMatrix());
simulator_->physicsDebugDraw(projM * camM);
}
Mn::GL::Renderer::setDepthFunction(Mn::GL::Renderer::DepthFunction::Less);
Mn::GL::Renderer::setPolygonOffset(0.0f, 0.0f);
Mn::GL::Renderer::disable(Mn::GL::Renderer::Feature::PolygonOffsetFill);
visibles = renderCamera_->getPreviousNumVisibleDrawables();
esp::gfx::RenderTarget* sensorRenderTarget =
simulator_->getRenderTarget(defaultAgentId_, sensorVisID_);
CORRADE_ASSERT(sensorRenderTarget,
"Error in Viewer::drawEvent: sensor's rendering target "
"cannot be nullptr.", );
if (objectPickingHelper_->isObjectPicked()) {
// we need to immediately draw picked object to the SAME frame buffer
// so bind it first
// bind the framebuffer
sensorRenderTarget->renderReEnter();
// setup blending function
Mn::GL::Renderer::enable(Mn::GL::Renderer::Feature::Blending);
// render the picked object on top of the existing contents
esp::gfx::RenderCamera::Flags flags;
if (simulator_->isFrustumCullingEnabled()) {
flags |= esp::gfx::RenderCamera::Flag::FrustumCulling;
}
renderCamera_->draw(objectPickingHelper_->getDrawables(), flags);
Mn::GL::Renderer::disable(Mn::GL::Renderer::Feature::Blending);
}
sensorRenderTarget->blitRgbaToDefault();
} else {
// Depth Or Semantic, or Non-pinhole RGBA
simulator_->drawObservation(defaultAgentId_, sensorVisID_);
esp::gfx::RenderTarget* sensorRenderTarget =
simulator_->getRenderTarget(defaultAgentId_, sensorVisID_);
CORRADE_ASSERT(sensorRenderTarget,
"Error in Viewer::drawEvent: sensor's rendering target "
"cannot be nullptr.", );
if (visualizeMode_ == VisualizeMode::Depth) {
simulator_->visualizeObservation(defaultAgentId_, sensorVisID_,
1.0f / 512.0f, // colorMapOffset
1.0f / 12.0f); // colorMapScale
} else if (visualizeMode_ == VisualizeMode::Semantic) {
simulator_->visualizeObservation(defaultAgentId_, sensorVisID_);
}
sensorRenderTarget->blitRgbaToDefault();
}
// Immediately bind the main buffer back so that the "imgui" below can work
// properly
Mn::GL::defaultFramebuffer.bind();
// Do not include ImGui content drawing in per frame profiler measurements
profiler_.endFrame();
imgui_.newFrame();
ImGui::SetNextWindowPos(ImVec2(10, 10));
if (showFPS_) {
ImGui::Begin("main", NULL,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground |
ImGuiWindowFlags_AlwaysAutoResize);
ImGui::SetWindowFontScale(1.5);
ImGui::Text("%.1f FPS", Mn::Double(ImGui::GetIO().Framerate));
uint32_t total = activeSceneGraph_->getDrawables().size();
ImGui::Text("%u drawables", total);
if (sensorMode_ == VisualSensorMode::Camera) {
ImGui::Text("%u culled", total - visibles);
}
auto& cam = getAgentCamera();
switch (sensorMode_) {
case VisualSensorMode::Camera:
if (cam.getCameraType() == esp::sensor::SensorSubType::Orthographic) {
ImGui::Text("Orthographic camera sensor");
} else if (cam.getCameraType() == esp::sensor::SensorSubType::Pinhole) {
ImGui::Text("Pinhole camera sensor");
};
break;
case VisualSensorMode::Fisheye:
ImGui::Text("Fisheye sensor");
break;
case VisualSensorMode::Equirectangular:
ImGui::Text("Equirectangular sensor");
break;
default:
break;
}
ImGui::Text("%s", profiler_.statistics().c_str());
std::string modeText =
"Mouse Interaction Mode: " + mouseModeNames.at(mouseInteractionMode);
ImGui::Text("%s", modeText.c_str());
if (!semanticTag_.empty()) {
ImGui::Text("Semantic %s", semanticTag_.c_str());
}
ImGui::End();
}
/* Set appropriate states. If you only draw ImGui, it is sufficient to
just enable blending and scissor test in the constructor. */
Mn::GL::Renderer::enable(Mn::GL::Renderer::Feature::Blending);
Mn::GL::Renderer::enable(Mn::GL::Renderer::Feature::ScissorTest);
Mn::GL::Renderer::disable(Mn::GL::Renderer::Feature::FaceCulling);
Mn::GL::Renderer::disable(Mn::GL::Renderer::Feature::DepthTest);
imgui_.drawFrame();
/* Reset state. Only needed if you want to draw something else with
different state after. */
Mn::GL::Renderer::enable(Mn::GL::Renderer::Feature::DepthTest);
Mn::GL::Renderer::enable(Mn::GL::Renderer::Feature::FaceCulling);
Mn::GL::Renderer::disable(Mn::GL::Renderer::Feature::ScissorTest);
Mn::GL::Renderer::disable(Mn::GL::Renderer::Feature::Blending);
swapBuffers();
timeline_.nextFrame();
redraw();
} // Viewer::drawEvent()