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.
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.