PagedGeometry & creating my own render window

Tamarac

28-07-2008 00:15:40

I'm trying to get the code from Example1 of the PagedGeometry running in my own application, which creates it's own window (rather than letting Ogre create a window for me with root->initialise(true, "").

Here's (roughly) what I do :

// Register window class
WNDCLASSEX l_Class;
l_Class.cbSize = sizeof( l_Class );
l_Class.style = 0;
l_Class.lpszClassName = szWindowClass;
l_Class.lpfnWndProc = WndProc;
l_Class.hbrBackground = NULL;
l_Class.hCursor = NULL;
l_Class.hIcon = NULL;
l_Class.hIconSm = NULL;
l_Class.lpszMenuName = NULL;
l_Class.cbClsExtra = 0;
l_Class.cbWndExtra = 0;
l_Class.hInstance = h_Inst;

if( !RegisterClassEx( &l_Class ) )
return;

m_window = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, h_Inst, NULL);

if (!m_window) {
return;
}

mRoot = new Ogre::Root();
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./media", "FileSystem");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./media/trees", "FileSystem");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./media/terrains", "FileSystem");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./media/grass", "FileSystem");

mRoot->loadPlugin("Plugin_CgProgramManager");
mRoot->loadPlugin("Plugin_OctreeSceneManager");
mRoot->loadPlugin("RenderSystem_Direct3D9");
mRoot->loadPlugin("RenderSystem_GL");

bool result = mRoot->showConfigDialog();
mRoot->initialise(false,"Some Window Title");
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

Ogre::NameValuePairList misc;
misc["externalWindowHandle"] = Ogre::StringConverter::toString((size_t)m_window);
mRenderWindow = mRoot->createRenderWindow( "My sub render window", 800, 600, false, &misc );

// choose scene manager
mSceneMgr = mRoot->createSceneManager(Ogre::ST_EXTERIOR_CLOSE, "SceneManager");

Ogre::Light *light = mSceneMgr->createLight("Sun");
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(Ogre::Vector3(0.0f, -0.5f, 1.0f));
mSceneMgr->setAmbientLight(Ogre::ColourValue(1, 1, 1));

// Create the camera
.... (code edited for brevity)

// Basic terrain ..
mSceneMgr->setFog(Ogre::FOG_LINEAR, mViewPort->getBackgroundColour(), 0, 100, 700);
mSceneMgr->setWorldGeometry("terrain.cfg");

// Paged Geomety

geometryPager = new Forests::PagedGeometry();
geometryPager->setCamera(getCamera());
geometryPager->setPageSize(80); //Set the size of each page of geometry
geometryPager->setInfinite(); //Use infinite paging mode
geometryPager->addDetailLevel<Forests::BatchPage>(150, 50); //Use batches up to 150 units away, and fade for 30 more units
geometryPager->addDetailLevel<Forests::ImpostorPage>(500, 50); //Use impostors up to 400 units, and for for 50 more units

//Create a new TreeLoader3D object
Forests::TreeLoader3D *treeLoader = new Forests::TreeLoader3D(geometryPager, Forests::TBounds(0, 0, 1500, 1500));
geometryPager->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance

//Load a tree entity
Ogre::Entity *myEntity = mSceneMgr->createEntity("Tree", "tree2.mesh");

//Setup the height function (so the Y values of trees can be calculated when they are placed on the terrain)

HeightFunction::initialize(mSceneMgr);

//Randomly place 20,000 copies of the tree on the terrain
Ogre::Vector3 position;
Ogre::Radian yaw;
Ogre::Real scale;
for (int i = 0; i < 20000; i++){
yaw = Ogre::Degree(Math::RangeRandom(0, 360));

position.x = Math::RangeRandom(0, 1500);
position.z = Math::RangeRandom(0, 1500);
position.y = HeightFunction::getTerrainHeight(position.x, position.z);

scale = Math::RangeRandom(0.5f, 0.6f);

treeLoader->addTree(myEntity, position, yaw, scale);
}

// End PagedGeometry

ShowWindow(m_window, SW_SHOWNORMAL);
UpdateWindow(m_window);

l_Class.lpszClassName = TEXT( "DesktopIndicatorHandlerClass" );

MSG msg;

PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);

while (msg.message!=WM_QUIT) {

if (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Ogre::WindowEventUtilities::messagePump();

if (!cameraController->control()) break;
geometryPager->update();
if (!mRoot->renderOneFrame()) break;

// Some other minor stuff done in here
}

All the code works fine in the example framework, with Ogre performing the window creation automatically, but when I do it, I get the following stack :

> msvcr71d.dll!operator delete(void * pUserData=0x06a019e8) Line 52 + 0x51 C++
JNITest.dll!std::allocator<std::_List_nod<Ogre::VertexElement,std::allocator<Ogre::VertexElement> >::_Node>::deallocate(std::_List_nod<Ogre::VertexElement,std::allocator<Ogre::VertexElement> >::_Node * _Ptr=0x06a019e8, unsigned int __formal=1) Line 132 + 0x9 C++
JNITest.dll!std::list<Ogre::VertexElement,std::allocator<Ogre::VertexElement> >::clear() Line 622 C++
JNITest.dll!std::list<Ogre::VertexElement,std::allocator<Ogre::VertexElement> >::_Tidy() Line 931 C++
JNITest.dll!std::list<Ogre::VertexElement,std::allocator<Ogre::VertexElement> >::~list<Ogre::VertexElement,std::allocator<Ogre::VertexElement> >() Line 366 C++
JNITest.dll!Forests::BatchedGeometry::SubBatch::build() Line 385 C++
JNITest.dll!Forests::BatchedGeometry::build() Line 155 C++
JNITest.dll!Forests::BatchPage::build() Line 71 C++
JNITest.dll!Forests::GeometryPageManager::_loadPage(Forests::GeometryPage * page=0x035caf80) Line 708 + 0xd C++
JNITest.dll!Forests::GeometryPageManager::update(unsigned long deltaTime=687, Ogre::Vector3 & camPos={...}, Ogre::Vector3 & camSpeed={...}, bool & enableCache=true, Forests::GeometryPageManager * prevManager=0x00000000) Line 404 C++
JNITest.dll!Forests::PagedGeometry::update() Line 223 C++
JNITest.dll!REAL::RenderWindowThread::doEnable() Line 396 C++
JNITest.dll!REAL::RenderWindowThread::ThreadProc(void * lpParameter=0x035c85d8) Line 127 C++
kernel32.dll!7c80b683()

The list deletion code is getting called after this piece of BatchedGeometry.cpp runs :

for (Ogre::ushort i = 0; i < vertBinding->getBufferCount(); ++i)
{
HardwareVertexBufferSharedPtr buffer = HardwareBufferManager::getSingleton()
.createVertexBuffer(vertDecl->getVertexSize(i), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

vertBinding->setBinding(i, buffer);
vertexBuffers.push_back(static_cast<uchar*>(buffer->lock(HardwareBuffer::HBL_DISCARD)));
vertexBufferElements.push_back(vertDecl->findElementsBySource(i));
}

it looks to me that the HardwareVertexBuffer is getting cleaned up by the shared ptr stuff, or that something else is invalid. I suspect something isn't getting initialized properly somewhere - any ideas on what I might be doing wrong ?

Everything works fine with the sample in it's original context.

JohnJ

28-07-2008 15:38:42

Hmm. I'm not sure what's wrong. Like you say, probably an initialization problem with the custom window. Are you sure you're not initializing PagedGeometry too early (before Ogre is ready?)

Tamarac

29-07-2008 04:56:07

I thought I was initializing Ogre before I loaded the PagingGeometry stuff (see above) - is this not sufficient ?

Just now I replaced the part where I load the plug-ins with the plug-in loading code from Example1 rather than hardcoding to the release plug-ins.

Weirdly, it fails when it tries to load the debug versions of the plugins (my DLL is debug) - loading the first plug-in for Cg - an assert for Root::getSingleton fails, because the singleton is NULL (it should not be, since the Root is created).

So, I'm sure that there is something to do with loading the plugins which is broken. If it matters, my app is using STL in a DLL, and is MT. I went through earlier and made sure all of the relevant linker and compile options were set up the same.

syedhs

29-07-2008 06:51:59

Maybe you are linking and loading different Ogre DLL? Eg link to Ogre 1.4.8 but run on Ogre 1.4.9.

Tamarac

30-07-2008 02:47:33

I found the solution to the problem. I had my .dll compiled as debug; it was linked to a non-debug OgreMain; which then failed to load debug plugins.

Making eveything debug (or release it would see) .. and everything works fine.