2025-03-13 00:42:41 +00:00
2025-01-04 04:12:51 +00:00
# include "app/Application.h"
# include "common/SpdLogger.h"
# include "common/RecourceHelper.h"
# include "common/CrashHandler.h"
# include "ui/MainFrame.h"
2025-03-13 00:42:41 +00:00
# include "ui/MainWindow.h"
# include "viewer/OsgWidget.h"
2025-01-04 04:12:51 +00:00
2025-03-13 00:42:41 +00:00
# include <QTimer>
# include <QApplication>
# include <QGridLayout>
2025-01-04 04:12:51 +00:00
2025-03-13 00:42:41 +00:00
# include <osgViewer/CompositeViewer>
# include <osgViewer/ViewerEventHandlers>
2025-01-04 04:12:51 +00:00
2025-03-13 00:42:41 +00:00
# include <osgGA/MultiTouchTrackballManipulator>
2025-01-04 04:12:51 +00:00
2025-03-13 00:42:41 +00:00
# include <osgDB/ReadFile>
# include <osgEarth/MapNode>
# include <osgEarthUtil/ExampleResources>
# include <osgGA/StateSetManipulator>
// #include <osgEarth/GLUtils>
2025-01-04 04:12:51 +00:00
2025-03-13 00:42:41 +00:00
# include "osgqt/GraphicsWindowQt.h"
# include "scene/ui/CompositeWidgetManager.h"
# include "scene/ui/QueryElevationWidget.h"
# ifndef LC
# define LC "DYT"
# endif
const unsigned int MASK_2D = 0xF0000000 ;
std : : string path = " D: \\ Project \\ DYT \\ Source \\ bin \\ Release \\ data \\ " ;
bool scrollWindow ( osgWidget : : Event & ev ) {
// The first thing we need to do is make sure we have a Frame object...
osgWidget : : Frame * frame = dynamic_cast < osgWidget : : Frame * > ( ev . getWindow ( ) ) ;
if ( ! frame ) return false ;
// And now we need to make sure our Frame has a valid internal EmbeddedWindow widget.
osgWidget : : Window : : EmbeddedWindow * ew =
dynamic_cast < osgWidget : : Window : : EmbeddedWindow * > ( frame - > getEmbeddedWindow ( ) )
;
if ( ! ew ) return false ;
// Lets get the visible area so that we can use it to make sure our scrolling action
// is necessary in the first place.
const osgWidget : : Quad & va = ew - > getWindow ( ) - > getVisibleArea ( ) ;
// The user wants to scroll up; make sure that the visible area's Y origin isn't already
// at 0.0f, 0.0f.
if ( ev . getWindowManager ( ) - > isMouseScrollingUp ( ) & & va [ 1 ] ! = 0.0f )
ew - > getWindow ( ) - > addVisibleArea ( 0 , - 20 )
;
else if ( va [ 1 ] < = ( ew - > getWindow ( ) - > getHeight ( ) - ew - > getHeight ( ) ) )
ew - > getWindow ( ) - > addVisibleArea ( 0 , 20 )
;
// We need to manually call update to make sure the visible area scissoring is done
// properly.
frame - > update ( ) ;
return true ;
}
bool changeTheme ( osgWidget : : Event & ev ) {
std : : string theme ;
if ( ev . key = = osgGA : : GUIEventAdapter : : KEY_Right )
theme = " osgWidget/theme-1.png "
;
else if ( ev . key = = osgGA : : GUIEventAdapter : : KEY_Left )
theme = " osgWidget/theme-2.png "
;
else return false ;
osgWidget : : Frame * frame = dynamic_cast < osgWidget : : Frame * > ( ev . getWindow ( ) ) ;
if ( ! frame ) return false ;
// This is just one way to access all our Widgets; we could just as well have used:
//
// for(osgWidget::Frame::Iterator i = frame.begin(); i != frame.end() i++) {}
//
// ...and it have worked, too.
for ( unsigned int row = 0 ; row < 3 ; row + + ) {
for ( unsigned int col = 0 ; col < 3 ; col + + ) {
frame - > getByRowCol ( row , col ) - > setImage ( theme ) ;
}
}
return true ;
}
osg : : Node * createUiExample ( osgViewer : : View * viewer , osgWidget : : WindowManager * wm ) {
if ( ! wm ) return nullptr ;
// viewer.setUpViewInWindow(
// 50,
// 50,
// static_cast<int>(wm->getWidth()),
// static_cast<int>(wm->getHeight())
// );
osg : : Group * group = new osg : : Group ( ) ;
osg : : Camera * camera = wm - > createParentOrthoCamera ( ) ;
group - > addChild ( camera ) ;
viewer - > addEventHandler ( new osgWidget : : MouseHandler ( wm ) ) ;
viewer - > addEventHandler ( new osgWidget : : KeyboardHandler ( wm ) ) ;
viewer - > addEventHandler ( new osgWidget : : ResizeHandler ( wm , camera ) ) ;
viewer - > addEventHandler ( new osgWidget : : CameraSwitchHandler ( wm , camera ) ) ;
viewer - > addEventHandler ( new osgViewer : : StatsHandler ( ) ) ;
viewer - > addEventHandler ( new osgViewer : : WindowSizeHandler ( ) ) ;
viewer - > addEventHandler ( new osgGA : : StateSetManipulator (
viewer - > getCamera ( ) - > getOrCreateStateSet ( )
) ) ;
wm - > resizeAllWindows ( ) ;
return group ;
}
void creatWidget ( osgViewer : : View * viewer , osg : : Group * root ) {
osgWidget : : WindowManager * wm = new osgWidget : : WindowManager (
viewer ,
1280.0f ,
1024.0f ,
MASK_2D ,
osgWidget : : WindowManager : : WM_PICK_DEBUG
//osgWidget::WindowManager::WM_NO_INVERT_Y
) ;
osgWidget : : Frame * frame = osgWidget : : Frame : : createSimpleFrameFromTheme (
" frame " ,
osgDB : : readRefImageFile ( " osgWidget/theme.png " ) ,
40.0f ,
40.0f ,
osgWidget : : Frame : : FRAME_ALL
) ;
osgWidget : : Box * box = new osgWidget : : Box ( " images " , osgWidget : : Box : : VERTICAL ) ;
osgWidget : : Widget * img1 = new osgWidget : : Widget ( " im1 " , 512.0f , 512.0f ) ;
osgWidget : : Widget * img2 = new osgWidget : : Widget ( " im2 " , 512.0f , 512.0f ) ;
osgWidget : : Widget * img3 = new osgWidget : : Widget ( " im3 " , 512.0f , 512.0f ) ;
osgWidget : : Widget * img4 = new osgWidget : : Widget ( " im4 " , 512.0f , 512.0f ) ;
img1 - > setImage ( path + " osgWidget/scrolled1.jpg " , true ) ;
img2 - > setImage ( path + " osgWidget/scrolled2.jpg " , true ) ;
img3 - > setImage ( path + " osgWidget/scrolled3.jpg " , true ) ;
img4 - > setImage ( path + " osgWidget/scrolled4.jpg " , true ) ;
img1 - > setMinimumSize ( 10.0f , 10.0f ) ;
img2 - > setMinimumSize ( 10.0f , 10.0f ) ;
img3 - > setMinimumSize ( 10.0f , 10.0f ) ;
img4 - > setMinimumSize ( 10.0f , 10.0f ) ;
box - > addWidget ( img1 ) ;
box - > addWidget ( img2 ) ;
box - > addWidget ( img3 ) ;
box - > addWidget ( img4 ) ;
box - > setEventMask ( osgWidget : : EVENT_NONE ) ;
//frame->getEmbeddedWindow()->setWindow(box);
frame - > setWindow ( box ) ;
frame - > getEmbeddedWindow ( ) - > setColor ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
frame - > resize ( 300.0f , 300.0f ) ;
frame - > addCallback ( new osgWidget : : Callback ( & scrollWindow , osgWidget : : EVENT_MOUSE_SCROLL ) ) ;
frame - > addCallback ( new osgWidget : : Callback ( & changeTheme , osgWidget : : EVENT_KEY_DOWN ) ) ;
wm - > addChild ( frame ) ;
osg : : Node * ui = createUiExample ( viewer , wm ) ;
root - > addChild ( ui ) ;
}
void configureView ( osgViewer : : View * view )
{
// default uniform values:
// GLUtils::setGlobalDefaults(view->getCamera()->getOrCreateStateSet());
// add some stock OSG handlers:
view - > addEventHandler ( new osgViewer : : StatsHandler ( ) ) ;
view - > addEventHandler ( new osgViewer : : WindowSizeHandler ( ) ) ;
view - > addEventHandler ( new osgViewer : : ThreadingHandler ( ) ) ;
view - > addEventHandler ( new osgViewer : : LODScaleHandler ( ) ) ;
view - > addEventHandler ( new osgGA : : StateSetManipulator ( view - > getCamera ( ) - > getOrCreateStateSet ( ) ) ) ;
view - > addEventHandler ( new osgViewer : : RecordCameraPathHandler ( ) ) ;
view - > addEventHandler ( new osgViewer : : ScreenCaptureHandler ( ) ) ;
}
osg : : Node * LoadEarth ( const std : : string & earth , osgViewer : : CompositeViewer * viewer ) {
osg : : ref_ptr < osg : : Node > node = osgDB : : readNodeFile ( earth ) ;
osg : : ref_ptr < osgEarth : : MapNode > mapNode = osgEarth : : MapNode : : get ( node . get ( ) ) ;
if ( ! mapNode . valid ( ) )
{
OE_WARN < < LC < < " Loaded scene graph does not contain a MapNode - aborting " < < std : : endl ;
return 0L ;
}
// collect the views
osgViewer : : Viewer : : Views views ;
if ( viewer )
{
viewer - > getViews ( views ) ;
}
// warn about not having an earth manip
for ( osgViewer : : Viewer : : Views : : iterator view = views . begin ( ) ; view ! = views . end ( ) ; + + view )
{
osgEarth : : Util : : EarthManipulator * manip = dynamic_cast < osgEarth : : Util : : EarthManipulator * > ( ( * view ) - > getCameraManipulator ( ) ) ;
if ( manip = = 0L )
{
OE_WARN < < LC < < " Helper used before installing an EarthManipulator " < < std : : endl ;
}
}
// a root node to hold everything:
osg : : Group * root = new osg : : Group ( ) ;
root - > addChild ( node ) ;
// parses common cmdline arguments and apply to the first view:
// if ( !views.empty() )
// {
// parse( mapNode.get(), args, views.front(), root, userContainer );
//
// float lodscale;
// if (args.read("--lodscale", lodscale))
// {
// LODScaleGroup* g = new LODScaleGroup();
// g->setLODScaleFactor(osg::maximum(lodscale, 0.0001f));
// osgEarth::insertGroup(g, mapNode->getParent(0));
// OE_NOTICE << "LOD Scale set to: " << lodscale << std::endl;
// }
// }
// configures each view with some stock goodies
for ( osgViewer : : Viewer : : Views : : iterator view = views . begin ( ) ; view ! = views . end ( ) ; + + view )
{
configureView ( * view ) ;
}
# ifdef OSG_GL3_AVAILABLE
if ( viewer )
{
viewer - > setRealizeOperation ( new GL3RealizeOperation ( ) ) ;
}
# endif
return root ;
}
class ViewerWidget : public QWidget , public osgViewer : : CompositeViewer
{
public :
ViewerWidget ( QWidget * parent = 0 , Qt : : WindowFlags f = 0 , osgViewer : : ViewerBase : : ThreadingModel threadingModel = osgViewer : : CompositeViewer : : SingleThreaded ) : QWidget ( parent , f )
{
setThreadingModel ( threadingModel ) ;
// disable the default setting of viewer.done() by pressing Escape.
setKeyEventSetsDone ( 0 ) ;
std : : string earthPath = " D:/Project/DYT/Tool/TritonSample/TritonSample/triton.earth " ;
// osg::Node* node = osgDB::readNodeFile();
osg : : Node * node = LoadEarth ( earthPath , this ) ;
if ( ! node ) {
return ;
}
// Group to hold all our annotation elements.
// osg::Group* annoGroup = new osg::Group();
// osgEarth::MapNode::get(node)->addChild( annoGroup );
QWidget * widget1 = addViewWidget ( createGraphicsWindow ( 0 , 0 , 100 , 100 ) , node ) ;
// QWidget* widget2 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("glider.osgt") );
// QWidget* widget3 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("axes.osgt") );
// QWidget* widget4 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("fountain.osgt") );
// QWidget* popupWidget = addViewWidget( createGraphicsWindow(900,100,320,240,"Popup window",true), osgDB::readRefNodeFile("dumptruck.osgt") );
// popupWidget->show();
QGridLayout * grid = new QGridLayout ;
grid - > addWidget ( widget1 , 0 , 0 ) ;
// grid->addWidget( widget2, 0, 1 );
// grid->addWidget( widget3, 1, 0 );
// grid->addWidget( widget4, 1, 1 );
setLayout ( grid ) ;
2025-01-04 04:12:51 +00:00
2025-03-13 00:42:41 +00:00
connect ( & _timer , SIGNAL ( timeout ( ) ) , this , SLOT ( update ( ) ) ) ;
_timer . start ( 10 ) ;
}
QWidget * addViewWidget ( osgQt : : GraphicsWindowQt * gw , osg : : ref_ptr < osg : : Node > scene )
{
osgViewer : : View * view = new osgViewer : : View ;
addView ( view ) ;
view - > setCameraManipulator ( new osgEarth : : Util : : EarthManipulator ( ) ) ;
configureView ( view ) ;
osg : : Camera * camera = view - > getCamera ( ) ;
camera - > setGraphicsContext ( gw ) ;
const osg : : GraphicsContext : : Traits * traits = gw - > getTraits ( ) ;
camera - > setClearColor ( osg : : Vec4 ( 0.2 , 0.2 , 0.6 , 1.0 ) ) ;
camera - > setViewport ( new osg : : Viewport ( 0 , 0 , traits - > width , traits - > height ) ) ;
camera - > setProjectionMatrixAsPerspective ( 30.0f , static_cast < double > ( traits - > width ) / static_cast < double > ( traits - > height ) , 1.0f , 10000.0f ) ;
creatWidget ( view , scene - > asGroup ( ) ) ;
osgEarth : : MapNode * mapNode = osgEarth : : MapNode : : findMapNode ( scene ) ;
if ( ! mapNode )
return gw - > getGLWidget ( ) ;
auto skyDome_ = osgEarth : : Util : : SkyNode : : create ( mapNode ) ;
if ( ! mapNode ) {
LOG_WARN ( " eart map node is nullptr " ) ;
return gw - > getGLWidget ( ) ;
}
skyDome_ - > attach ( view ) ;
skyDome_ - > getSunLight ( ) - > setAmbient ( osg : : Vec4 ( 0.5 , 0.5 , 0.5 , 1.0 ) ) ;
scene - > asGroup ( ) - > addChild ( skyDome_ ) ;
skyDome_ - > setDateTime ( osgEarth : : DateTime ( 2024 , 12 , 24 , 3 ) ) ;
view - > setSceneData ( scene ) ;
view - > addEventHandler ( new osgViewer : : StatsHandler ) ;
// view->setCameraManipulator( new osgGA::MultiTouchTrackballManipulator );
gw - > setTouchEventsEnabled ( true ) ;
return gw - > getGLWidget ( ) ;
}
osgQt : : GraphicsWindowQt * createGraphicsWindow ( int x , int y , int w , int h , const std : : string & name = " " , bool windowDecoration = false )
{
osg : : DisplaySettings * ds = osg : : DisplaySettings : : instance ( ) . get ( ) ;
osg : : ref_ptr < osg : : GraphicsContext : : Traits > traits = new osg : : GraphicsContext : : Traits ;
traits - > windowName = name ;
traits - > windowDecoration = windowDecoration ;
traits - > x = x ;
traits - > y = y ;
traits - > width = w ;
traits - > height = h ;
traits - > doubleBuffer = true ;
traits - > alpha = ds - > getMinimumNumAlphaBits ( ) ;
traits - > stencil = ds - > getMinimumNumStencilBits ( ) ;
traits - > sampleBuffers = ds - > getMultiSamples ( ) ;
traits - > samples = ds - > getNumMultiSamples ( ) ;
return new osgQt : : GraphicsWindowQt ( traits . get ( ) ) ;
}
virtual void paintEvent ( QPaintEvent * /*event*/ )
{ frame ( ) ; }
protected :
QTimer _timer ;
} ;
int main ( int argc , char * argv [ ] ) {
SpdLogger logger ( " logs/log.txt " , 5 ) ;
//
// Application::setAttribute(Qt::AA_EnableHighDpiScaling);
//
// Application app(argc, argv);
// app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
// InstallCrashHandler();
//
// RecourceHelper::ChangeSkin("default");
//
// MainFrame mainWindow;
// mainWindow.showMaximized();
//
// int ret = app.exec();
// return ret;
osg : : ArgumentParser arguments ( & argc , argv ) ;
// Qt5 is currently crashing and reporting "Cannot make QOpenGLContext current in a different thread" when the viewer is run multi-threaded, this is regression from Qt4
osgViewer : : ViewerBase : : ThreadingModel threadingModel = osgViewer : : ViewerBase : : SingleThreaded ;
QApplication app ( argc , argv ) ;
OsgWidget * viewWidget = new OsgWidget ( nullptr , Qt : : Widget ) ;
// ViewerWidget* viewWidget = new ViewerWidget(nullptr, Qt::Widget, threadingModel);
viewWidget - > setGeometry ( 100 , 100 , 800 , 600 ) ;
viewWidget - > Initialize ( ) ;
viewWidget - > show ( ) ;
return app . exec ( ) ;
2025-01-04 04:12:51 +00:00
}