QuadTree class

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
Quantum1982
Posts: 45
Joined: Mon Apr 23, 2012 9:31 am

QuadTree class

Post by Quantum1982 »

Hi

I am creating a quadtree for the first time with some drawing and classifying of objects. I am getting an access violation error with the driver variable.
I am new to this so the class is not complete, but what am I missing ?

Code: Select all

 
 
    #include <irrlicht.h>
    #include "driverChoice.h"
        #include "EventLogger.h"
     
    using namespace irr;
     
        #define LOG_TESTCLASS   LOG_COLOR_RED | LOG_BOLD
        #define LOG_TESTFN              LOG_COLOR_DK_BLUE | LOG_ITALICS | LOG_UNDERLINE
 
    #ifdef _MSC_VER
    #pragma comment(lib, "Irrlicht.lib")
    #endif
     
    enum
    {
            MAZE_X1 = 40,
            MAZE_Y1 = 20,
            XBlocks = 20,
            YBlocks = 20,
            BlockWidth = (480-MAZE_Y1)/XBlocks,
                        //BlockWidth = 100,
                        Depth = 20,
    };
    
    class CHuman
    {
    public:
            CHuman(void);
            int iX, iY;
                        float xVel,yVel;
                        float fPosX, fPosY;
                        bool bHasTarget;
                        int xTarget, yTarget;
                        int xDir, yDir;
     
            void Draw(video::IVideoDriver* driver,irr::video::SColor color = irr::video::SColor(255,255,255,255));
           
            void Update(SEvent& event);
    };
     
    CHuman::CHuman(void)
    {
            iX = 0;
            iY = 0;
                        xVel = 0.0;
                        yVel = 0.0;
                        bHasTarget=false;
                        xTarget=0;
                        yTarget=0;
        }
    void CHuman::Draw(video::IVideoDriver* driver,irr::video::SColor color)
    {
            driver->draw2DRectangle(color,irr::core::rect<irr::s32>(fPosX+2,fPosY+2,
                    fPosX+BlockWidth-2,fPosY+BlockWidth-2));
    }
    void CHuman::Update(SEvent& event)
    {
           
    }
    class CAlien
    {
    public:
            CAlien(void);
            int iX, iY;
     
            void Update(int iHumanX,int iHumanY);
            void Draw(video::IVideoDriver* driver,irr::video::SColor color = irr::video::SColor(255,255,255,255));
           
    };
    CAlien::CAlien(void)
    {
            iX = 0;
            iY = 0;
    }
    void CAlien::Update(int iHumanX,int iHumanY)
    {
                 
    }
    void CAlien::Draw(video::IVideoDriver* driver,irr::video::SColor color)
    {
            driver->draw2DRectangle(color,irr::core::rect<irr::s32>(MAZE_X1+iX*BlockWidth+2,MAZE_Y1+iY*BlockWidth+2,
                    MAZE_X1+(iX+1)*BlockWidth-2,MAZE_Y1+(iY+1)*BlockWidth-2));
    }
     
    
    CHuman Human; // global player
    CAlien Alien; // global alien
    
class MyEventReceiver : public IEventReceiver
{
public:
        irr::EKEY_CODE MyKey;
        // This is the one method that we have to implement
        virtual bool OnEvent(const SEvent& event)
        {
                //MyKey = KEY_KEY_0;
                // Remember whether each key is down or up
                if (event.EventType == irr::EET_KEY_INPUT_EVENT)
                {
                        //MyKey = event.KeyInput.Key; // get this key
                        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
                        KeyIsUp[event.KeyInput.Key] = event.KeyInput.PressedDown;
                }
                
                return false;
        }
        
        // This is used to check whether a key is being held down
        virtual bool IsKeyDown(EKEY_CODE keyCode) const
        {
                return KeyIsDown[keyCode];
        }
        virtual bool IsKeyUp(EKEY_CODE keyCode) const
        {
                return KeyIsUp[keyCode];
        }
        
        MyEventReceiver()
        {
                for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
                {
                        KeyIsDown[i] = false;
                        KeyIsUp[i] = false;
                } 
        }
        
 
private:
        // We use this array to store the current state of each key
        bool KeyIsDown[KEY_KEY_CODES_COUNT];
        bool KeyIsUp[KEY_KEY_CODES_COUNT];
}; 
        
class CQuadTree
{
public:
        CQuadTree(void);
        void Draw(video::IVideoDriver* driver);
        void CreateChildren(void);
        int X1,Y1,X2,Y2; // bounds
        int iSize;
 
 
        CQuadTree* parent, *NW,*NE,*SW,*SE;
        
};
 
CQuadTree::CQuadTree(void)
{
}
void CQuadTree::Draw(video::IVideoDriver* driver)
{
        driver->draw2DRectangleOutline(irr::core::recti(X1,Y1,X2,Y2),irr::video::SColor(255,0,255,0));
 
        //if (NW)
        //      NW->Draw(driver);
 
}
 
void CQuadTree::CreateChildren(void)
{
        NW = new CQuadTree();
        NW ->iSize = iSize/2;
        NW ->X1 = X1;
        NW ->Y1 = Y1;
        NW -> X2 = X1+NW->iSize;
        NW -> Y2 = Y1+NW->iSize;
 
        NE = new CQuadTree();
        NE ->iSize = iSize/2;
        NE ->X1 = X1+NW->iSize;
        NE ->Y1 = Y1;
        NE -> X2 = NE->X1+NE->iSize;
        NE -> Y2 = NE->Y1+NE->iSize;
 
        SW = new CQuadTree();
        SW ->iSize = iSize/2;
        SW ->X1 = X1;
        SW ->Y1 = Y1+SW->iSize;
        SW -> X2 = X1+SW->iSize;
        SW -> Y2 = SW->Y1+SW->iSize;
 
        SE = new CQuadTree();
        SE ->iSize = iSize/2;
        SE ->X1 = X1+SE->iSize;
        SE ->Y1 = Y1+SE->iSize;
        SE -> X2 = SE->X1+SE->iSize;
        SE -> Y2 = SE->Y1+SE->iSize;
}
int main()
{
        
        // ask user for driver
        video::E_DRIVER_TYPE driverType=driverChoiceConsole();
        if (driverType==video::EDT_COUNT)
                return 1;
 
        MyEventReceiver receiver;
 
        IrrlichtDevice* device = createDevice(driverType,
                        core::dimension2d<u32>(640, 480), 16, false, false, false, &receiver);
        
        if (device == 0)
                return 1; // could not create selected driver.
 
        video::IVideoDriver* driver = device->getVideoDriver();
        scene::ISceneManager* smgr = device->getSceneManager();
        gui::IGUIEnvironment* env = device->getGUIEnvironment();
        
        
 
        Human.fPosX = MAZE_X1+Human.iX*BlockWidth;
        Human.fPosY = MAZE_Y1+Human.iY*BlockWidth;
        int iNewX,iNewY;
        
        video::ITexture* cheese = driver->getTexture("../../media/cheese.png");
        driver->makeColorKeyTexture(cheese, core::position2d<s32>(0,0));
 
        video::ITexture* mouse = driver->getTexture("../../media/mouse.png");
        driver->makeColorKeyTexture(mouse, core::position2d<s32>(0,0));
 
        core::rect<s32> cheese_rect(0,0,20,20);
        core::rect<s32> mouse_rect(0,0,20,20);
 
        gui::IGUIFont* font = device->getGUIEnvironment()->getBuiltInFont();
        
        irr::core::stringw str;
 
        CQuadTree QuadTree;
        CQuadTree* Current;
 
        QuadTree.iSize = 400;
        QuadTree.X1 = 200;
        QuadTree.Y1 = 50;
        QuadTree.X2 = QuadTree.X1+QuadTree.iSize;
        QuadTree.Y2 = QuadTree.Y1+QuadTree.iSize;
        //QuadTree.CreateChildren();
 
        Current = &QuadTree;
 
        for (int i=0;i<4;i++)
        {
                Current->CreateChildren();
                Current = Current->NW;
        }
 
        while(device->run())
        if (device->isWindowActive())
        {
                driver->beginScene(true, true, irr::video::SColor(255,255,255,255) );
 
                
                while (Current!=0)
                {
                        Current->Draw(driver);
                        Current = Current->NW;
                }
                
 
                driver->endScene();
        }
 
        device->drop();
        
        return 0;
}
 
 
 
Cheers
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: QuadTree class

Post by CuteAlien »

Please try a little more before asking for help. First you haven't even told us _where_ it crashes - so no way for us to see this quickly without having to compile stuff.
And next - when you are hunting bugs and have no idea what's going on then reduce your code. Do you really need all that alien and human code to reproduce your bug or did you just throw it in for fun to confuse us? If you're too lazy to reduce your code to the minium there's not so much motiviation hunting for it for others as reading and understanding code usually takes way longer (and also shows you didn't really try much yourself yet). Also it's a good habit to get into - no matter how experienced you are, you will always have to find bugs in large programs and removing everything that doesn't crash is one technique you will need over and over when bughunting. So good idea starting to do that with simple examples like this one.

Also my first hint would be - check pointers for images, maybe they are not found.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: QuadTree class

Post by zerochen »

maybe your media cant be loaded? also i think that getBuiltInFont() doesnt work and is isnt needed in your programm
both just a guess.
Quantum1982
Posts: 45
Joined: Mon Apr 23, 2012 9:31 am

Re: QuadTree class

Post by Quantum1982 »

Thanks for the reply

Like I said in my post, "I am getting an access violation error with the driver variable". The reason I included all the code is because I assumed that it would be easy to compile. But to try and isolate the problem the yellow arrow points to this :

Code: Select all

 
void CQuadTree::Draw(video::IVideoDriver* driver)
{
        driver->draw2DRectangleOutline(irr::core::recti(X1,Y1,X2,Y2),irr::video::SColor(255,0,255,0));
 
        //if (NW)
        //      NW->Draw(driver);
 
}
 
It points to the driver variable, which means either that it's null or something.

In the console, it says :

First-chance exception at 0x00fe1ad4 in Marbles_2D.exe: 0xC0000005: Access violation reading location 0xcdcdcdd9.
Unhandled exception at 0x00fe1ad4 in Marbles_2D.exe: 0xC0000005: Access violation reading location 0xcdcdcdd9.

I will try and restructure the code a bit

Cheers
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: QuadTree class

Post by smso »

Try:

make clean
make

if you are using linux.

Regards
smso
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: QuadTree class

Post by CuteAlien »

Ah ok - easy. The reason is that you do not initialize your member-variables. parent, NW, NE, SW, SE - all those have random values. Always initialize every pointer in your constructor (preferably in the intializer list). So your while (Current!=0) will not work because you never actually set NW to 0.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Quantum1982
Posts: 45
Joined: Mon Apr 23, 2012 9:31 am

Re: QuadTree class

Post by Quantum1982 »

Thanks for the help. I managed to get rid of that error, the program runs, but the problem now is that it doesn't draw anything ??

Code: Select all

 
 
    #include <irrlicht.h>
    #include "driverChoice.h"
        #include "EventLogger.h"
     
    using namespace irr;
     
        #define LOG_TESTCLASS   LOG_COLOR_RED | LOG_BOLD
        #define LOG_TESTFN              LOG_COLOR_DK_BLUE | LOG_ITALICS | LOG_UNDERLINE
 
    #ifdef _MSC_VER
    #pragma comment(lib, "Irrlicht.lib")
    #endif
     
    enum
    {
            MAZE_X1 = 40,
            MAZE_Y1 = 20,
            XBlocks = 20,
            YBlocks = 20,
            BlockWidth = (480-MAZE_Y1)/XBlocks,
                        //BlockWidth = 100,
                        Depth = 20,
    };
    
    class CHuman
    {
    public:
            CHuman(void);
            int iX, iY;
                        float xVel,yVel;
                        float fPosX, fPosY;
                        bool bHasTarget;
                        int xTarget, yTarget;
                        int xDir, yDir;
     
            void Draw(video::IVideoDriver* driver,irr::video::SColor color = irr::video::SColor(255,255,255,255));
           
            void Update(SEvent& event);
    };
     
    CHuman::CHuman(void)
    {
            iX = 0;
            iY = 0;
                        xVel = 0.0;
                        yVel = 0.0;
                        bHasTarget=false;
                        xTarget=0;
                        yTarget=0;
        }
    void CHuman::Draw(video::IVideoDriver* driver,irr::video::SColor color)
    {
            driver->draw2DRectangle(color,irr::core::rect<irr::s32>(fPosX+2,fPosY+2,
                    fPosX+BlockWidth-2,fPosY+BlockWidth-2));
    }
    void CHuman::Update(SEvent& event)
    {
           
    }
    class CAlien
    {
    public:
            CAlien(void);
            int iX, iY;
     
            void Update(int iHumanX,int iHumanY);
            void Draw(video::IVideoDriver* driver,irr::video::SColor color = irr::video::SColor(255,255,255,255));
           
    };
    CAlien::CAlien(void)
    {
            iX = 0;
            iY = 0;
    }
    void CAlien::Update(int iHumanX,int iHumanY)
    {
                 
    }
    void CAlien::Draw(video::IVideoDriver* driver,irr::video::SColor color)
    {
            driver->draw2DRectangle(color,irr::core::rect<irr::s32>(MAZE_X1+iX*BlockWidth+2,MAZE_Y1+iY*BlockWidth+2,
                    MAZE_X1+(iX+1)*BlockWidth-2,MAZE_Y1+(iY+1)*BlockWidth-2));
    }
     
    
    CHuman Human; // global player
    CAlien Alien; // global alien
    
class MyEventReceiver : public IEventReceiver
{
public:
        irr::EKEY_CODE MyKey;
        // This is the one method that we have to implement
        virtual bool OnEvent(const SEvent& event)
        {
                //MyKey = KEY_KEY_0;
                // Remember whether each key is down or up
                if (event.EventType == irr::EET_KEY_INPUT_EVENT)
                {
                        //MyKey = event.KeyInput.Key; // get this key
                        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
                        KeyIsUp[event.KeyInput.Key] = event.KeyInput.PressedDown;
                }
                
                return false;
        }
        
        // This is used to check whether a key is being held down
        virtual bool IsKeyDown(EKEY_CODE keyCode) const
        {
                return KeyIsDown[keyCode];
        }
        virtual bool IsKeyUp(EKEY_CODE keyCode) const
        {
                return KeyIsUp[keyCode];
        }
        
        MyEventReceiver()
        {
                for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
                {
                        KeyIsDown[i] = false;
                        KeyIsUp[i] = false;
                } 
        }
        
 
private:
        // We use this array to store the current state of each key
        bool KeyIsDown[KEY_KEY_CODES_COUNT];
        bool KeyIsUp[KEY_KEY_CODES_COUNT];
}; 
        
class CQuadTree
{
public:
        CQuadTree(void);
        void Draw(video::IVideoDriver* driver);
        void CreateChildren(void);
        int X1,Y1,X2,Y2; // bounds
        int iSize;
 
 
        CQuadTree* parent;
        CQuadTree  *NW,*NE,*SW,*SE;
        
};
 
CQuadTree::CQuadTree(void)
{
        NW = 0;
        NE = 0;
        SW = 0;
        SE = 0;
}
void CQuadTree::Draw(video::IVideoDriver* driver)
{
        driver->draw2DRectangleOutline(irr::core::recti(X1,Y1,X2,Y2),irr::video::SColor(255,0,255,255));
 
        //if (NW)
        //      NW->Draw(driver);
 
}
 
void CQuadTree::CreateChildren(void)
{
        NW = new CQuadTree();
        NW ->iSize = iSize/2;
        NW ->X1 = X1;
        NW ->Y1 = Y1;
        NW -> X2 = X1+NW->iSize;
        NW -> Y2 = Y1+NW->iSize;
 
        NE = new CQuadTree();
        NE ->iSize = iSize/2;
        NE ->X1 = X1+NW->iSize;
        NE ->Y1 = Y1;
        NE -> X2 = NE->X1+NE->iSize;
        NE -> Y2 = NE->Y1+NE->iSize;
 
        SW = new CQuadTree();
        SW ->iSize = iSize/2;
        SW ->X1 = X1;
        SW ->Y1 = Y1+SW->iSize;
        SW -> X2 = X1+SW->iSize;
        SW -> Y2 = SW->Y1+SW->iSize;
 
        SE = new CQuadTree();
        SE ->iSize = iSize/2;
        SE ->X1 = X1+SE->iSize;
        SE ->Y1 = Y1+SE->iSize;
        SE -> X2 = SE->X1+SE->iSize;
        SE -> Y2 = SE->Y1+SE->iSize;
}
int main()
{
        
        // ask user for driver
        video::E_DRIVER_TYPE driverType=driverChoiceConsole();
        if (driverType==video::EDT_COUNT)
                return 1;
 
        MyEventReceiver receiver;
 
        IrrlichtDevice* device = createDevice(driverType,
                        core::dimension2d<u32>(640, 480), 16, false, false, false, &receiver);
        
        if (device == 0)
                return 1; // could not create selected driver.
 
        video::IVideoDriver* driver = device->getVideoDriver();
        scene::ISceneManager* smgr = device->getSceneManager();
        gui::IGUIEnvironment* env = device->getGUIEnvironment();
        
        Human.fPosX = MAZE_X1+Human.iX*BlockWidth;
        Human.fPosY = MAZE_Y1+Human.iY*BlockWidth;
        int iNewX,iNewY;
        
        video::ITexture* cheese = driver->getTexture("../../media/cheese.png");
        driver->makeColorKeyTexture(cheese, core::position2d<s32>(0,0));
 
        video::ITexture* mouse = driver->getTexture("../../media/mouse.png");
        driver->makeColorKeyTexture(mouse, core::position2d<s32>(0,0));
 
        core::rect<s32> cheese_rect(0,0,20,20);
        core::rect<s32> mouse_rect(0,0,20,20);
 
        gui::IGUIFont* font = device->getGUIEnvironment()->getBuiltInFont();
        
        irr::core::stringw str;
 
        CQuadTree QuadTree;
        CQuadTree* Current;
 
        QuadTree.iSize = 400;
        QuadTree.X1 = 200;
        QuadTree.Y1 = 50;
        QuadTree.X2 = QuadTree.X1+QuadTree.iSize;
        QuadTree.Y2 = QuadTree.Y1+QuadTree.iSize;
        //QuadTree.CreateChildren();
 
        Current = &QuadTree;
 
        for (int i=0;i<4;i++)
        {
                Current->CreateChildren();
                /*
                Current->NW = new CQuadTree();
                Current->NE = new CQuadTree();
                Current->SW = new CQuadTree();
                Current->SE = new CQuadTree();
                */
                Current->NW->CreateChildren();
                Current->NE->CreateChildren();
                Current->SW->CreateChildren();
                Current->SE->CreateChildren();
 
                Current = Current->NW;
                
        }
 
        Current = &QuadTree;
        while(device->run())
        if (device->isWindowActive())
        {
                driver->beginScene(true, true, irr::video::SColor(255,255,255,255) );   
                
                while (Current!=0)
                {
                        Current->Draw(driver);
                        Current = Current->NW;
                }
                
                driver->endScene();
        }
 
        device->drop();
        
        return 0;
}
 
 
 
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: QuadTree class

Post by CuteAlien »

Set the driver transformation first:

Code: Select all

 
driver->setTransform(video::ETS_WORLD, core::matrix4());
 
Also maybe set a material as well with lighting false:

Code: Select all

 
SMaterial material;
material.Lighting = false;
driver->setMaterial(material);
 
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply