/
main.cpp
118 lines (93 loc) · 4.6 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <vsg/all.h>
#ifdef vsgXchange_FOUND
#include <vsgXchange/all.h>
#endif
#include <iostream>
int main(int argc, char** argv)
{
auto options = vsg::Options::create();
auto windowTraits = vsg::WindowTraits::create();
windowTraits->windowTitle = "MyFirstVsgApplication";
// set up defaults and read command line arguments to override them
vsg::CommandLine arguments(&argc, argv);
windowTraits->debugLayer = arguments.read({"--debug","-d"});
windowTraits->apiDumpLayer = arguments.read({"--api","-a"});
if (arguments.read({"--fullscreen", "--fs"})) windowTraits->fullscreen = true;
if (arguments.read({"--window", "-w"}, windowTraits->width, windowTraits->height)) { windowTraits->fullscreen = false; }
auto horizonMountainHeight = arguments.value(0.0, "--hmh");
arguments.read("--screen", windowTraits->screenNum);
arguments.read("--display", windowTraits->display);
if (arguments.errors()) return arguments.writeErrorMessages(std::cerr);
#ifdef vsgXchange_all
// add use of vsgXchange's support for reading and writing 3rd party file formats
options->add(vsgXchange::all::create());
#endif
auto scene = vsg::Group::create();
// read any vsg files from command line arguments
for (int i=1; i<argc; ++i)
{
vsg::Path filename = arguments[i];
auto loaded_scene = vsg::read_cast<vsg::Node>(filename, options);
if (loaded_scene)
{
scene->addChild(loaded_scene);
arguments.remove(i, 1);
--i;
}
}
if (scene->children.empty())
{
std::cout<<"No scene loaded, please specify valid 3d model(s) on command line."<<std::endl;
return 1;
}
// create the viewer and assign window(s) to it
auto viewer = vsg::Viewer::create();
vsg::ref_ptr<vsg::Window> window(vsg::Window::create(windowTraits));
if (!window)
{
std::cout<<"Could not create window."<<std::endl;
return 1;
}
viewer->addWindow(window);
// compute the bounds of the scene graph to help position the camera
vsg::ComputeBounds computeBounds;
scene->accept(computeBounds);
vsg::dvec3 centre = (computeBounds.bounds.min+computeBounds.bounds.max)*0.5;
double radius = vsg::length(computeBounds.bounds.max-computeBounds.bounds.min)*0.6;
double nearFarRatio = 0.0001;
// set up the camera
auto lookAt = vsg::LookAt::create(centre+vsg::dvec3(0.0, -radius*3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0));
vsg::ref_ptr<vsg::ProjectionMatrix> perspective;
if (vsg::ref_ptr<vsg::EllipsoidModel> ellipsoidModel(scene->getObject<vsg::EllipsoidModel>("EllipsoidModel")); ellipsoidModel)
{
// EllipsoidPerspective is useful for whole earth databases where per frame management of the camera's near & far values is optimized
// to the current view relative to an ellipsoid model of the earth so that when near to the earth the near and far planes are pulled in close to the eye
// and when far away from the earth's surface the far plane is pushed out to ensure that it encompasses the horizon line, accounting for mountains over the horizon.
perspective = vsg::EllipsoidPerspective::create(lookAt, ellipsoidModel, 30.0, static_cast<double>(window->extent2D().width) / static_cast<double>(window->extent2D().height), nearFarRatio, horizonMountainHeight);
}
else
{
perspective = vsg::Perspective::create(30.0, static_cast<double>(window->extent2D().width) / static_cast<double>(window->extent2D().height), nearFarRatio*radius, radius * 4.5);
}
auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D()));
// add close handler to respond to pressing the window's close window button and to pressing escape
viewer->addEventHandler(vsg::CloseHandler::create(viewer));
// add a trackball event handler to control the camera view using the mouse
viewer->addEventHandler(vsg::Trackball::create(camera));
// create a command graph to render the scene on the specified window
auto commandGraph = vsg::createCommandGraphForView(window, camera, scene);
viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph});
// compile all the Vulkan objects and transfer data required to render the scene
viewer->compile();
// rendering main loop
while (viewer->advanceToNextFrame())
{
// pass any events into EventHandlers assigned to the Viewer
viewer->handleEvents();
viewer->update();
viewer->recordAndSubmit();
viewer->present();
}
// clean up done automatically thanks to ref_ptr<>
return 0;
}