Problem with pointers

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
Mr_Karjala
Posts: 5
Joined: Thu Jan 03, 2008 8:17 pm

Problem with pointers

Post by Mr_Karjala »

Hi everybody!

I have a small game project going on and first I have to say that this forum has been very helpfull and I thank you for it. However I guess the wall finaly came and I got stuck badly.

The problem came as I tried to organize my work, use classes and inheritance mainly. It seems that there is some problem getting the irrlicht device created in Core -class to SceneManager -class.

Idea is that Core keeps the irrlicht engine in memory and Game handles the logic of showing correct scenes and asks SceneManager to load right maps.

Code compiles but creates immediatly this error after I start debugging it:
Unhandled exception at 0x00412546 in GameAmentia.exe: 0xC0000005: Access violation reading location 0xccccccd0.

And the compiler points this part in Core -class:

//return a funtion to engine core fuctions here
IrrlichtDevice* CGameCore::getDevice()
{
return pDevice;
}


Main parts of code are here, they use some of the tutorials and code snippets posted here in forums. They work in the "spagetti" code.

You would save my day if you could help me a bit, I have a bad habit to forget something small wich causes code not to work.



Core.h

Code: Select all

#ifndef _CORE_H_
#define _CORE_H_ 

#include <irrlicht.h> 

//engine namespaces
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui; 


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
Core.cpp

Code: Select all

#include "Core.h"
#include <iostream>


CGameCore::CGameCore()
{
   InitalizeDevice();

}


CGameCore::~CGameCore()
{

}

void CGameCore::InitalizeDevice()
{
   pDevice = createDevice(EDT_DIRECT3D9, core::dimension2d<s32>(1024,768), 32, false, true, true);


   //Init engine functions and store the pointers to them
   pSceneMngr = pDevice->getSceneManager();
   pDrv = pDevice->getVideoDriver();
   pGUIEnv = pDevice->getGUIEnvironment();

}


      //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;
   } 
Game.h

Code: Select all

#ifndef _GAME_H_
#define _GAME_H_


#include <irrlicht.h>
#include "Core.h"
#include "SceneManager.h"
#include "CameraManager.h"

using namespace irr;

//! Main entry point to game
class CGame
{
public:

   CGame();

   ~CGame();

   bool run();

private:
   
   CGameCore * pManager;
   SceneManager *gameSceneManager;
   CameraManager *gameCameraManager;

};
#endif
Game.cpp

Code: Select all


#include "Game.h"


CGame::CGame()
{
	CGameCore *pManager = new CGameCore;
	gameSceneManager = new SceneManager(pManager);
	gameCameraManager = new CameraManager;

}

CGame::~CGame()
{
	delete gameSceneManager;
	delete gameCameraManager;
	delete pManager;

}

//! Main game loop
bool CGame::run()
{

// Name of game, displayed in window if windowed
pManager->getDevice()->setWindowCaption(L"some app name here");
   
int lastFPS = -1; 
 
// Keep running game loop if device exists

gameSceneManager->SceneMansion();
gameCameraManager->FirstPersonCamera();

   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;
}

SceneManager.h

Code: Select all

#ifndef _SCENEMANAGER_H_
#define _SCENEMANAGER_H_ 

#include "Core.h"
#include "irrlicht.h"

class SceneManager
{
public:
	SceneManager(CGameCore *gameCore);

	~SceneManager();

	void SceneMansion();

private:

	IrrlichtDevice *gameDevice;
	scene::ISceneManager* sm;
	scene::IQ3LevelMesh* quakeLevelMesh;
	scene::ISceneNode* quakeLevelNode;
	scene::ITriangleSelector* mapSelector;

};

#endif
SceneManager.cpp

Code: Select all

#include "SceneManager.h"


SceneManager::SceneManager(CGameCore *gameCore){


	gameDevice = gameCore->getDevice();
	sm = gameDevice->getSceneManager();
	gameDevice->getFileSystem()->addZipFileArchive("media/irrlicht.dat");
	gameDevice->getFileSystem()->addZipFileArchive("media/map-20kdm2.pk3");

}

SceneManager::~SceneManager(){}

void SceneManager::SceneMansion()
{

	quakeLevelMesh = (scene::IQ3LevelMesh*) sm->getMesh("maps/20kdm2.bsp");

	if (quakeLevelMesh)
	{
		u32 i;

		//move all quake level meshes (non-realtime)
		core::matrix4 m;
		m.setTranslation ( core::vector3df(-1300,-70,-1249) );

		for ( i = 0; i!= scene::quake3::E_Q3_MESH_SIZE; ++i )
		{
			sm->getMeshManipulator()->transformMesh ( quakeLevelMesh->getMesh(i), m );
		}

		quakeLevelNode = sm->addOctTreeSceneNode(quakeLevelMesh->getMesh( scene::quake3::E_Q3_MESH_GEOMETRY),0,20);
		if (quakeLevelNode)
		{
			//quakeLevelNode->setPosition(core::vector3df(-1300,-70,-1249));
			quakeLevelNode->setVisible(true);

			// create map triangle selector
			mapSelector = sm->createOctTreeTriangleSelector(quakeLevelMesh->getMesh(0),
				quakeLevelNode, 128);

			// if not using shader and no gamma it's better to use more lighting, because
			// quake3 level are dark
			quakeLevelNode->setMaterialType ( video::EMT_LIGHTMAP_M4 );

			// set additive blending if wanted

		}

		// the additional mesh can be quite huge and is unoptimized
		scene::IMesh * additional_mesh = quakeLevelMesh->getMesh ( scene::quake3::E_Q3_MESH_ITEMS );

		for ( i = 0; i!= additional_mesh->getMeshBufferCount (); ++i )
		{
			scene::IMeshBuffer *meshBuffer = additional_mesh->getMeshBuffer ( i );
			const video::SMaterial &material = meshBuffer->getMaterial();

			//! The ShaderIndex is stored in the material parameter
			s32 shaderIndex = (s32) material.MaterialTypeParam2;

			// the meshbuffer can be rendered without additional support, or it has no shader
			const scene::quake3::SShader *shader = quakeLevelMesh->getShader ( shaderIndex );
			if ( 0 == shader )
			{
				continue;
			}
			// Now add the MeshBuffer(s) with the current Shader to the Manager
			sm->addQuake3SceneNode ( meshBuffer, shader );
		}

		// original mesh is not needed anymore
		quakeLevelMesh->releaseMesh ( scene::quake3::E_Q3_MESH_ITEMS );

	}


}
JonLT
Posts: 152
Joined: Thu Mar 15, 2007 5:47 pm
Location: Denmark

Post by JonLT »

try changing

Code: Select all


CGame::CGame()
{
   CGameCore *pManager = new CGameCore;
   gameSceneManager = new SceneManager(pManager);
   gameCameraManager = new CameraManager;

} 
to

Code: Select all

CGame::CGame()
{
   pManager = new CGameCore;
   gameSceneManager = new SceneManager(pManager);
   gameCameraManager = new CameraManager;
}
Mr_Karjala
Posts: 5
Joined: Thu Jan 03, 2008 8:17 pm

Post by Mr_Karjala »

ok thanks for that, it removed the device error but now it complains about SceneManager. Same error message expect now it points to:

Code: Select all

   
ISceneManager* CGameCore::getSceneMngr()
   {
      return pSceneMngr;
   } 
Console shows that textures are loaded from the map before that error pops up.
Yustme
Posts: 107
Joined: Sat Dec 01, 2007 10:50 pm

Post by Yustme »

Mr_Karjala wrote:ok thanks for that, it removed the device error but now it complains about SceneManager. Same error message expect now it points to:

Code: Select all

   
ISceneManager* CGameCore::getSceneMngr()
   {
      return pSceneMngr;
   } 
Console shows that textures are loaded from the map before that error pops up.

Hi Mr_Karjala,

I haven't gone through your code completely, but try this:

Code: Select all

ISceneManager* CGameCore::getSceneMngr()
   {
      return *pSceneMngr;
   } 
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

Yustme's code won't work (creates a pointer to the pointer).

I took the code you posted above, removed all camera manager elements (as that code is missing) and applied jonlt's fix. Then I just added 2 lines to add a fps camera and load the zip file containing the map files.

Works out of the box without any problems (Irrlicht SVN 1.4). Maybe you made some mistake somewhere? Or there is some problem within the camera file(s) and/or header(s) causing that problem?
Mr_Karjala
Posts: 5
Joined: Thu Jan 03, 2008 8:17 pm

Post by Mr_Karjala »

Yeah, I found what was the problem and indeed it was the CameraManager class.

I simply forgot to remade the CameraManager class as I first tested it with camera that was defined in Core class and thus CameraManager never got a pointer to scene manager to add the fps camera. I didn't even thought that it could cause the problem but seems I was wrong.

It works now as it should work, thanks for the help everyone.

Another question though, not about the problem but overrall structure of the code. Is this kind of structure good in your opininion? I am currently university student in data processing and I am trying the methods teached there. Therefore I use managers to handle all scripts, levels, items, physics and so on.

You think this would be a good idea or should I took a different view at the architecture?
Post Reply