Creating an IGUIEnvironment
Creating an IGUIEnvironment
Hello everybody, how do I create and use an IGUIEnvironment without having to get it from the IrrlichtDriver? I want to make different environments for my different scenes which, at certain points, will change the environments loading a different one depending on the scene I'm at.. I can't find a function that sets the environment for the IrrlichtDriver... is there a way to do this?
I dont have an answer to your exact question, but I do have a system that I use that performs the same type of function.
the 'level' class keeps track of any gui elements that are created and it hides/restores them as the level is loaded and unloaded. This allows me to use a 'level' for anything that I want, for example, the main menu is just a level itself, which allows me to have an animated 3d background going on whiel the user is in the main menu. It also allows game objects to add gui elements to the screen (example, an 'eye' is displayed when the 'true vision' spell is active. It opens when the owner object is near a 'secret'
the CSApp has a list of 'levels' and can swap between them.
Each level has it's own SMGR which is used for rendering everything. This is particularly cool, as I can load multiple 'levels' and hot swap between them, gui included and i dont have to do any fancy footwork.
When a level becomes the active level, the app calls the Load() function of the level. When the level loses 'focus' the app calls the UnLoad() function.
Here is an example level to show what I mean.
notice the Load() function, it is called by the App class when the level is selected as the active level.
notice also that the m_Smgr of the selected level becomes the input smgr for the device. Pretty cool stuff they left us in there I think
last btut not least, the app calls the frame of the level each frame
so............ again, I dont have an answer to your exact question, but maybe this will give you can idea of how to simulate what you are wanting.
the 'level' class keeps track of any gui elements that are created and it hides/restores them as the level is loaded and unloaded. This allows me to use a 'level' for anything that I want, for example, the main menu is just a level itself, which allows me to have an animated 3d background going on whiel the user is in the main menu. It also allows game objects to add gui elements to the screen (example, an 'eye' is displayed when the 'true vision' spell is active. It opens when the owner object is near a 'secret'
the CSApp has a list of 'levels' and can swap between them.
Each level has it's own SMGR which is used for rendering everything. This is particularly cool, as I can load multiple 'levels' and hot swap between them, gui included and i dont have to do any fancy footwork.
When a level becomes the active level, the app calls the Load() function of the level. When the level loses 'focus' the app calls the UnLoad() function.
Code: Select all
oid CSLevel::Load()
{
}
void CSLevel::UnLoad()
{
// ok, a little strange behavior here.
// in the event that a parent exists, we have to account for that
// so...... run backwards through the list (parent always created before child)
// and if parent exists, dont delete the child because the parent will do that
// when it is destroyed
for (int x=MAX_GUI_ELEMENTS-1; x>-1; x--)
{
if (m_GUIElements[x])
{
if (m_GUIElements[x]->getParent()!=0) m_GUIElements[x]->remove();
m_GUIElements[x]=NULL;
}
}
}
Code: Select all
#pragma once
// include the needed header files
#include "CSApp.h"
#include "CSlevel.h"
#include "GlobalData.h"
#include <windows.h>
#include <stdio.h>
// a simple test level to use it is derived from CSLevel and can be added to the CSApp
// list of levels easily in the CobbleStones.h file
class CSLevel_SlideShow : public CSLevel
{
public:
// declare the persistent variables
ADD_PUBLIC(int,m_Timer,Timer);
ADD_PUBLIC(int,m_MaxTimer,MaxTimer);
ADD_PUBLIC(bool,m_Valid,Valid);
char m_Path[1000];
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
DWORD dwError;
INT retval;
// class contructor / destructor
CSLevel_SlideShow(void) { Initialize(); }
virtual ~CSLevel_SlideShow(void) { Cleanup(); }
// set all variables to a known value this prevents us from accessing memory
// that has not been allocated properly
virtual void Initialize() {
SetTimer(0);
SetMaxTimer(1000);
CS_INIT(m_Valid);
}
// using the create() method allows us to capture errors and handle
// them properly.
virtual bool Create(CSApp* App) {
// create the base class
if (!CSLevel::Create(App)) return false;
// create an Irrlicht FPS camera
// if we cannot create it, then bail, otherwise
// set the position to something nice
m_Camera = m_Smgr->addCameraSceneNodeFPS(0,100,100);
if (!m_Camera) return false;
m_Camera->setPosition(core::vector3df(50,50,-150));
strcpy(m_Path,"media");
int index = 0;
// Find the first file in the directory.
char dirpath[1000];
sprintf(dirpath,"%s\\*.jpg",m_Path);
hFind = FindFirstFile(ConvertToWChar(dirpath), &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) SetValid(false);
else SetValid(true);
// it looks like everything went fine
return true;
}
// cleanup whatever memory mess we made
virtual bool Cleanup() {
if (m_Valid) FindClose(hFind);
Initialize();
return false;
}
// do whatever this calss does each frame
virtual void Frame() {
// let the base class do whatver it does each frame
CSLevel::Frame();
m_Timer++;
// show the next picture
if (m_Timer > m_MaxTimer)
{
m_Timer = 0;
if (GetValid())
{
if (FindNextFile(hFind, &FindFileData) != 0)
{
// remember the filename
char filename[255];
char text[255];
wcstombs(text,FindFileData.cFileName,wcslen(FindFileData.cFileName));
if (m_GUIElements[1])m_GUIElements[1]->remove();
m_GUIElements[1] = 0;
sprintf(filename,"%s\\%s",m_Path,text);
int x = 0;
int y = 0;
ITexture* image = m_App->m_Engine->m_Driver->getTexture(filename);
if (image)
{
x = m_App->m_Engine->m_Device->getVideoDriver()->getScreenSize().Width/2 - (image->getSize().Width / 2);
y = m_App->m_Engine->m_Device->getVideoDriver()->getScreenSize().Height/2 - (image->getSize().Height / 2);
m_GUIElements[1] = m_App->m_Engine->m_Gui->addImage(image,position2d<int>(x,y));
}
}
else
{
FindClose(hFind);
// Find the first file in the directory.
char dirpath[1000];
sprintf(dirpath,"%s\\*.jpg",m_Path);
hFind = FindFirstFile(ConvertToWChar(dirpath), &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) SetValid(false);
else SetValid(true);
}
}
}
// render everything using this smgr
m_Smgr->drawAll();
}
virtual bool OnEvent(SEvent event)
{
// let the camera have the message if it wants it
if (m_Camera->OnEvent(event)) return true;
// do application level message handling here
// based upon the event type
switch(event.EventType)
{
case EET_GUI_EVENT :
{
if (event.GUIEvent.EventType == EGET_EDITBOX_ENTER)
{
if (GetValid()) FindClose(hFind);
strcpy(m_Path,ConvertToMultiByte((wchar_t*)event.GUIEvent.Caller->getText()));
// Find the first file in the directory.
char dirpath[1000];
sprintf(dirpath,"%s\\*.jpg",m_Path);
hFind = FindFirstFile(ConvertToWChar(dirpath), &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) SetValid(false);
else SetValid(true);
}
else
if (event.GUIEvent.EventType == EGET_SCROLL_BAR_CHANGED)
{
IGUIScrollBar* sb = (IGUIScrollBar*)event.GUIEvent.Caller;
m_MaxTimer = sb->getPos() * 100;
}
} break;
case EET_KEY_INPUT_EVENT :
{
if (event.KeyInput.Shift) { /*nothing*/ };
} break;
// if it is a mouse event
case EET_MOUSE_INPUT_EVENT :
{
// based upon the mouse event type
switch (event.MouseInput.Event)
{
// if it is a mouse right button down event
case EMIE_RMOUSE_PRESSED_DOWN :
{
}; break;
case EMIE_LMOUSE_PRESSED_DOWN :
{
} break;
case EMIE_LMOUSE_LEFT_UP :
{
} break;
case EMIE_MOUSE_MOVED :
{
} break;
}
} break;
}
// we did not want this message
return false;
}
// this is called whenever the level is set as the application current level
// reload whatever persistent GUI elements that there are and reset the mouse,
// fog etc...
virtual void Load() {
// toggle whether the mouse will move the camera
// or just mvoe around the screen for the GUI
m_Camera->setInputReceiverEnabled(false);
m_App->m_Engine->m_Device->getCursorControl()->setVisible(true);
m_GUIElements[0] = m_App->m_Engine->m_Gui->addEditBox(ConvertToWChar(m_Path),core::rect<s32>(10,10,200,30),true,0,ID_PATH);
m_GUIElements[2] = m_App->m_Engine->m_Gui->addScrollBar(true,core::rect<s32>(10,50,200,80),0,ID_SPEED);
}
};
Code: Select all
void CSApp::SetCurrentLevel(int i)
{
if (m_Levels[i])
{
if (m_Levels[m_CurrentLevel]) m_Levels[m_CurrentLevel]->UnLoad();
m_CurrentLevel = i;
m_Levels[m_CurrentLevel]->Load();
m_Engine->m_Device->setInputReceivingSceneManager(m_Levels[m_CurrentLevel]->m_Smgr);
}
}
last btut not least, the app calls the frame of the level each frame
Code: Select all
void CSApp::Frame()
{
if (GetEngine())
{
GetEngine()->BeginFrame();
if (m_Levels[m_CurrentLevel]) m_Levels[m_CurrentLevel]->Frame();
GetEngine()->Frame();
GetEngine()->EndFrame();
}
}
so............ again, I dont have an answer to your exact question, but maybe this will give you can idea of how to simulate what you are wanting.
another solution would be to create the GUI with another lib like FLTK or wxWidgets and use Irrlicht for render to a widget as view port...
there is a tutorial that shows how to render to a win32 window/widget and I think there are some threads in the forums, too...
there is a tutorial that shows how to render to a win32 window/widget and I think there are some threads in the forums, too...
while(!asleep) sheep++;
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
I solved it in a similar way(Edit: like Seven). You should look after GameStates and GameStateManager tutorials i think on http://www.GameDev.net is a nice one.
After posting this topic, and before reading your replies, I solved this problem myself.. Also I read that Gamestate on gameDev and I realized I did something which is similar to what is explained there.. only it's called GameScene instead of Gamestate... anyways my solution is that every GameScene has a initGUIEnv(); function which is called in the readyScene(); function which is the function called when a scene changes and another one is loaded. Inside the initGUIEnv(); I save the GUIEnvironment pointer taken from IrrlichtDevice inside an IGUIEnvironment object... Then I clear it (clearing whatever was inside it from other scenes) and I load all the GUI elements I need for that scene...