Page 1 of 1

[SOLVED] How to render into an existing window?

Posted: Sat Oct 29, 2011 6:50 am
by Nav
I'm passing a window handle to Ogre and trying to use createRenderWindow to cause Ogre to render into that window.

Code: Select all

bool LowLevelOgre::go(HWND m_hWnd)
{
    //...some code (not shown)
    // configure 
    Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
    if(!(rs->getName() == "OpenGL Rendering Subsystem")) {return false;}//No RenderSystem found

    // configure our RenderSystem
    rs->setConfigOption("Full Screen", "No");
    rs->setConfigOption("VSync", "No");
    rs->setConfigOption("Video Mode", "1024 x 760 @ 32-bit");
 
    mRoot->setRenderSystem(rs);
 
    //mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");
    Ogre::String winHandle;
    winHandle += Ogre::StringConverter::toString(m_hWnd);
    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = winHandle;
    mWindow = mRoot->createRenderWindow( "My window", 100, 100, false, &params );
    
    //....more code (not shown)
}
It builds, but the program crashes when run. During the build I get this warning:
1>f:\projects\visualstudio\projects\polygon\polygon\polyctl.h(102): warning C4800: 'HWND' : forcing value to bool 'true' or 'false' (performance warning)
So obviously I'm doing something wrong in the toString function. I got the string conversion function from a QT based code where they were converting a window id into a string. I'm just creating a DLL in VC++, so how can I render into the window?

Re: How to render into an existing window?

Posted: Sat Oct 29, 2011 10:17 am
by LiMuBei
Looks good to me. I'm using this to create the handle string

Code: Select all

handle = Ogre::StringConverter::toString((size_t)((HWND)Wnd->GetHWND()));
In my case though, Wnd is a wxWidgets window, but if I remember correctly GetHWND() simply returns the windows window handle.

Also, you should probably change the += to a = :)

Re: How to render into an existing window?

Posted: Sat Oct 29, 2011 10:36 am
by Nav
Tried what you suggested. It builds fine, but when loading the ActiveX control DLL (my program) into another application, it aborts saying "Debug error ... R6010".
I wonder if it's because I'm passing a wrong window handle to the "go" function.

My program is an ActiveX DLL, which passes the window handle to "go" like this:

Code: Select all

HRESULT CPolyCtl::OnDraw(ATL_DRAWINFO& di)
{
   LowLevelOgre app;
   app.go(m_hWnd);//I know this shouldn't be in onDraw, but am keeping it here just for a start
   return S_OK;
}//OnDraw
I assumed that m_hWnd would be the window handle. Calling this.getParent() caused the control to abort because IsParent() failed to assert.
Need help...

Re: How to render into an existing window?

Posted: Sat Oct 29, 2011 12:18 pm
by Nav
Tried something else:
I took the code from here: http://www.winprog.org/tutorial/simple_window.html
and passed the window handle of the program to Ogre like this:

In my LowLevelOgre class

Code: Select all

LowLevelOgre::LowLevelOgre(HWND h)   : mRoot(0), mCamera(0), mSceneMgr(0), mWindow((Ogre::RenderWindow*)h) {}
In the WinMain of the tutorial code:

Code: Select all

LowLevelOgre app(hwnd);
app.go();
In the go() function:

Code: Select all

//initialize root and the render system
mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");
//do the Ogre head rendering
The tutorial's small window gets created and the Ogre head is rendered in a separate window.
But that's not what I want. I want the Ogre head to be rendered inside the tutorial's window! How can that be achieved?

p.s: Tried mRoot->initialise(false,..) but it crashes saying "no factory found for scenemanager of type octtreescenemanager" which means it couldn't find the window for rendering.

Re: How to render into an existing window?

Posted: Sat Oct 29, 2011 12:58 pm
by Mind Calamity
Nav wrote: In the go() function:

Code: Select all

//initialize root and the render system
mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");
//do the Ogre head rendering
Your Code wrote:mRoot->initialise(true);
You're telling OGRE to create a new window, yet you want it to render in your own ?

The parameters of the initialise() function are about creating a new window, and you said "yes" to the offer.

I think just changing that to this:

Code: Select all

mRoot->initialise(false);
Would do the trick, as that is what I use for my Qt application.

Re: How to render into an existing window?

Posted: Mon Oct 31, 2011 12:21 am
by LiMuBei
Nav wrote:p.s: Tried mRoot->initialise(false,..) but it crashes saying "no factory found for scenemanager of type octtreescenemanager" which means it couldn't find the window for rendering.
Uh...no? That just means that Ogre couldn't instantiate an octree scene manager, which is most likely because you haven't loaded the plugin. If you want to render to an existing window you have to initialize with false, like Mind Calamity already said.

Re: How to render into an existing window?

Posted: Mon Oct 31, 2011 5:53 am
by Nav
Thanks Mind and LiMuBei. Program still crashes. I'm lost.

This is the entire code:

Code: Select all

#include <windows.h>
#include <OgreRoot.h>
#include <OgreCamera.h>
#include <OgreSceneManager.h>
#include <OgreRenderWindow.h>

#include <OgreManualObject.h>
#include <OgrePrerequisites.h>
#include <OgreRenderQueueListener.h>

class LowLevelOgre
{
public:
    LowLevelOgre(void);
    LowLevelOgre(HWND h);
    virtual ~LowLevelOgre(void);
    bool go(void);
protected:
    Ogre::Root *mRoot;
    Ogre::Camera* mCamera;
    Ogre::SceneManager* mSceneMgr;
    Ogre::RenderWindow* mWindow;

};

#include <OgreLogManager.h>
#include <OgreViewport.h>
#include <OgreEntity.h>
#include <OgreWindowEventUtilities.h>
#include <OgrePlugin.h>

//-------------------------------------------------------------------------------------
LowLevelOgre::LowLevelOgre(HWND h)   : mRoot(0), mCamera(0), mSceneMgr(0), mWindow((Ogre::RenderWindow*)h) {}
LowLevelOgre::~LowLevelOgre(void) {delete mRoot;}
//-------------------------------------------------------------------------------------
 
bool LowLevelOgre::go(void)
{
    // construct Ogre::Root : no plugins filename, no config filename, using a custom log filename
    mRoot = new Ogre::Root("", "", "LowLevelOgre.log");
 
    // A list of required plugins
    Ogre::StringVector required_plugins;
    required_plugins.push_back("GL RenderSystem");
    required_plugins.push_back("Octree & Terrain Scene Manager");
 
    // List of plugins to load
    Ogre::StringVector plugins_toLoad;
    plugins_toLoad.push_back("RenderSystem_GL");
    plugins_toLoad.push_back("Plugin_OctreeSceneManager");
 
    // Load the OpenGL RenderSystem and the Octree SceneManager plugins
    for (Ogre::StringVector::iterator j = plugins_toLoad.begin(); j != plugins_toLoad.end(); j++)
    {
#ifdef _DEBUG
        mRoot->loadPlugin(*j + Ogre::String("_d"));
#else
        mRoot->loadPlugin(*j);
#endif;
    }
 
    // Check if the required plugins are installed and ready for use
    // If not: exit the application
    Ogre::Root::PluginInstanceList ip = mRoot->getInstalledPlugins();
    for (Ogre::StringVector::iterator j = required_plugins.begin(); j != required_plugins.end(); j++)
    {
        bool found = false;
        // try to find the required plugin in the current installed plugins
        for (Ogre::Root::PluginInstanceList::iterator k = ip.begin(); k != ip.end(); k++)
        {
            if ((*k)->getName() == *j) {found = true;break;}
        }//for
        if (!found) {return false;}  // return false because a required plugin is not available
    }//for
 
//-------------------------------------------------------------------------------------
    // setup resources. Only add the minimally required resource locations to load up the Ogre head mesh    
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/programs", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/scripts", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/textures", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/models", "FileSystem", "General");
//-------------------------------------------------------------------------------------
    // configure 
    Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
    if(!(rs->getName() == "OpenGL Rendering Subsystem")) {return false;}//No RenderSystem found
    // configure our RenderSystem
    rs->setConfigOption("Full Screen", "No");
    rs->setConfigOption("VSync", "No");
    rs->setConfigOption("Video Mode", "1024 x 760 @ 32-bit");
    mRoot->setRenderSystem(rs);
 
    //mWindow = mRoot->initialise(false, "LowLevelOgre Render Window");
    mRoot->initialise(false);
    /*Ogre::String winHandle;
    winHandle = Ogre::StringConverter::toString(mWindow);
    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = winHandle;
    mWindow = mRoot->createRenderWindow( "My window", 100, 100, false, &params );*/

//-------------------------------------------------------------------------------------
    // Get the SceneManager, in this case the OctreeSceneManager
    mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "DefaultSceneManager");
    //mSceneMgr = mRoot->createSceneManager("DefaultSceneManager");
//-------------------------------------------------------------------------------------
    mCamera = mSceneMgr->createCamera("PlayerCam");// create camera
    mCamera->setPosition(Ogre::Vector3(0,0,800));// Position it at 800 in Z direction
    mCamera->lookAt(Ogre::Vector3(0,0,-50));// Look back along -Z
    mCamera->setNearClipDistance(5);
//-------------------------------------------------------------------------------------
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
    mCamera->setAspectRatio( Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()) );// Alter the camera aspect ratio to match the viewport
//-------------------------------------------------------------------------------------
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);// Set default mipmap level (NB some APIs ignore this)
//-------------------------------------------------------------------------------------
    // Create any resource listeners (for loading screens)
    //createResourceListener();
//-------------------------------------------------------------------------------------
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();// load resources
//-------------------------------------------------------------------------------------
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");// Create the scene
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));// Set ambient light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");// Create a light
    l->setPosition(20,80,50);
//-------------------------------------------------------------------------------------
    //mRoot->startRendering();
    while(true)
    {
        Ogre::WindowEventUtilities::messagePump(); // Pump window messages for nice behaviour
        mRoot->renderOneFrame();// Render a frame
        if(mWindow->isClosed()) {return false;}
    }
    // We should never be able to reach this corner but return true to calm down our compiler
    return true;
}//go
 
const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,  NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",  MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

        LowLevelOgre app(hwnd);// Create application object
 
        try {app.go();} 
        catch( Ogre::Exception& e ) 
        {
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
        }

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
Running the program requires the following files to be present in your Debug directory:
OgreMain_d.dll
OIS_d.dll
Plugin_OctreeSceneManager_d.dll
RenderSystem_Direct3D9_d.dll
RenderSystem_GL_d.dll
OgreMain_d.ilk
Plugin_OctreeSceneManager_d.ilk
RenderSystem_Direct3D9_d.ilk
RenderSystem_GL_d.ilk
OgreMain.pdb
Plugin_OctreeSceneManager.pdb
RenderSystem_Direct3D9.pdb
RenderSystem_GL.pdb
C/C++ Additional include directories:
$(OGRE_HOME)\OgreMain\include;$(OGRE_HOME)\bin\include;$(OGRE_HOME)\Dependencies\include\OIS;
Linker Additional library directories:
$(OGRE_HOME)\bin\lib;$(OGRE_HOME)\bin\lib\Debug;$(OGRE_HOME)\Dependencies\lib\Debug
Linker Input Additional dependencies:
kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;OgreMain_d.lib;OIS_d.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
Caution: In my program, I've specified some paths as absolute Eg: Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/programs", "FileSystem", "General");

Re: How to render into an existing window?

Posted: Mon Oct 31, 2011 12:05 pm
by LiMuBei
I think you need to create the render window before the scene manager, in the code you commented that part out.

Re: How to render into an existing window?

Posted: Mon Oct 31, 2011 12:10 pm
by Nav
Had already tried createRenderWindow. It simply creates a separate window instead of rendering into the window I want it to render into. That's why I commented it out.

Re: How to render into an existing window?

Posted: Mon Oct 31, 2011 3:12 pm
by Nav
Could anybody please help? I've been trying variations all day, looking up the documentation for RenderTarget etc. and didn't get a clue about how to solve it.
Isn't it possible for Ogre to render into another window at all?

Re: How to render into an existing window?

Posted: Mon Oct 31, 2011 4:13 pm
by Mind Calamity
Nav wrote:Could anybody please help? I've been trying variations all day, looking up the documentation for RenderTarget etc. and didn't get a clue about how to solve it.
Isn't it possible for Ogre to render into another window at all?
Upload the source of your application, if it isn't anything secret, and I'll try to locate and solve the problem. :)

Re: How to render into an existing window?

Posted: Tue Nov 01, 2011 12:13 am
by LiMuBei
Highly possible your window handle is not correct then. That was mostly the reason when rendering into an existing window didn't work for me.

Re: How to render into an existing window?

Posted: Tue Nov 01, 2011 5:14 am
by Nav
@Mind Calamity: I've already posted the entire source above. Also posted the files and linker requirements you'll need to run the program. You can find it by searching this page for the sentence "This is the entire code:". Thanks.

@LiMuBei: I picked the simplest window creating program so that I could be sure I'm passing the correct handle. See the code above. I've used:

Code: Select all

hwnd = CreateWindowEx(blah);
LowLevelOgre app(hwnd);
Wonder why it didn't work.

Re: How to render into an existing window?

Posted: Tue Nov 01, 2011 2:54 pm
by Nav
Yaaaaaaaaaaaaaaaaaaaahooooooooooooooooo! Solved it myself :)

Code: Select all

#include <windows.h>
#include <OgreRoot.h>
#include <OgreCamera.h>
#include <OgreSceneManager.h>
#include <OgreRenderWindow.h>

#include <OgreManualObject.h>
#include <OgrePrerequisites.h>
#include <OgreRenderQueueListener.h>

class LowLevelOgre
{
public:
    LowLevelOgre(void);
    LowLevelOgre(HWND h);
    virtual ~LowLevelOgre(void);
    bool go(HWND hwnd);
protected:
    Ogre::Root *mRoot;
    Ogre::Camera* mCamera;
    Ogre::SceneManager* mSceneMgr;
    Ogre::RenderWindow* mWindow;
};

#include <OgreLogManager.h>
#include <OgreViewport.h>
#include <OgreEntity.h>
#include <OgreWindowEventUtilities.h>
#include <OgrePlugin.h>

//-------------------------------------------------------------------------------------
LowLevelOgre::LowLevelOgre(HWND h) : mRoot(0), mCamera(0), mSceneMgr(0), mWindow(0) {}
LowLevelOgre::~LowLevelOgre(void) {delete mRoot;}
//-------------------------------------------------------------------------------------
 
bool LowLevelOgre::go(HWND hwnd)
{
    // construct Ogre::Root : no plugins filename, no config filename, using a custom log filename
    mRoot = new Ogre::Root("", "", "LowLevelOgre.log");
 
    // A list of required plugins
    Ogre::StringVector required_plugins;
    required_plugins.push_back("GL RenderSystem");
    required_plugins.push_back("Octree & Terrain Scene Manager");
 
    // List of plugins to load
    Ogre::StringVector plugins_toLoad;
    plugins_toLoad.push_back("RenderSystem_GL");
    plugins_toLoad.push_back("Plugin_OctreeSceneManager");
 
    // Load the OpenGL RenderSystem and the Octree SceneManager plugins
    for (Ogre::StringVector::iterator j = plugins_toLoad.begin(); j != plugins_toLoad.end(); j++)
    {
#ifdef _DEBUG
        mRoot->loadPlugin(*j + Ogre::String("_d"));
#else
        mRoot->loadPlugin(*j);
#endif;
    }
 
    // Check if the required plugins are installed and ready for use
    // If not: exit the application
    Ogre::Root::PluginInstanceList ip = mRoot->getInstalledPlugins();
    for (Ogre::StringVector::iterator j = required_plugins.begin(); j != required_plugins.end(); j++)
    {
        bool found = false;
        // try to find the required plugin in the current installed plugins
        for (Ogre::Root::PluginInstanceList::iterator k = ip.begin(); k != ip.end(); k++)
        {
            if ((*k)->getName() == *j) {found = true;break;}
        }//for
        if (!found) {return false;}  // return false because a required plugin is not available
    }//for
 
//-------------------------------------------------------------------------------------
    // setup resources. Only add the minimally required resource locations to load up the Ogre head mesh    
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/programs", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/scripts", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/textures", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/models", "FileSystem", "General");
//-------------------------------------------------------------------------------------
    // configure 
    Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
    if(!(rs->getName() == "OpenGL Rendering Subsystem")) {return false;}//No RenderSystem found
    // configure our RenderSystem
    rs->setConfigOption("Full Screen", "No");
    rs->setConfigOption("VSync", "No");
    rs->setConfigOption("Video Mode", "1024 x 760 @ 32-bit");
    mRoot->setRenderSystem(rs);
 

    
mRoot->initialise(false);
HWND hWnd = hwnd;  // Get the hWnd of the application!
Ogre::NameValuePairList misc;
misc["externalWindowHandle"] = Ogre::StringConverter::toString((int)hWnd);
mWindow = mRoot->createRenderWindow("Main RenderWindow", 800, 600, false, &misc);


/*Ogre::NameValuePairList misc;
if (mWindow) misc["externalWindowHandle"] = Ogre::StringConverter::toString(mWindow);
//misc["colourDepth"] = Ogre::StringConverter::toString(32);
mWindow=mRoot->createRenderWindow("RenderWindowName", 800,600, false, &misc);
mWindow->setActive(true);*/

    //mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");
    //mRoot->initialise(false);
    /*Ogre::String winHandle;
    winHandle = Ogre::StringConverter::toString(mWindow);
    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = winHandle;
    mWindow = mRoot->createRenderWindow( "My window", 100, 100, false, &params );*/

//-------------------------------------------------------------------------------------
    // Get the SceneManager, in this case the OctreeSceneManager
    mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "DefaultSceneManager");
    //mSceneMgr = mRoot->createSceneManager("DefaultSceneManager");
//-------------------------------------------------------------------------------------
    mCamera = mSceneMgr->createCamera("PlayerCam");// create camera
    mCamera->setPosition(Ogre::Vector3(0,0,800));// Position it at 800 in Z direction
    mCamera->lookAt(Ogre::Vector3(0,0,-50));// Look back along -Z
    mCamera->setNearClipDistance(5);
//-------------------------------------------------------------------------------------
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
    mCamera->setAspectRatio( Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()) );// Alter the camera aspect ratio to match the viewport
//-------------------------------------------------------------------------------------
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);// Set default mipmap level (NB some APIs ignore this)
//-------------------------------------------------------------------------------------
    // Create any resource listeners (for loading screens)
    //createResourceListener();
//-------------------------------------------------------------------------------------
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();// load resources
//-------------------------------------------------------------------------------------
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");// Create the scene
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));// Set ambient light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");// Create a light
    l->setPosition(20,80,50);
//-------------------------------------------------------------------------------------
    //mRoot->startRendering();
    while(true)
    {
        Ogre::WindowEventUtilities::messagePump(); // Pump window messages for nice behaviour
        mRoot->renderOneFrame();// Render a frame
        if(mWindow->isClosed()) {return false;}
    }
    // We should never be able to reach this corner but return true to calm down our compiler
    return true;
}//go
 








const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,  NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",  MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

        LowLevelOgre app(hwnd);// Create application object
 
        try {app.go(hwnd);} 
        catch( Ogre::Exception& e ) 
        {
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
        }

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}