[2.2] Scene Creation Order vs Compositor Workspace
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
[2.2] Scene Creation Order vs Compositor Workspace
During a recent code refactor, I stumbled across an order dependency which seems strange and does not make sense to me.
Scenario 1
1. Create Ogre::Item based on a mesh and attach to a new node.
2. Create Ogre::Camera based on camera level data definition, attach to new node.
3. Create compositor workspace using this scene manager, camera created in (2) and the render context's window w/green bgcolor.
Scenario 2
1. Create Ogre::Camera based on camera level data definition, attach to new node.
2. Create compositor workspace using this scene manager, camera created in (1) and the render context's window w/green bgcolor.
3. Create Ogre::Item based on a mesh and attach to a new node.
Under Scenario 1, the cube mesh is never visible but background is green.
Under Scenario 2, the cube mesh is visible and background is green.
It does not make sense to me why a workspace must be created prior to the creation of the Ogre::Item. Is there something amuck here or is there a hidden dependency that which just isn't clear or obvious here? I do initialize OGRE with an initial dummy window that is hidden to handle resource loading and things since its up to the application to provide a window handle (e.g. editor viewports for example) as to where OGRE will render when a level is actually loaded and prepped to be rendered.
Scenario 1
1. Create Ogre::Item based on a mesh and attach to a new node.
2. Create Ogre::Camera based on camera level data definition, attach to new node.
3. Create compositor workspace using this scene manager, camera created in (2) and the render context's window w/green bgcolor.
Scenario 2
1. Create Ogre::Camera based on camera level data definition, attach to new node.
2. Create compositor workspace using this scene manager, camera created in (1) and the render context's window w/green bgcolor.
3. Create Ogre::Item based on a mesh and attach to a new node.
Under Scenario 1, the cube mesh is never visible but background is green.
Under Scenario 2, the cube mesh is visible and background is green.
It does not make sense to me why a workspace must be created prior to the creation of the Ogre::Item. Is there something amuck here or is there a hidden dependency that which just isn't clear or obvious here? I do initialize OGRE with an initial dummy window that is hidden to handle resource loading and things since its up to the application to provide a window handle (e.g. editor viewports for example) as to where OGRE will render when a level is actually loaded and prepped to be rendered.
Last edited by crancran on Tue May 01, 2018 5:16 pm, edited 2 times in total.
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [2.2] Scene Creation Order vs Compositor Workspace
Hi!
I am not aware of any such order dependence.
I can create workspaces after a whole scene is populated with items with no problem. There must be some other issue going on.
I am not aware of any such order dependence.
I can create workspaces after a whole scene is populated with items with no problem. There must be some other issue going on.
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
The entire bootstrap for OGRE is as follows
1. Create Ogre::Root
2. Initialize Ogre::Root using false
3. Other engine systems do their pre-boostrap init (so they can supply resource locations to OGRE)
4. Create hidden render window (dummy window used so resources can be loaded).
5. Initialize HLMS
6. Initialize all Resources
7. Other engine systems do post-init here
When the editor goes to open the game data, it does the following
1. Create SceneManager
2. Create scene objects, items, cameras, etc.
3. Opens the editor camera-perspective viewport
5. Asks OGRE to create a render window based on viewport's winId()
4. Creates an editor camera
5. Creates a compositor workspace using the SceneManager, editor camera from (4), and the window from (5).
Looking at CompositorWorkspace's constructor, I see a comment
Code: Select all
//We need this so OpenGL can switch contexts (if needed) before creating the textures
if( finalTarget )
mRenderSys->_setCurrentDeviceFromTexture( finalTarget );
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
Sadly this is precisely the issue, which is really quite unfortunate from an API perspective IMO.crancran wrote: ↑Tue May 01, 2018 5:25 pm Looking at CompositorWorkspace's constructor, I see a commentI'm curious if there is an OpenGL context issue here which is why the workspace must be constructed prior?Code: Select all
//We need this so OpenGL can switch contexts (if needed) before creating the textures if( finalTarget ) mRenderSys->_setCurrentDeviceFromTexture( finalTarget );
If I construct the viewport up-front and create the window and call the above method on the render system with the window's Texture() pointer, I can then create the scene objects without the workspace and they'll be visible after the workspace is constructed.
There has to be a better way to do this imo as I would prefer not to create the RenderViewportPerspective unless the scene was successfully loaded.
Also what about the use case where you want to render the scene from the vantage point of two cameras their own window. In this case, you'd ideally prefer to load the scene into the SceneManager first and let each window dictate their camera's perspective and construct a workspace after the fact.
Last edited by crancran on Tue May 01, 2018 6:36 pm, edited 2 times in total.
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [2.2] Scene Creation Order vs Compositor Workspace
I missed the 2.2 tag to this post. I am not yet running 2.2 so my experience is not applicable to your situation. Sorry!
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [2.2] Scene Creation Order vs Compositor Workspace
2.1 + GL3Plus.
In general Ogre needs a rendering API context before it can load textures and mesh data. We create a hidden render window initially during load time, before any proper render window has been created.
Otherwise, the workspace creation should be decoupled from Item creation.
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact:
Re: [2.2] Scene Creation Order vs Compositor Workspace
Mmmm... I don't think I ever done scenario 1, but it should work. Perhaps the GL context isn't set, as zxz has remarked.
However I think I spotted the problem:
See Ogre 2.1 FAQ regarding multiple windows.
Basically the problem is not the order at which you are creating the workspace (that can be done afterwards). The problem is that you're creating the render window too late.
However I think I spotted the problem:
At least one render window must to exist prior to everything. A dummy hidden window is the common approach (create a 1x1 window, then hide it forever. Then the next windows are created by sharing the context with the dummy 1x1 one).crancran wrote: ↑Tue May 01, 2018 5:25 pm 1. Create SceneManager
2. Create scene objects, items, cameras, etc.
3. Opens the editor camera-perspective viewport
5. Asks OGRE to create a render window based on viewport's winId() ---> PROBLEM
4. Creates an editor camera
5. Creates a compositor workspace using the SceneManager, editor camera from (4), and the window from (5).
See Ogre 2.1 FAQ regarding multiple windows.
Basically the problem is not the order at which you are creating the workspace (that can be done afterwards). The problem is that you're creating the render window too late.
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
Well that's exactly what I am doing here in my Editor written with Qt. As I said previously, during OGRE's initial bootstrap, we create the dummy hidden window as well, load the scene into a SceneManager. If all that succeeds, during the editor's level open callback handler, the editor creates the RenderPerspectiveViewport window, we create an OGRE render window using the RenderPerspectiveViewport's winId() handle and then ask OGRE to build a workspace using the SceneManager, the winId() handle, and a newly created Camera.zxz wrote: ↑Tue May 01, 2018 7:13 pm2.1 + GL3Plus.
In general Ogre needs a rendering API context before it can load textures and mesh data. We create a hidden render window initially during load time, before any proper render window has been created.
Otherwise, the workspace creation should be decoupled from Item creation.
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
Yep and that is exactly what I am doing but unfortunately under Qt5 it does not seem to behave as expected.dark_sylinc wrote: ↑Tue May 01, 2018 7:32 pm At least one render window must to exist prior to everything. A dummy hidden window is the common approach (create a 1x1 window, then hide it forever. Then the next windows are created by sharing the context with the dummy 1x1 one).
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [2.2] Scene Creation Order vs Compositor Workspace
Which OS and rendersystem are you using?
We are running GL3Plus on Linux, and we are also using Qt5. We had to made a couple of adjustments in the GLX window setup for the drawable and contexts to be reused properly in our setup.
We are running GL3Plus on Linux, and we are also using Qt5. We had to made a couple of adjustments in the GLX window setup for the drawable and contexts to be reused properly in our setup.
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact:
Re: [2.2] Scene Creation Order vs Compositor Workspace
Could you post that code?crancran wrote: ↑Tue May 01, 2018 7:46 pmYep and that is exactly what I am doing but unfortunately under Qt5 it does not seem to behave as expected.dark_sylinc wrote: ↑Tue May 01, 2018 7:32 pm At least one render window must to exist prior to everything. A dummy hidden window is the common approach (create a 1x1 window, then hide it forever. Then the next windows are created by sharing the context with the dummy 1x1 one).
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
Here is a very simple example
AFAICT, the only way to get this to work is to reorder the constructor method calls to be
What adjustments did you have to make?
And btw the code I posted is against 2.1 as I am seeing the same problem under both versions. It should be simple enough to alter the MainWindow code where applicable to be compliant with 2.2's API changes.
Code: Select all
#include <QResizeEvent>
#include "OgreUtil.hpp"
#include <OgreRoot.h>
#include <OgreRenderWindow.h>
#include <OgreCamera.h>
#include <OgreItem.h>
#include <Compositor/OgreCompositorManager2.h>
#include <Compositor/OgreCompositorWorkspace.h>
MainWindow::MainWindow() :
QMainWindow( Q_NULLPTR ),
root_( nullptr ),
sm_( nullptr ),
camera_( nullptr ),
dummyWindow_( nullptr ),
realWindow_( nullptr ),
workspace_( nullptr )
{
// create OGRE
root_ = OGRE_NEW Ogre::Root();
if ( !root_->showConfigDialog() )
return;
// initialize OGRE without a primary window
root_->initialise( false );
CreateDummyWindow();
InitializeResources();
CreateSceneManager();
CreateScene();
CreateRealWindow();
CreateCamera();
CreateWorkspace();
timer_ = new QTimer( this );
timer_->setSingleShot( true );
timer_->start( 5 );
connect( timer_, &QTimer::timeout, this, &MainWindow::Draw );
}
MainWindow::~MainWindow()
{
if ( root_ )
{
OGRE_DELETE root_;
root_ = nullptr;
}
}
void MainWindow::Draw()
{
root_->renderOneFrame();
timer_->start( 5 );
}
void MainWindow::CreateDummyWindow()
{
// build dummy window
Ogre::NameValuePairList params;
params[ "hidden" ] = "true";
dummyWindow_ = root_->createRenderWindow( "DummyWindow", 1, 1, false, ¶ms );
}
void MainWindow::CreateRealWindow()
{
// create real window now
Ogre::NameValuePairList params;
params[ "externalWindowHandle" ] = Ogre::StringConverter::toString( (uint32_t) winId() );
realWindow_ = root_->createRenderWindow( "RealWindow", size().width(), size().height(), false, ¶ms );
}
void MainWindow::CreateCamera()
{
camera_ = sm_->createCamera( "Default" );
camera_->detachFromParent();
Ogre::SceneNode *cameraNode = sm_->getRootSceneNode()->createChildSceneNode();
cameraNode->setPosition( 0.f, 0.f, 50.f );
cameraNode->attachObject( camera_ );
camera_->setFarClipDistance( 1024.f );
camera_->setNearClipDistance( 0.25f );
camera_->setAutoAspectRatio( true );
camera_->lookAt( Ogre::Vector3::ZERO );
}
void MainWindow::CreateScene()
{
Ogre::Item *item = sm_->createItem( "cube_new.mesh" );
item->setDatablockOrMaterialName( "Blue" );
Ogre::SceneNode *itemNode = sm_->getRootSceneNode()->createChildSceneNode();
itemNode->setPosition( 0.f, 0.f, -50.f );
itemNode->setScale( .1f, .1f, .1f );
itemNode->attachObject( item );
}
void MainWindow::InitializeResources()
{
// initialize HLMS
OgreUtil::InitializeHlmsMaterialSystem( Ogre::HLMS_PBS, "./Cache/Shaders/Pbs/", true );
OgreUtil::InitializeHlmsMaterialSystem( Ogre::HLMS_UNLIT, "./Cache/Shaders/Unlit/", true );
// initialize resources
Ogre::ResourceGroupManager *rgm = Ogre::ResourceGroupManager::getSingletonPtr();
rgm->addResourceLocation( "Data/Materials", "FileSystem", "General" );
rgm->addResourceLocation( "Data/Meshes", "FileSystem", "General" );
rgm->initialiseAllResourceGroups( false );
}
void MainWindow::CreateWorkspace()
{
// build workspace
Ogre::CompositorManager2 *compositorManager = root_->getCompositorManager2();
if ( !compositorManager->hasWorkspaceDefinition( "Default" ) )
compositorManager->createBasicWorkspaceDef( "Default", Ogre::ColourValue::Black );
workspace_ = compositorManager->addWorkspace( sm_, realWindow_, camera_, "Default", true );
}
void MainWindow::CreateSceneManager()
{
sm_ = root_->createSceneManager( Ogre::ST_GENERIC, 2, Ogre::INSTANCING_CULLING_THREADED );
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
if ( realWindow_ )
realWindow_->resize( event->size().width(), event->size().height() );
QWidget::resizeEvent( event );
}
Code: Select all
namespace OgreUtil
{
void InitializeHlmsMaterialSystem(Ogre::HlmsTypes type, Ogre::String debugPath, bool outputProperties)
{
auto& root = Ogre::Root::getSingleton();
auto& archiveManager = Ogre::ArchiveManager::getSingleton();
Ogre::ConfigFile hlmsConfig;
hlmsConfig.load( "hlms.cfg" );
Ogre::String section = "Hlms";
Ogre::String rootHlmsFolder;
if ( Ogre::HLMS_USER0 == type )
rootHlmsFolder = hlmsConfig.getSetting( "DoNotUseAsResourceCustom", section, "" );
else
rootHlmsFolder = hlmsConfig.getSetting( "DoNotUseAsResource", section, "" );
Ogre::String mainFolderPath;
Ogre::StringVector libraryFolderPaths;
Ogre::StringVector::const_iterator libraryFolderPathIt;
switch ( type )
{
case Ogre::HLMS_PBS:
Ogre::HlmsPbs::getDefaultPaths( mainFolderPath, libraryFolderPaths );
break;
case Ogre::HLMS_UNLIT:
Ogre::HlmsUnlit::getDefaultPaths( mainFolderPath, libraryFolderPaths );
break;
default:
throw std::runtime_error( "Unknown HLMS type specified for initialization" );
}
Ogre::ArchiveVec archiveFolders;
Ogre::StringVector::const_iterator itor = libraryFolderPaths.begin();
Ogre::StringVector::const_iterator end = libraryFolderPaths.end();
while ( itor != end )
{
Ogre::String path = rootHlmsFolder + *itor;
archiveFolders.push_back( archiveManager.load( path, "FileSystem", true ) );
++itor;
}
Ogre::Archive* archive = archiveManager.load( rootHlmsFolder + mainFolderPath, "FileSystem", true );
Ogre::Hlms* hlms = nullptr;
switch ( type )
{
case Ogre::HLMS_PBS:
hlms = OGRE_NEW Ogre::HlmsPbs( archive, &archiveFolders );
break;
case Ogre::HLMS_UNLIT:
hlms = OGRE_NEW Ogre::HlmsUnlit( archive, &archiveFolders );
break;
}
hlms->setDebugOutputPath( true, outputProperties, debugPath );
root.getHlmsManager()->registerHlms( hlms );
}
}
Code: Select all
CreateDummyWindow();
InitializeResources();
CreateSceneManager();
CreateRealWindow();
CreateCamera();
CreateWorkspace();
CreateScene();
Fedora 26
What adjustments did you have to make?
And btw the code I posted is against 2.1 as I am seeing the same problem under both versions. It should be simple enough to alter the MainWindow code where applicable to be compliant with 2.2's API changes.
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [2.2] Scene Creation Order vs Compositor Workspace
Well, first off let me give this disclaimer. Our setup is probably not the best way, but it works for us. It is most likely possible to get things working without making changes to Ogre.
I ended up letting Ogre create the renderwindow, and instead I provide a "parentWindowHandle" parameter. I think we initially used "externalWindowHandle" but ran into some sort of issues I cannot remember anymore (multisampling problems or something else). We also set "currentGLContext" to "true" in order to tell Ogre to reuse the current context (created earlier with the hidden render window).
Then, we use this patch, so that "currentGLContext" won't prevent window creation by setting the glxDrawable variable.
Code: Select all
diff --git a/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp b/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp
index 802938f..162fa53 100644
--- a/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp
+++ b/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp
@@ -150,7 +150,6 @@ namespace Ogre
}
glxContext = glXGetCurrentContext();
- glxDrawable = glXGetCurrentDrawable();
}
// Note: Some platforms support AA inside ordinary windows
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact:
Re: [2.2] Scene Creation Order vs Compositor Workspace
I'm not familiar with multiple windows in Linux + Mesa (last time I tried I hit Mesa bugs)
But it seems that passing currentGLContext is required, else apparently GLXWindow will request GLXContext to create a new context.
But it seems that passing currentGLContext is required, else apparently GLXWindow will request GLXContext to create a new context.
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact:
Re: [2.2] Scene Creation Order vs Compositor Workspace
Sounds like it should be split into currentGLContext & currentGLXDrawable ?zxz wrote: ↑Tue May 01, 2018 10:46 pm Then, we use this patch, so that "currentGLContext" won't prevent window creation by setting the glxDrawable variable.Code: Select all
diff --git a/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp b/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp index 802938f..162fa53 100644 --- a/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp +++ b/RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp @@ -150,7 +150,6 @@ namespace Ogre } glxContext = glXGetCurrentContext(); - glxDrawable = glXGetCurrentDrawable(); } // Note: Some platforms support AA inside ordinary windows
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
Aye it seems that is required and I had forgotten or overlooked that. Doing that as shown below with thedark_sylinc wrote: ↑Tue May 01, 2018 11:09 pm I'm not familiar with multiple windows in Linux + Mesa (last time I tried I hit Mesa bugs)
But it seems that passing currentGLContext is required, else apparently GLXWindow will request GLXContext to create a new context.
Code: Select all
void MainWindow::CreateRealWindow()
{
// create real window now
Ogre::NameValuePairList params;
params[ "externalWindowHandle" ] = Ogre::StringConverter::toString( (uint32_t) winId() );
params[ "currentGLContext" ] = "true";
realWindow_ = root_->createRenderWindow( "RealWindow", size().width(), size().height(), false, ¶ms );
}
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [2.2] Scene Creation Order vs Compositor Workspace
I think we were having issues with getting multisampling working (no AA at all) with some of the parameter combinations. It's working with our current setup, but I remember it was quite touchy to get all aspects of the window creation working perfectly.
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
Once I got past this, it seem having (1) dummyWindow and (2) sceneWindow rendering the same scene results in the scene windows rendering nada but clearing the buffer with their clear color. If I close one of these scene windows, the other begins to render again. This sounds so familar as I seem to recall this being a problem in the past and I cannot for the life of me recall how I got past this.
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [2.2] Scene Creation Order vs Compositor Workspace
-
- Greenskin
- Posts: 138
- Joined: Wed May 05, 2010 3:36 pm
- x 6
Re: [2.2] Scene Creation Order vs Compositor Workspace
It seems for Mesa, the workaround here is to make sure that you do not having multiple compositor workspaces enabled. Instead, if you guarantee that only one workspace is enabled, you can fire multiple calls to renderOneFrame and properly render to multiple surfaces without an issue. Something akin to the following works just fine. Its not ideal, but it works .crancran wrote: ↑Wed May 02, 2018 12:07 amOnce I got past this, it seem having (1) dummyWindow and (2) sceneWindow rendering the same scene results in the scene windows rendering nada but clearing the buffer with their clear color. If I close one of these scene windows, the other begins to render again. This sounds so familar as I seem to recall this being a problem in the past and I cannot for the life of me recall how I got past this.
Code: Select all
void RenderSystem::Render(float dt)
{
for ( CompositorWorkspace *workspace : workspaces_ )
{
workspace->setEnabled( true );
root_->renderOneFrame( dt );
workspace->setEnabled( false );
}
}
- Kaylx
- Greenskin
- Posts: 123
- Joined: Sun May 22, 2011 10:45 pm
- Location: Scotland
- x 7
Re: [2.2] Scene Creation Order vs Compositor Workspace
I've had the exact same issue on Windows with Intel/nVidia using Ogre 2.1 and Qt 5.9.2.
Multiple workspaces with a dummy window and shared opengl context setup just don't work.
@crancran - It feels completely wrong but your enable/disable workspace code does the trick for me too.
It must be possible without such 'fixes'.
Multiple workspaces with a dummy window and shared opengl context setup just don't work.
@crancran - It feels completely wrong but your enable/disable workspace code does the trick for me too.
It must be possible without such 'fixes'.