(C++) HOW TO: use .irr scene + a game manager Class
Posted: Sun Jan 21, 2007 3:10 am
Ok guys , I have been using IrrEdit in my project and im sure more of you would love to know how you can do this with a game manager in your project and still load scene data generated by IrrEdit and display it as you would with out it.
so having found the solution by trying various methods I have come upon a solution that works perfectly for this .
This is my first How To and I have tested this throughly in my project and so far it works perfectly, but as with most things in development resaults may vary depending on your OS , Complier and Compiler options . this example compiles and runs under Visual studio 2003 under windows server 2003 and should be fine under XP as well.
Right so off we go.
Step 1 - Create your meshes in 3dsmax or similar modeling program and import them into IrrEdit , then arrange your scene, lightmap, and save as a .irr file. this is the easy part lol
now to the code.
the first thing we want to do is tell the engine we want the game manager to be responsible for creating the Irrlicht device and that we want all of our functionality to be availibe via this game manager so we create a class for the game manger that will contain poiners to all the stuff we want to use easyly with out haveing to explicitly call the functions in our code over and over each time we want to use them.
so create a new file and make sure it is of type .h ( right click your project->add new item->somename.h->open.)
i call mine core.h but you may name it what ever you feel is apropreate.
now on to the class
the first thing to do is tell the compiler we want to include this file at compile time sooo..........
these preprocessor directives accomplish this.
now since we want all the engine fuctionality availible to the class, what would we put in there next ?
breif pause for thinking.........
well we need the namespaces irrlicht uses right ?
Wait, Stop you say, what about other classes and fuctions we may have in our code?
well in between the preprocessor directives and the namspace list you can forward declare those classes but that is beyond the scope of this how to
ok so now we have our directives and our namspaces time to start the class.!!!
now since the goal of this class is to make our coding much simpler and shorter what we do next is to create the pointers we need that point back to all our standard Irrlicht functions like so.
and that finishes the basic class definition, keep in mind we can add pointers for what ever we want to use easyly here, this will get ya started though.
ok now we need a source file to use these pointers in and to create the game manager object, initialize it and finaly keep track of everthing .
core.cpp
ok one more important thing to add is that if you use the Editor to add a camera, you must also add a camera scene node for it in your code in the EXACT and i do mean EXACT same position you put it in the editor, otherwise, the camera no matter what type of camera it may be will be static , you will be able to see your scene but not move the camera.....at all. also handy to have , you notice couts after each important fuction is either successful or fails , this can help you determine where your code starts misbehaving if something goes awry ( thank you to Vitek for that sugestion )
ok now that we have our game manager class and our implementation, we need our main function and you guessed it , entry point that tells the app where to start excuting code.
so main.cpp looks like this
But WAIT we dont have a CGame class or a run() fuction yet!!! well as you may have guessed, we create that next like so
game.h
now basicly all this class does is tells the app "ok there is a run function, its a boolian value ( true or false) and this fuction can only be accessed by ............ " yep you guessed it , the game manager because we want only the game manager to start the engine and thus the app so we can keep track of things and make our life easyer.
but wait , no where do we have a draw loop as of yet so how can we see our scene in action and doesnt that defeat the purpose of all this nifty stuff?
no, in the implementation for Game.cpp we will put our nifty pointers to work for us like this:
game.cpp
and there ya have it, an example of not only how to use a .irr scene file generated by IrrEdit as per a request in the IrrEdit forum but how to implement a game manager using it as well see not so bad was it?
thankx to Vitek for his help whilst tying to figure this stuff out and to the Guy that wrote the tutorial on how to add a game manager to use with irrlicht in which my game manager code is based on( lol cant remember your name ) as well as Niko for the excellent engine and editor and anyone else that answered my sometimes dingy posts i may have missed
please feel free to use this in your projects and modify it as needed:)
so having found the solution by trying various methods I have come upon a solution that works perfectly for this .
This is my first How To and I have tested this throughly in my project and so far it works perfectly, but as with most things in development resaults may vary depending on your OS , Complier and Compiler options . this example compiles and runs under Visual studio 2003 under windows server 2003 and should be fine under XP as well.
Right so off we go.
Step 1 - Create your meshes in 3dsmax or similar modeling program and import them into IrrEdit , then arrange your scene, lightmap, and save as a .irr file. this is the easy part lol
now to the code.
the first thing we want to do is tell the engine we want the game manager to be responsible for creating the Irrlicht device and that we want all of our functionality to be availibe via this game manager so we create a class for the game manger that will contain poiners to all the stuff we want to use easyly with out haveing to explicitly call the functions in our code over and over each time we want to use them.
so create a new file and make sure it is of type .h ( right click your project->add new item->somename.h->open.)
i call mine core.h but you may name it what ever you feel is apropreate.
now on to the class
the first thing to do is tell the compiler we want to include this file at compile time sooo..........
Code: Select all
#ifndef _CORE_H_
#define _CORE_H_
now since we want all the engine fuctionality availible to the class, what would we put in there next ?
breif pause for thinking.........
well we need the namespaces irrlicht uses right ?
Code: Select all
//engine namespaces
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
well in between the preprocessor directives and the namspace list you can forward declare those classes but that is beyond the scope of this how to
ok so now we have our directives and our namspaces time to start the class.!!!
now since the goal of this class is to make our coding much simpler and shorter what we do next is to create the pointers we need that point back to all our standard Irrlicht functions like so.
Code: Select all
class CGameCore //here we define the class and create our poiners
{
public:
//functions providing acess to engine componants.
//GUI Environment
IGUIEnvironment* getGUIEnv();
//Scene Manager
ISceneManager* getSceneMngr();
//video driver
IVideoDriver* getVideo();
//Engine core device
IrrlichtDevice* getDevice();
//constructor
CGameCore();
//destructor
virtual ~CGameCore();
private:
//used to insanianate device
void InitalizeDevice();
//corisponding pointers to engine core functions
IrrlichtDevice* pDevice;
IVideoDriver* pDrv;
ISceneManager* pSceneMngr;
IGUIEnvironment* pGUIEnv;
};
#endif
ok now we need a source file to use these pointers in and to create the game manager object, initialize it and finaly keep track of everthing .
core.cpp
Code: Select all
#include "core.h"
#include <iostream>
//constructor
CGameCore::CGameCore()
{
InitalizeDevice();
std::cout<<"Game Manager Created !\n";
}
//Default Constructor
CGameCore::~CGameCore()
{
std::cout<<"Game Manager Shut Down!!\n";
}
/* in thefuntion below we have 2 device types one that uses a directx
device with decent resolution settings and one using OpenGL with
minimal settings set up in an if statment. one cool thing about
doing ot this way is that if you have another app running that
wont release the directx driver, the game manager object
will automagicly use the openGL device instead and tell you
that its using it if you have a console app or a drop down style
console in your app ( quake style ) */
void CGameCore::InitalizeDevice()
{
pDevice = createDevice(EDT_DIRECT3D9, core::dimension2d<s32>(1024,768), 32, true, true, true);
std::cout<<"Device Creation Success !!\n";
//if above fails, use minimal config below
if(pDevice==NULL)
pDevice = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(1024,768),32,false,false,false);
std::cout<<"Warning : Minimal Device Config In Use !!\n";
//Init engine functions and store the pointers to them
pSceneMngr = pDevice->getSceneManager();
pDrv = pDevice->getVideoDriver();
pGUIEnv = pDevice->getGUIEnvironment();
//load scene using our pointer we made for the scene manager
pSceneMngr->loadScene("G:/ada1/ada1/debug/maps/home.irr");
std::cout<<" Scene 1 Loaded......\n";
/* one thing to note about Irredit is the fact that once the scene file
gets written out , upon loading it into the engine , you have to access
the nodes you want to work with by name, Id, or type, the commented
line below accesses the scene node named "home" by casting it as an
animated mesh scene node, then returning the name of the node
in question via getSceneNodeByName() then we can use the returned
node we cast it as to change material flag settings and the like. */
//IAnimatedMeshSceneNode* hnode = (IAnimatedMeshSceneNode*)pSceneMngr->getSceneNodeFromName("home");
//here we use the node name we casted above to change material flags
//hnode->setMaterialFlag(video::EMF_LIGHTING, false);
//add a light
scene::ISceneNode* lnode = 0;
lnode = pSceneMngr->addLightSceneNode(0, core::vector3df(200.0f,0,0));
//camera scene node
scene::ICameraSceneNode* player = pSceneMngr->addCameraSceneNodeFPS(0,100.0f,300.0f);
player->setPosition(core::vector3df(695.0f,119.0f,275.0f));
//disable mouse pointer
pDevice->getCursorControl()->setVisible(false);
std::cout<<"Mouse Pointer Disabled\n";
}
//return a funtion to engine core fuctions here
IrrlichtDevice* CGameCore::getDevice()
{
return pDevice;
}
// GUI
IGUIEnvironment* CGameCore::getGUIEnv()
{
return pGUIEnv;
}
//Video
IVideoDriver* CGameCore::getVideo()
{
return pDrv;
}
//Scene Manager
ISceneManager* CGameCore::getSceneMngr()
{
return pSceneMngr;
}
ok now that we have our game manager class and our implementation, we need our main function and you guessed it , entry point that tells the app where to start excuting code.
so main.cpp looks like this
Code: Select all
#include <irrlicht.h>
#include <iostream>
//new classes
#include "core.h"
#include "Game.h"
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
//this will disable the console window on startup when implemented
//#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
int main()
{
CGame game;
game.run();
}
game.h
Code: Select all
#ifndef _GAME_H_
#define _GAME_H_
#include <irrlicht.h>
#include "core.h"
using namespace irr;
//! Main entry point to game
class CGame
{
public:
CGame();
bool run();
private:
CGameCore pManager;
};
#endif
but wait , no where do we have a draw loop as of yet so how can we see our scene in action and doesnt that defeat the purpose of all this nifty stuff?
no, in the implementation for Game.cpp we will put our nifty pointers to work for us like this:
game.cpp
Code: Select all
#include "Game.h"
#include "core.h"
CGame::CGame()
{
}
//! Main game loop
bool CGame::run()
{
IrrlichtDevice* pDevice = 0;
IVideoDriver* pDrv = 0;
ISceneManager* pSceneMngr = 0;
IGUIEnvironment* pGUIEnv = 0;
// Name of game, displayed in window if windowed
pManager.getDevice()->setWindowCaption(L"some app name here");
int lastFPS = -1; //<-----doesnt work because there is no code to display
// fps in this example but needed to compile sucessfuly
// Keep running game loop if device exists
while(pManager.getDevice()->run())
{
pManager.getVideo()->beginScene(true,true, SColor(255, 100, 101, 140));
pManager.getSceneMngr()->drawAll();
pManager.getGUIEnv()->drawAll();
pManager.getVideo()->endScene();
}
{
pManager.getDevice()->drop();
}
return 0;
}
thankx to Vitek for his help whilst tying to figure this stuff out and to the Guy that wrote the tutorial on how to add a game manager to use with irrlicht in which my game manager code is based on( lol cant remember your name ) as well as Niko for the excellent engine and editor and anyone else that answered my sometimes dingy posts i may have missed
please feel free to use this in your projects and modify it as needed:)