how to replace a viewport

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
rrl
Halfling
Posts: 78
Joined: Sun Jun 04, 2017 12:33 am

how to replace a viewport

Post by rrl »

I'm trying to understand how viewports work in 2.3 and have been reading over some very early posts about the change to compositors but I haven't been able to wrap my head around them.

I think what I'm trying to do should be quite simple. I have an item (axes.mesh) attached to a sceneNode which rotates at the center of the screen but I would like to place it in a corner of my window which I *think* requires the use of a viewport positioned in the corner with a fixed camera. So when my model rotates, the axes rotate, but no transition.

Can anyone break this down into laymans terms using 2.3?

In my code I have the following in a setupCompositor() function. Is it just a matter of setting up another workspace with a new name, seperate camera, seperate Ogre::Window, and it's own sceneManager?

Code: Select all

        return compositorManager->addWorkspace(sceneManager,
            renderWindow->getTexture(), camera, workspaceName, true);
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5436
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1343

Re: how to replace a viewport

Post by dark_sylinc »

Because the compositor now manages viewports, the answer is often the compositor replaces a viewport!

There are various ways, the most basic one:

Code: Select all

render_pass
{
    rq_first 0
    rq_last 240
}

render_pass
{
    viewport top left width height
    camera "MyCustomCamera"
    rq_first 240
    rq_last 241
}
In this example I assume:
  • The 1st pass is the regular pass. All your objects are somewhere between render queues 0 and 239
  • The 2nd pass is your axis object and are living in render queue 240
  • You will create a camera with name "MyCustomCamera"
  • viewport 'top left width height' must be actual floating point numbers
You can alter this example:
  • You can use visibility_mask keyword instead of render queue IDs to control visibility. However please take note that splitting by render queues is a performance optimization: we can skip all objects living in render queues we want to ignore. But with visibility masks we still have to process all objects to see which ones match and which ones don't
  • If you don't want to hardcode the camera name, you can place the 2nd compositor pass in it own workspace alone and send the camera in addWorkspace. Conceptually the idea is not too different from what StereoRendering sample does (StereoRendering renders the same scene twice, once to the left half, then to the right half, using two different cameras. However in StereoRendering we reuse the same workspace while you would need two different ones)
  • If you want to control the viewport size dynamically at runtime, use viewport modifier masks (see StereoRendering sample)
Cheers
Matias
rrl
Halfling
Posts: 78
Joined: Sun Jun 04, 2017 12:33 am

Re: how to replace a viewport

Post by rrl »

I'm trying to place the 2nd compositor pass in it's own workspace and send the same camera I'm using for the main rendering to the axes workspace as well. So I have two workspaces. I've changed setupCompositor() in my GraphicsSystem to the following.

Code: Select all

void GraphicsSystem::setupCompositor(void)
    {
        Ogre::CompositorManager2 *compositorManager =
            root->getCompositorManager2();

	// first workspace, has black background.
        const Ogre::String mainWorkspaceName("MyRenderingWorkspace");

        if (!compositorManager->hasWorkspaceDefinition(mainWorkspaceName)) {
            compositorManager->createBasicWorkspaceDef(mainWorkspaceName,
                backgroundColor, Ogre::IdString());
        }

        workspaces->push_back(compositorManager->addWorkspace(sceneManager,
            renderWindow->getTexture(), camera, mainWorkspaceName, true));

	// second workspace for axes, has blue background
        const Ogre::String axesWorkspaceName("Axes Workspace");

        if (!compositorManager->hasWorkspaceDefinition(axesWorkspaceName)) {
            compositorManager->createBasicWorkspaceDef(axesWorkspaceName,
                axesBackgroundColor, Ogre::IdString());
        }

        workspaces->push_back(compositorManager->addWorkspace(sceneManager,
            renderWindow->getTexture(), camera, axesWorkspaceName, true));

        return;
    }
I've not used scripts before, but here was my first go. I made this script by looking over StereoRendering.compositor.

Code: Select all

compositor_node MyRenderingNode
{
    render_pass
    {
        rq_first 0
        rq_last 240
    }

    render_pass
    {
        viewport 0.0 0.0 40.0 40.0

        rq_first 240
        rq_last 241
    }
}

workspace MyRenderingWorkspace
{
    connect MyRenderingNode 0
}
What I don't get is that my entire screen is blue, so it would appear the size I have in viewport is not correct. I was expecting to see a small blue background in the top left corner of my screen. And I don't get how the 2nd workspace would be referenced in that compositor script. I'm sure I probably don't have the workspace part of this script correct.

Ideas?

Also, any links to references on how to do scripting like this?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5436
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1343

Re: how to replace a viewport

Post by dark_sylinc »

Hi!

The size is in range [0; 1] as described in the manual.
rrl
Halfling
Posts: 78
Joined: Sun Jun 04, 2017 12:33 am

Re: how to replace a viewport

Post by rrl »

Made some changes but this still isn't working out.

I am trying to places axes.mesh in the lower corner of my main render window (which I think is an RT for rendering target, not sure what RTT means). With the following configuration, my axes window is not showing up.

So I have two cameras setup and two workspaces in setupCompositor(). Each workspace has it's own camera and SceneManager.

Code: Select all

    void GraphicsSystem::createCameras(void)
    {
        camera = sceneManager->createCamera("MainCamera");
        camera->setPosition(Ogre::Vector3(0, 5, 15));
        camera->lookAt(Ogre::Vector3(0, 0, 0));
        camera->setNearClipDistance(0.2f);
        camera->setFarClipDistance(1000.0f);
        camera->setAutoAspectRatio(true);

        axesCamera = axesSceneManager->createCamera("AxesCamera");
        axesCamera->setPosition(Ogre::Vector3(0, 5, 15));
        axesCamera->lookAt(Ogre::Vector3(0, 0, 0));
        axesCamera->setNearClipDistance(0.2f);
        axesCamera->setFarClipDistance(1000.0f);
        axesCamera->setAutoAspectRatio(true);
    }

    void GraphicsSystem::setupCompositor(void)
    {
        Ogre::CompositorManager2 *compositorManager =
            root->getCompositorManager2();

        const Ogre::String mainWorkspaceName("MainWorkspace");

        if (!compositorManager->hasWorkspaceDefinition(mainWorkspaceName)) {
            compositorManager->createBasicWorkspaceDef(mainWorkspaceName,
                mainBackgroundColor, Ogre::IdString());
        }
        
        workspaces->push_back(compositorManager->addWorkspace(sceneManager,
            renderWindow->getTexture(), camera, mainWorkspaceName, true));

        const Ogre::String axesWorkspaceName("AxesWorkspace");

        if (!compositorManager->hasWorkspaceDefinition(axesWorkspaceName)) {
            compositorManager->createBasicWorkspaceDef(axesWorkspaceName,
                axesBackgroundColor, Ogre::IdString());
        }

        workspaces->push_back(compositorManager->addWorkspace(axesSceneManager,
            renderWindow->getTexture(), axesCamera, axesWorkspaceName, true));
    }
Then I have the following two scripts. My axes.compositor script.

Code: Select all

compositor_node AxesRenderingNode
{
    in 0 rt_axesWindow

    target rt_axesWindow
    {
        pass render_scene
        {
            viewport 0.0 0.0 0.3 0.3
            rq_first 240
            rq_last 241
        }
    }

    out 0 rt_axesWindow
}

workspace AxesRenderingWorkspace
{
    connect_output AxesRenderingNode 0
}
And my main.compositor script.

Code: Select all

compositor_node MainRenderingNode
{
    in 0 rt_renderWindow

    target rt_renderWindow
    {
        pass clear { }

        pass render_scene
        {
            rq_first 0
            rq_last 240
        }
    }

    out 0 rt_renderWindow
}

workspace MainWorkspace
{
    connect_output MainRenderingNode 0
}
The problem is that I don't see the axes window show up anywhere's. The main rendering window works just fine as expected.

Thoughts?