diff --git a/src/applications/osgearth_imgui/osgearth_imgui.cpp b/src/applications/osgearth_imgui/osgearth_imgui.cpp index 656852ae99..03b787538f 100644 --- a/src/applications/osgearth_imgui/osgearth_imgui.cpp +++ b/src/applications/osgearth_imgui/osgearth_imgui.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -120,6 +121,7 @@ main(int argc, char** argv) ui->add("Tools", new TerrainGUI()); ui->add("Tools", new TextureInspectorGUI()); ui->add("Tools", new ViewpointsGUI()); + ui->add("Tools", new LiveCamerasGUI()); #ifdef OSGEARTH_HAVE_CESIUM_NODEKIT ui->add("Cesium", new osgEarth::Cesium::CesiumIonGUI()); diff --git a/src/osgEarthImGui/CMakeLists.txt b/src/osgEarthImGui/CMakeLists.txt index 5296cf6a28..cecfa4a0d1 100644 --- a/src/osgEarthImGui/CMakeLists.txt +++ b/src/osgEarthImGui/CMakeLists.txt @@ -24,6 +24,7 @@ set(STOCK_PANELS NetworkMonitorGUI NotifyGUI OpenEarthFileGUI + LiveCamerasGUI PickerGUI RenderingGUI SceneGraphGUI diff --git a/src/osgEarthImGui/LiveCamerasGUI b/src/osgEarthImGui/LiveCamerasGUI new file mode 100644 index 0000000000..82894401c6 --- /dev/null +++ b/src/osgEarthImGui/LiveCamerasGUI @@ -0,0 +1,172 @@ +/* -*-c++-*- */ +/* osgEarth - Geospatial SDK for OpenSceneGraph + * Copyright 2018 Pelican Mapping + * http://osgearth.org + * + * osgEarth is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see + */ +#pragma once + +#include +#include + +#include + + + +namespace osgEarth +{ + class LiveCamerasGUI : public ImGuiPanel + { + public: + LiveCamerasGUI() : + ImGuiPanel("Live Cameras") + { + memset(_name, 0, sizeof(_name)); + } + + void draw(osg::RenderInfo& ri) override + { + if (!isVisible()) return; + if (!findNodeOrHide(_mapNode, ri)) return; + + osgViewer::View* view = dynamic_cast(ri.getView()); + + if (!_installed) + { + _root = new osg::Group(); + view->getSceneData()->asGroup()->addChild(_root.get()); + _installed = true; + } + + ImGui::Begin(name(), visible()); + + ImGui::InputText("Name", _name, IM_ARRAYSIZE(_name)); + + if (ImGui::Button("Add")) + { + auto currentCamera = ri.getCurrentCamera(); + + float width = currentCamera->getViewport()->width(); + float height = currentCamera->getViewport()->height(); + double aspectRatio = width / height; + + height = 200.0; + width = height * aspectRatio; + + osg::Camera* camera = new osg::Camera; + std::string name = std::string(_name); + if (name.empty()) + { + name = "Camera " + std::to_string(_root->getNumChildren() + 1); + } + camera->setName(name); + camera->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 1.0)); + camera->setClearDepth(1.0); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); + + camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); + camera->setRenderOrder(osg::Camera::PRE_RENDER); + camera->setAllowEventFocus(false); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + + camera->setViewMatrix(currentCamera->getViewMatrix()); + camera->setProjectionMatrix(currentCamera->getProjectionMatrix()); + + osg::Viewport* viewport = new osg::Viewport(0, 0, width, height); + + camera->setViewport(viewport); + camera->setImplicitBufferAttachmentMask(0, 0); + camera->setSmallFeatureCullingPixelSize(0.0f); + + osg::Texture2D* colorTexture = new osg::Texture2D; + colorTexture->setInternalFormat(GL_RGBA8); + colorTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); + colorTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); + colorTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + colorTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + colorTexture->setTextureSize(width, height); + camera->attach(osg::Camera::COLOR_BUFFER0, colorTexture); + + /* + osg::Texture2D* depthTexture = new osg::Texture2D(); + depthTexture->setTextureSize(width, height); + depthTexture->setSourceFormat(GL_DEPTH_COMPONENT); + depthTexture->setSourceType(GL_FLOAT); + depthTexture->setInternalFormat(GL_DEPTH_COMPONENT24); + depthTexture->setBorderWidth(0); + depthTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); + depthTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); + depthTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + depthTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + camera->attach(osg::Camera::DEPTH_BUFFER, depthTexture); + */ + + + + camera->addChild(_mapNode.get()); + + _root->addChild(camera); + } + + osg::Camera* toRemove = nullptr; + + for (unsigned int i = 0; i < _root->getNumChildren(); i++) + { + osg::Camera* camera = dynamic_cast(_root->getChild(i)); + if (camera) + { + ImGui::PushID(camera); + ImGui::Text(camera->getName().c_str()); + if (ImGui::Button("Zoom to")) + { + auto manip = view->getCameraManipulator(); + manip->setByInverseMatrix(camera->getViewMatrix()); + } + ImGui::SameLine(); + if (ImGui::Button("Remove")) + { + toRemove = camera; + } + auto colorAttachment = camera->getBufferAttachmentMap().find(osg::Camera::COLOR_BUFFER0); + if (colorAttachment != camera->getBufferAttachmentMap().end()) + { + osg::Texture2D* texture = dynamic_cast(colorAttachment->second._texture.get()); + if (texture) + { + ImGuiEx::OSGTexture(texture, ri, 200); + } + } + ImGui::Separator(); + ImGui::PopID(); + } + } + + if (toRemove) + { + _root->removeChild(toRemove); + } + + ImGui::End(); + } + + private: + char _name[1024]; + osg::ref_ptr< osg::Group > _root; + osg::observer_ptr _mapNode; + bool _installed = false; + }; +}