Skip to content

Instantly share code, notes, and snippets.

@dov
Created November 26, 2024 12:55
Show Gist options
  • Save dov/b4ca06a0b13558b75da05948eb955777 to your computer and use it in GitHub Desktop.
Save dov/b4ca06a0b13558b75da05948eb955777 to your computer and use it in GitHub Desktop.
An example of how to use the proposed vsg::View::resize() update function to redraw the view elements
//======================================================================
// hello-box.cpp - Show a box with vsg viewer
//
// Extended to add keyboard interaction
//
// Dov Grobgeld <[email protected]>
// Sat Mar 16 23:25:06 2024
//----------------------------------------------------------------------
#include <vsg/all.h>
#include <iostream>
#include <vsg/app/ProjectionMatrix.h>
#include <stdio.h>
// A view example that draws a 40 pixel border around the window
class BorderView : public vsg::Inherit<vsg::View, BorderView>
{
public:
BorderView(vsg::ref_ptr<vsg::Camera> modelCamera)
:
_projMatrix(vsg::Orthographic::create(
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 10000.0f))
{
// Fixed 0->1 view matrix
auto viewMatrix = vsg::LookAt::create(
vsg::dvec3(0.0, 0.0, 1.0),
vsg::dvec3(0.0, 0.0, 0.0),
vsg::dvec3(0.0, 1.0, 0.0));
camera = vsg::Camera::create(
_projMatrix,
viewMatrix,
modelCamera->viewportState);
// Create four quads to draw the border
auto builder = vsg::Builder::create();
vsg::GeometryInfo geomInfo;
geomInfo.color = vsg::vec4 {1.0f, 1.0f, 1.0f, 0.5f};
geomInfo.transform = vsg::translate(vsg::dvec3(0.5,0.5,0.0)); // map to 0->1
vsg::StateInfo stateInfo;
stateInfo.blending = true;
stateInfo.lighting = false;
// Create the quads with geom transformation not initialized
for (int i = 0; i < 4; i++)
{
auto transform = vsg::MatrixTransform::create();
this->addChild(transform);
transform->addChild(builder->createBox(geomInfo, stateInfo));
}
resize();
}
void resize() override
{
camera->projectionMatrix = vsg::Orthographic::create(
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 10000.0f);
auto extent = camera->viewportState->getViewport();
int w = extent.width;
int h = extent.height;
// Create the four border transformations
for (int i=0; i<4; i++)
{
auto transform = children[i].cast<vsg::MatrixTransform>();
// horizontal quads
vsg::dvec2 pos, size;
if (i<2)
{
pos = vsg::dvec2(borderSizeInPix/w, i*(1.0-borderSizeInPix/h));
size = vsg::dvec2(1.0-2.0*borderSizeInPix/w, borderSizeInPix/h);
}
// vertical quads
else
{
pos = vsg::dvec2((i-2)*(1.0-borderSizeInPix/w), borderSizeInPix/h);
size = vsg::dvec2(borderSizeInPix/w, 1.0-2.0*borderSizeInPix/h);
}
transform->matrix = vsg::translate(vsg::dvec3(pos, 0.0)) * vsg::scale(vsg::dvec3(size, 1.0));
}
}
vsg::ref_ptr<vsg::ProjectionMatrix> _projMatrix;
double borderSizeInPix = 40.0;
};
int main(int argc, char **argv)
{
auto windowTraits = vsg::WindowTraits::create();
windowTraits->windowTitle = "vsgbuilder";
auto builder = vsg::Builder::create();
auto scene = vsg::Group::create();
vsg::GeometryInfo geomInfo;
vsg::StateInfo stateInfo;
// Change box color to red
geomInfo.color = vsg::vec4 {1.0f, 0.0f, 0.0f, 1.0f};
auto node = builder->createBox(geomInfo, stateInfo);
scene->addChild(node);
// 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;
// centre = vsg::dvec3(0,0,0);
// create the viewer and assign window(s) to it
auto viewer = vsg::Viewer::create();
auto window = vsg::Window::create(windowTraits);
if (!window)
{
std::cout << "Could not create window." << std::endl;
return 1;
}
viewer->addWindow(window);
// set up the camera
double radius = 1.0;
vsg::ref_ptr<vsg::LookAt> lookAt = vsg::LookAt::create(centre + vsg::dvec3(-radius * 3.5, -radius*2, -radius), centre, vsg::dvec3(0.0, 0.0, 1.0));
double nearFarRatio = 0.001;
auto perspective = vsg::Perspective::create(30.0, static_cast<double>(window->extent2D().width) / static_cast<double>(window->extent2D().height), nearFarRatio * radius, radius * 10.0);
// auto perspective = vsg::Orthographic();
auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D()));
viewer->addEventHandler(vsg::CloseHandler::create(viewer));
auto trackball = vsg::Trackball::create(camera);
viewer->addEventHandler(trackball);
auto view = vsg::View::create(camera);
view->addChild(vsg::createHeadlight());
view->addChild(scene);
auto commandGraph = vsg::CommandGraph::create(window);
auto renderGraph = vsg::RenderGraph::create(window);
renderGraph->addChild(view);
renderGraph->addChild(BorderView::create(camera));
commandGraph->addChild(renderGraph);
viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph});
viewer->compile();
auto startTime = vsg::clock::now();
double numFramesCompleted = 0.0;
// rendering main loop
while (viewer->advanceToNextFrame())
{
// pass any events into EventHandlers assigned to the Viewer
viewer->handleEvents();
viewer->update();
viewer->recordAndSubmit();
viewer->present();
numFramesCompleted += 1.0;
}
auto duration = std::chrono::duration<double, std::chrono::seconds::period>(vsg::clock::now() - startTime).count();
if (numFramesCompleted > 0.0)
{
std::cout << "Average frame rate = " << (numFramesCompleted / duration) << std::endl;
}
return 0;
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment