Problem with gui and while loop

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
systat
Posts: 41
Joined: Mon Jan 07, 2008 8:01 pm

Problem with gui and while loop

Post by systat »

Here is the code, I want't that it continously update some game data stats, which it do well, and I want to add a text in listbox when i press F9, but for some reason, actually guienv->clear(), it doesn't work, it appears for one seccond, but then it dissapears, I want that it stay there.
I don't know what else can I use except guienv, anyway, here is the code.
CGame.cpp

Code: Select all

#include "CGame.h"

  //////////////////////////////////////////////////////////////////
 //    Default constructor, better don't use this                //
//////////////////////////////////////////////////////////////////
CGame::CGame() : driverType(EDT_SOFTWARE), dimensions(640,480), bits(16), fullscreen(true), stencilbuffer(false), vsync(false) {}
	
CGame::CGame(E_DRIVER_TYPE drvType,dimension2d<s32> dim,u32 bts,bool fscr,bool stnc,bool vsnc)
: driverType(drvType),dimensions(dim),bits(bts),fullscreen(fscr),stencilbuffer(stnc),vsync(vsnc) {}



  //////////////////////////////////////////////////////////////////
 //                        Runs the Game                         //
//////////////////////////////////////////////////////////////////
void CGame::Run() {
	Initialize();
	//IGUIFont *font=guienv->getFont("arial.bmp");
	while(device->run()) {
	driver->beginScene(true,true,SColor(255,255,0,0));
		smgr->drawAll();
		guienv->drawAll();
		showStats();
		driver->endScene();
	}
	device->drop();
	return;
}

  //////////////////////////////////////////////////////////////////
 //                  Good 'ol Event Receiver                     //
//////////////////////////////////////////////////////////////////
bool CGame::OnEvent(const irr::SEvent &event) {
	if(!device)
		return false;
	if(event.EventType==EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)  {
		switch(event.KeyInput.Key) {
			case KEY_ESCAPE:
				device->closeDevice();
				return true;
			case KEY_F9:
				takeScreenshot();
				listbox->addItem(L"Screenshot taken..");

				return true;
		}
	
	}
		return false;
}
  //////////////////////////////////////////////////////////////////
 //               Initializations of all variables               //
//////////////////////////////////////////////////////////////////
void CGame::Initialize() {
	controls[0].Action=EKA_MOVE_FORWARD;
	controls[0].KeyCode=KEY_KEY_W;
	controls[1].Action=EKA_MOVE_BACKWARD;
	controls[1].KeyCode=KEY_KEY_S;
	controls[2].Action=EKA_STRAFE_LEFT;
	controls[2].KeyCode=KEY_KEY_A;
	controls[3].Action=EKA_STRAFE_RIGHT;
	controls[3].KeyCode=KEY_KEY_D;
	controls[4].Action=EKA_JUMP_UP;
	controls[4].KeyCode=KEY_KEY_E;
	device=createDevice(driverType,dimensions,bits,fullscreen,stencilbuffer,vsync);
	device->setEventReceiver(this);
	driver=device->getVideoDriver();
	guienv=device->getGUIEnvironment();
	smgr=device->getSceneManager();
    screen_center=position2d<s32>(driver->getScreenSize().Width/2,driver->getScreenSize().Height/2);
	device->getCursorControl()->setVisible(false);
	terrain=smgr->addTerrainSceneNode("blank.bmp",0,-1,vector3df(0,0,0),vector3df(0,0,0),vector3df(10,10,10),SColor(100,255,255,255),4,scene::ETPS_9);
	terrain->setMaterialFlag(EMF_LIGHTING,false);
	terrain->setMaterialTexture(0,driver->getTexture("data/woodflort.tga"));
	terrain->scaleTexture(50,50);
	skydome=smgr->addSkyDomeSceneNode(driver->getTexture("data/skydome.jpg"),32,32,1,2);
	camera=smgr->addCameraSceneNodeFPS(0,100,500,-1,controls,5);
	camera->setPosition(vector3df(0,100,0));
	camera->setFarValue(12000.0f);
	driver->makeColorKeyTexture(driver->getTexture("data/aim.bmp"),SColor(0,0,0,0));



}

void CGame::showStats() {
	IGUIFont *font=device->getGUIEnvironment()->getFont("arial.bmp");
	guienv->getSkin()->setFont(font);
	FPS=driver->getFPS();
	screenWidth=driver->getScreenSize().Width;
	screenHeight=driver->getScreenSize().Height;
	maxprimitive=driver->getMaximalPrimitiveCount();
	primitivecount=driver->getPrimitiveCountDrawn();
	materialcount=driver->getMaterialRendererCount();
	dynamiclightcount=driver->getDynamicLightCount();
	referencecount=driver->getReferenceCount();
    stringw gameData;
	gameData=L"FPS: ";
	gameData+=FPS;
	gameData+=L"\n";
	gameData+=L"Resolution:";
	gameData+=L"\nWidth->";
	gameData+=screenWidth;
	gameData+=L"\nHeight->";
	gameData+=screenHeight;
	gameData+=L"\nCounts:\n";
	gameData+=L"Max Primitive count->";
	gameData+=maxprimitive;
	gameData+="\nPrimitive count->";
	gameData+=primitivecount;
	gameData+="\nMaterial count->";
	gameData+=materialcount;
	gameData+="\nDynamic light count->";
	gameData+=dynamiclightcount;
	gameData+="\nReference count->";
	gameData+=referencecount;
	guienv->clear();
	info=guienv->addStaticText(gameData.c_str(),rect<s32>(0,0,220,180),true,true,0,-1,true);
	listbox = guienv->addListBox(rect<s32>(250, 100, 450, 310),0,-1,true);
}


void CGame::takeScreenshot() {
		stringc name;
        name="screenshot/screenie-";
		name+=device->getTimer()->getTime();
		name+=".jpg";
		screenshot=driver->createScreenShot();
		driver->writeImageToFile(screenshot,name.c_str());
		screenshot->drop();

}

void CGame::drawOnRun() {
	showStats();
	aim=guienv->addImage(driver->getTexture("data/aim.bmp"),screen_center);
	aim->setColor(SColor(150,255,255,255));
}

Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

of course !!! :lol:
you delete all gui elements and create new ones, so the new elements are empty (because new) !!!

Code: Select all

   guienv->clear();
   info=guienv->addStaticText(gameData.c_str(),rect<s32>(0,0,220,180),true,true,0,-1,true);
   listbox = guienv->addListBox(rect<s32>(250, 100, 450, 310),0,-1,true);
maybe use setText(...) for the text box

Code: Select all

   // guienv->clear(); // not used
   info->setText(gameData.c_str());
   // listbox = guienv->addListBox(rect<s32>(250, 100, 450, 310),0,-1,true); // not used
or only remove the text box and not the list box...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
systat
Posts: 41
Joined: Mon Jan 07, 2008 8:01 pm

Post by systat »

Thanks, but you only partially helped me, with text, but I still can't add item to the listbox when I press F9, I tried creating guienv2, etc, but that don't wokr neither.........................
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

hmmm, I don't see why it should not work...
it seems to be ok...
does it make a screen shot with F9 ???
does the escape key work ???

maybe show your current code and also show the header file (CGame.h)...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
systat
Posts: 41
Joined: Mon Jan 07, 2008 8:01 pm

Post by systat »

I want that when I press F9 that a text "Screenshot Taken.." appears for short period of time, and then dissapears, fade out or something like that, and that also in same time there is FPS, and other stats shown on screen.
pera
Posts: 460
Joined: Wed May 14, 2008 1:05 pm
Location: Novi Sad, Serbia
Contact:

Post by pera »

put this line in Init function:
listbox = guienv->addListBox(rect<s32>(250, 100, 450, 310),0,-1,true);

so you don't recreate the list box each frame.

if you want entry to disapear after a while, you'll need a timer.
(here is one silly way to do it:
- in show function check if screenshot text is shown
- if it is, increase member variable fadeoutTimer += timeElapsed;
- if fadeoutTimer > 10(sec), clean your screenshot text
timeElapsed can be taken from FPS calculations I think)
systat
Posts: 41
Joined: Mon Jan 07, 2008 8:01 pm

Post by systat »

Thanks, pera and acki, now it is working properly, only I experience FPS loss, yeah, like every 2-5 seconds FPS is falling away, so I came to 22 FPS, look at code, I don't know what is wrong here :(
I put a screenshot neither...

Code: Select all

#include "CGame.h"

  //////////////////////////////////////////////////////////////////
 //    Default constructor, better don't use this                //
//////////////////////////////////////////////////////////////////
CGame::CGame() : driverType(EDT_SOFTWARE), dimensions(640,480), bits(16), fullscreen(true), stencilbuffer(false), vsync(false) {}
	
CGame::CGame(E_DRIVER_TYPE drvType,dimension2d<s32> dim,u32 bts,bool fscr,bool stnc,bool vsnc)
: driverType(drvType),dimensions(dim),bits(bts),fullscreen(fscr),stencilbuffer(stnc),vsync(vsnc) {}



  //////////////////////////////////////////////////////////////////
 //                        Runs the Game                         //
//////////////////////////////////////////////////////////////////
void CGame::Run() {
	Initialize();
	while(device->run()) {
	driver->beginScene(true,true,SColor(255,255,0,0));
		smgr->drawAll();
		guienv->drawAll();
		showStats();
		driver->endScene();
	}
	device->drop();
	return;
}

  //////////////////////////////////////////////////////////////////
 //                  Good 'ol Event Receiver                     //
//////////////////////////////////////////////////////////////////
bool CGame::OnEvent(const irr::SEvent &event) {
	if(!device)
		return false;
	if(event.EventType==EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)  {
		switch(event.KeyInput.Key) {
			case KEY_ESCAPE:
				device->closeDevice();
				return true;
			case KEY_F9:				
				listbox->addItem(L"Screenshot taken...");
				takeScreenshot();

				return true;
		}
	
	}
		return false;
}
  //////////////////////////////////////////////////////////////////
 //               Initializations of all variables               //
//////////////////////////////////////////////////////////////////
void CGame::Initialize() {
	controls[0].Action=EKA_MOVE_FORWARD;
	controls[0].KeyCode=KEY_KEY_W;
	controls[1].Action=EKA_MOVE_BACKWARD;
	controls[1].KeyCode=KEY_KEY_S;
	controls[2].Action=EKA_STRAFE_LEFT;
	controls[2].KeyCode=KEY_KEY_A;
	controls[3].Action=EKA_STRAFE_RIGHT;
	controls[3].KeyCode=KEY_KEY_D;
	controls[4].Action=EKA_JUMP_UP;
	controls[4].KeyCode=KEY_KEY_E;
	device=createDevice(driverType,dimensions,bits,fullscreen,stencilbuffer,vsync);
	device->setEventReceiver(this);
	driver=device->getVideoDriver();
	guienv=device->getGUIEnvironment();
	smgr=device->getSceneManager();
    screen_center=position2d<s32>(driver->getScreenSize().Width/2,driver->getScreenSize().Height/2);
	device->getCursorControl()->setVisible(false);
	terrain=smgr->addTerrainSceneNode("data/terrain-heightmap.bmp",0,-1,vector3df(0,0,0),vector3df(0,0,0),vector3df(60,6,60),SColor(100,255,255,255),4,scene::ETPS_9);
	terrain->setMaterialFlag(EMF_LIGHTING,false);
	terrain->setMaterialTexture(0,driver->getTexture("data/detailmap3.jpg"));
	terrain->scaleTexture(10,50);
	skydome=smgr->addSkyDomeSceneNode(driver->getTexture("data/skydome.jpg"),32,32,1,2);
	camera=smgr->addCameraSceneNodeFPS(0,100,500,-1,controls,5);
	camera->setPosition(vector3df(0,100,0));
	camera->setFarValue(12000.0f);
	driver->makeColorKeyTexture(driver->getTexture("data/aim.bmp"),SColor(0,0,0,0));
    info=guienv->addStaticText(L"a ",rect<s32>(0,0,220,180),true,true,0,-1,true);
    listbox = guienv->addListBox(rect<s32>(700, 600, 1004, 710),0,-1,true); //HERE IS THE lISTBOX INIT
	editbox=guienv->addEditBox(L"Edit Box?",rect<s32>(700,720,900,780),true);

}

void CGame::showStats() {
	IGUIFont *font=device->getGUIEnvironment()->getFont("arial.bmp");
	guienv->getSkin()->setFont(font);
	FPS=driver->getFPS();
	screenWidth=driver->getScreenSize().Width;
	screenHeight=driver->getScreenSize().Height;
	maxprimitive=driver->getMaximalPrimitiveCount();
	primitivecount=driver->getPrimitiveCountDrawn();
	materialcount=driver->getMaterialRendererCount();
	dynamiclightcount=driver->getDynamicLightCount();
	referencecount=driver->getReferenceCount();
    stringw gameData;
	gameData=L"FPS: ";
	gameData+=FPS;
	gameData+=L"\n";
	gameData+=L"Resolution:";
	gameData+=L"\nWidth->";
	gameData+=screenWidth;
	gameData+=L"\nHeight->";
	gameData+=screenHeight;
	gameData+=L"\nCounts:\n";
	gameData+=L"Max Primitive count->";
	gameData+=maxprimitive;
	gameData+="\nPrimitive count->";
	gameData+=primitivecount;
	gameData+="\nMaterial count->";
	gameData+=materialcount;
	gameData+="\nDynamic light count->";
	gameData+=dynamiclightcount;
	gameData+="\nReference count->";
	gameData+=referencecount;
	aim=guienv->addImage(driver->getTexture("data/aim.bmp"),screen_center);
	aim->setColor(SColor(150,255,255,255));
	info->setText(gameData.c_str()); //I USED SETTEXT
	
}


int CGame::takeScreenshot() {
		time_t Now;
        time(&Now);
        strftime(screenshotName, 32, "screenshot/%Y%m%d-%H%M%S.jpg", localtime(&Now));
		screenshot=driver->createScreenShot();
		if(!screenshot) return 0;
		driver->writeImageToFile(screenshot,screenshotName);
		screenshot->drop();
		return 1;

}

void CGame::drawOnRun() {
	showStats();
}


Image[/code]

As you see, there is no "Screenshot taken.." text in box, even though I put function to add text in box before screenshot function in F9 case,
I see "Screenshot taken.." ingame, but I don't see it in screenshot image for some reason, why is that?
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

the problem why you can't see the text in the screen shots is simply because there is no update between setting the text and taking the screen shot... ;)
so you still have the old screen (before setting the text)...
the new text is only shown after the guienv->drawAll(); statement...
but this statement is not executed between setText and takeScreenshot... ;)

the problem with the FPS seems to depend on this line in showStats():

Code: Select all

 aim=guienv->addImage(driver->getTexture("data/aim.bmp"),screen_center);
you create/add a new image everytime the showStats() function is called, so you'll get 100s or even 1000s of images after a short time !!!
I think you should remove the old image before adding a new one... ;)

EDIT: oh wait, this image is always the same, so move the functions (addImage and its setColor function) to the Initialize() function too (like the addEditBox and addListBox functions) !!!
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
systat
Posts: 41
Joined: Mon Jan 07, 2008 8:01 pm

Post by systat »

Thanks once again Acki, I added drawAll function between setText and takeScreenshot in F9 case, I hope that it wouldn't slow the game...

And one more question, because I don't want to open new thread, why when I am far away from some hill, it looks like a triangle, it doesn't have it smooth shape, and as I am closer to it, the shape is starting to get right.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

systat wrote:Thanks once again Acki, I added drawAll function between setText and takeScreenshot in F9 case, I hope that it wouldn't slow the game...
remember the drawAll function is not enough, you'll have to do it like in the main loop (driver->beginScene - smgr->drawAll - guienv->drawAll - driver->endScene)... ;)
systat wrote:And one more question, because I don't want to open new thread, why when I am far away from some hill, it looks like a triangle, it doesn't have it smooth shape, and as I am closer to it, the shape is starting to get right.
probably because of the terrain's LOD (level of detail)...
that means: the farther away the lesser vertices are used (for performance)... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Post Reply