Skip to content

Conversation

@dov
Copy link

@dov dov commented Nov 26, 2024

  • This allows creating views that are redrawn on window resize

Pull Request Template

Description

Some View's may need updating when the window is resized. E.g. if doing a pixel exact 2D overlay, we may want to resize the elements to be of a certain size in pixels. I could not find any callback that I could catch in my custom view that notifies of such resizing. This was the reason that I introduced the resize() abstract callback.

Another issue with pixel exact overlays, is that we may want to have the projection matrix fixed. Currently, the projection matrix is updated in WindowResizeHandler::apply(vsg::View&). An overloaded resize() method allows resetting the projectionMatrix to an expected transparent state.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • Test A

I created a test program available here: https://gist.github.com/dov/b4ca06a0b13558b75da05948eb955777

Test Configuration:

Tested on Linux .

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

- This allows creating views that are redrawn on window resize
@robertosfield
Copy link
Collaborator

I have review this PR a couple of times and each time I've come away confused as to why it's needed, I've just done another review and still feel the same. I am closing this PR as I believe the correct way to implement custom resize behavior is to subclass from the WindowResizeHandler and then assign the custom one to the RenderGraph.

@dov
Copy link
Author

dov commented Feb 16, 2025

Just subclassing the WindowResizeHandle does not solve the problem of how the overrided WindowResizeHandle will notify its child views that they were resized. Currently I worked around this by creating a "repository" of resizeble views, and then notifying all of them. My idea of this pull request was to resizable views default, and get around the need for this hack.

I do have the feeling though that I'm missing something, and there must be an easier way to do it.

Your suggestions are most appreciated.

// This is like view, but it has an additional virtual method resize() which is
// called the containing window is resized
class ResizableView : public vsg::Inherit<vsg::View, ResizableView>
{
  public:
     explicit ResizableView(vsg::ViewFeatures in_features = vsg::RECORD_ALL)
       : vsg::Inherit<vsg::View, ResizableView>(in_features) {}
     explicit ResizableView(vsg::ref_ptr<vsg::Camera> in_camera, vsg::ref_ptr<vsg::Node> in_scenegraph = {}, vsg::ViewFeatures in_features = vsg::RECORD_ALL)
      : vsg::Inherit<vsg::View, ResizableView>(in_camera, in_scenegraph, in_features) {}
    virtual void resize() {};
};

:

class MyWindowResizeHandler : public vsg::Inherit<vsg::WindowResizeHandler, MyWindowResizeHandler>
{
public:
    MyWindowResizeHandler()
        : vsg::Inherit<vsg::WindowResizeHandler, MyWindowResizeHandler>() {}

    void apply(vsg::View& view) override {
        vsg::Inherit<vsg::WindowResizeHandler, MyWindowResizeHandler>::apply(view);

        if (resizableViews.count(&view) > 0)
            ((ResizableView*)&view)->resize();
    };

    // A "registry" for resizable views
    std::set<vsg::View*> resizableViews;
};
:
class LogoView : public vsg::Inherit<ResizableView, LogoView>
{
}
:
vsg::ref_ptr<MyWindowResizeHandler> resizeHandler = MyWindowResizeHandler::create();
resizeHandler->resizableViews.insert(logoView.get());

// Overridethe renderGraph resize handler
renderGraph->windowResizeHandler = resizeHandler;

@robertosfield
Copy link
Collaborator

You can simply do a dynamic_cast<ResizableView*> in the MyWindowResizeHandler::apply(View& view) or override the accept() method of the ResizeableView::accept(Visitor* visitor) method and do a cast to WindowResizeHandler/MyWindowResizeHandler and do any special work you want there.

@robertosfield
Copy link
Collaborator

The vsgvisitorcustomtype example might of interest:

https://github.com/vsg-dev/vsgExamples/tree/master/examples/core/vsgvisitorcustomtype

@dov
Copy link
Author

dov commented Feb 16, 2025

@robertosfield Thanks! dynamic_cast indeed cleans it up, an removes my ugly set of resizable views! I really have to get used to thinking in terms of RTTI!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants