OgreTest::OgreTest() :
ogreRoot(new Ogre::Root()) {
// WinRt apps only have one render system they can pick from...
pickFirstAvailableRenderSystem();
this->ogreRoot->initialise(false);
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::Initialize(CoreApplicationView ^applicationView) {
// ...omitted WinRT suspend/resume event subscribing stuff...
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::SetWindow(CoreWindow ^window) {
this->window = window;
setupOgreRenderWindow();
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::Load(Platform::String ^entryPoint) {
this->ogreSceneManager = this->ogreRoot->createSceneManager(Ogre::ST_GENERIC);
this->ogreCamera = this->ogreSceneManager->createCamera("DefaultCamera");
this->ogreCamera->setPosition(Ogre::Vector3(0.0f, 100.0f, 250.0f));
this->ogreCamera->lookAt(Ogre::Vector3(0.0f, 50.0f, 0.0f));
this->ogreRenderWindow->removeAllViewports();
Ogre::Viewport *viewport = this->ogreRenderWindow->addViewport(this->ogreCamera);
viewport->setBackgroundColour(
Ogre::ColourValue(20.0f / 255.0f, 106.0f / 255.0f, 181.0f / 255.0f)
);
// This thing generates shader at runtime. It's currently not clear whether
// D3DCompile() will be supported on ARM (in the Windows 8 Consumer Preview,
// the ARM DLL is missing), so it might be wise to not rely on it.
initializeRuntimeShaderSystem();
// Only load what's necessary here. Metro applications must not become
// unresponsive for more than 50 ms at a time, so maybe load the resources necessary
// to display a loading screen here and do the rest asynchronously!
loadResources();
// Create the example scene
createScene();
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::Run() {
BasicTimer ^timer = ref new BasicTimer();
// App main loop
while(!this->windowClosed && !this->ogreRoot->endRenderingQueued()) {
timer->Update();
this->ogreRoot->renderOneFrame(timer->Delta);
// Good old message pump :)
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(
CoreProcessEventsOption::ProcessAllIfPresent
);
}
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::Uninitialize() {
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::pickFirstAvailableRenderSystem() {
assert(this->ogreRoot != nullptr);
const Ogre::RenderSystemList &renderSystems = this->ogreRoot->getAvailableRenderers();
for(
Ogre::RenderSystemList::const_iterator iterator = renderSystems.begin();
iterator != renderSystems.end();
++iterator
) {
this->ogreRoot->setRenderSystem(*iterator);
return;
}
throw std::runtime_error("No render systems registered");
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::setupOgreRenderWindow() {
Windows::Foundation::Rect bounds = this->window->Bounds;
// You cannot create windows in metro (not even a message box), instead, Windows
// hands you a "window" - a full-screen view, actually - that you can use. Thus,
// we don't proactively create a render window but just set up our render window
// into the one provided by Windows.
Ogre::NameValuePairList parameters;
parameters["externalWindowHandle"] = Ogre::StringConverter::toString(
(unsigned long)reinterpret_cast<void *>(this->window)
);
this->ogreRenderWindow = this->ogreRoot->createRenderWindow(
"OgreTest Rendering Window",
static_cast<unsigned int>(bounds.Width), static_cast<unsigned int>(bounds.Height),
false, // fullscreen
¶meters
);
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::initializeRuntimeShaderSystem() {
if(!Ogre::RTShader::ShaderGenerator::initialize()) {
throw std::runtime_error("Could not initialize runtime shader system");
}
this->ogreShaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
"Resources/RTShaderLib", "FileSystem"
);
this->ogreShaderGenerator->addSceneManager(this->ogreSceneManager);
// TODO: Enabling this on WinRT doesn't work yet. It fails to write the test file.
//this->ogreShaderGenerator->setShaderCachePath("Resources/RTShaderCache");
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::loadResources() {
Ogre::ConfigFile resourcesCfg;
resourcesCfg.load("resources.cfg");
// Go through all sections & settings in the file
Ogre::ConfigFile::SectionIterator sectionIterator = resourcesCfg.getSectionIterator();
while (sectionIterator.hasMoreElements()) {
Ogre::String sectionName = sectionIterator.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = sectionIterator.getNext();
for(
Ogre::ConfigFile::SettingsMultiMap::iterator iterator = settings->begin();
iterator != settings->end();
++iterator
) {
Ogre::String typeName = iterator->first;
Ogre::String archiveName = iterator->second;
bool recursive = true;
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
archiveName, typeName, sectionName, recursive
);
}
}
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
// --------------------------------------------------------------------------------------------- //
void OgreTest::createScene() {
// TODO: If you attemp to render the example mesh, the renderer will explode complaining:
//
// "Attempted to render to a D3D11 device without both vertex and fragment shaders there
// is no fixed pipeline in d3d11 - use the RTSS or write custom shaders."
//
// To see the actual error message, hit Ctrl+D,E to bring up the exception menu
// and tick the checkboxes in the "Thrown" column for C++ exceptions.
this->ogreSceneManager->setAmbientLight(Ogre::ColourValue::White);
//Ogre::Entity *entity = this->ogreSceneManager->createEntity("Head", "ogrehead.mesh");
//Ogre::SceneNode *node = this->ogreSceneManager->getRootSceneNode()->createChildSceneNode("HeadNode");
//node->attachObject(entity);
}