should bevirtual s32 getMaterialCount()
{
return 1;
}
with irrlicht-1.3.1 because it produces errors otherwise.virtual u32 getMaterialCount()
{
return 1;
}
should bevirtual s32 getMaterialCount()
{
return 1;
}
with irrlicht-1.3.1 because it produces errors otherwise.virtual u32 getMaterialCount()
{
return 1;
}
Code: Select all
#include <irrlicht/Irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
class CMySampleSceneNode : public ISceneNode
{
public:
CMySampleSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id)
: ISceneNode(parent, mgr, id)
{
driver = SceneManager->getVideoDriver();
Material.Wireframe = false;
Material.Lighting = false;
Material.BackfaceCulling = false;
Vertices[0] = S3DVertex(0,0,10, 1,1,0, SColor(255,255,0,0), 0,1);
Vertices[1] = S3DVertex(5,10,0, 1,0,0, SColor(255,0,255,0), 1,1);
Vertices[2] = S3DVertex(0,0,0, 0,1,1, SColor(255,0,0,255), 1,0);
Vertices[3] = S3DVertex(-5,10,0, 0,0,1, SColor(255,0,0,0), 0,0);
Box.reset(Vertices[0].Pos);
for (s32 i = 0; i < 4; i++)
Box.addInternalPoint(Vertices[i].Pos);
}
virtual void OnRegisterSceneNode()
{
if (IsVisible)
ISceneNode::OnRegisterSceneNode();
}
virtual void OnAnimate(u32 timeMs)
{
ISceneNode::OnAnimate(timeMs);
}
virtual void render()
{
u16 indices[] = {0,2,3, 2,1,3, 1,0,3, 2,0,1};
driver->setMaterial(Material);
driver->setTransform(ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 4);
}
virtual const aabbox3d<f32>& getBoundingBox() const
{
return Box;
}
virtual u32 getMaterialCount()
{
return 1;
}
virtual SMaterial& getMaterial(s32 i)
{
return Material;
}
private:
aabbox3d<f32> Box;
S3DVertex Vertices[4];
SMaterial Material;
IVideoDriver *driver;
};
int main()
{
IrrlichtDevice* device = createDevice(
EDT_OPENGL,
dimension2d<s32>(640,480),
32,
false,
false,
false,
0);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
device->setWindowCaption(L"Irrlicht Custom Scene Node!");
smgr->addCameraSceneNode(0, vector3df(0,-30,0), vector3df(0,0,0));
CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(), smgr, 2);
ISceneNodeAnimator* anim = smgr->createRotationAnimator(vector3df(0.8f, 0, 0.8f));
myNode->drop();
myNode->addAnimator(anim);
anim->drop();
while(device->run() && device->isWindowActive()) {
driver->beginScene(true, true, SColor(0,255,255,255));
myNode->render();
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Code: Select all
// create an instance of our custom node
CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(), smgr, 2);
ISceneNodeAnimator* anim = smgr->createRotationAnimator(vector3df(0.8f, 0, 0.8f));
myNode->drop(); <<<<<<<<<<<<<<???
myNode->addAnimator(anim);
anim->drop();
Code: Select all
1. // create a new object based on our custom node and put a pointer to it in myNode
2. CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(), smgr, 2);
3.
4. ISceneNodeAnimator* anim = smgr->createRotationAnimator(vector3df(0.8f, 0, 0.8f));
5. myNode->drop();
6. myNode->addAnimator(anim);
7. anim->drop();
It will work, but it's not quite right. After you've called drop() on an object, you shouldn't refer to that object again; it's not safe to assume that it still exists.ultramedia wrote:1. Is this right?Code: Select all
1. // create a new object based on our custom node and put a pointer to it in myNode 2. CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(), smgr, 2); 3. 4. ISceneNodeAnimator* anim = smgr->createRotationAnimator(vector3df(0.8f, 0, 0.8f)); 5. myNode->drop(); 6. myNode->addAnimator(anim); 7. anim->drop();
Code: Select all
CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(), smgr, 2);
ISceneNodeAnimator* anim = smgr->createRotationAnimator(vector3df(0.8f, 0, 0.8f));
if(anim)
{
myNode->addAnimator(anim);
myNode->drop();
anim->drop();
}
It's a pointer. The language here is going to get tricky, so hold onto your thesaurus.2. I understand that an object has been created here, and that myNode is a reference/pointer to it
OK, anim is created with a reference count of 1. When you add it to myNode(), myNode should take a reference to it, increasing its reference count to 2. Calling drop() will decrease it back to 1 again, which is where you want it to be. If something goes wrong when adding it to myNode, then calling drop() will reduce the reference count to 0, and the object will have deleted itself, so again, after you call drop(), don't use that object again.4. Same here only with anim
We are dropping one (oh, sorry) "reference" (common English usage) to the object that the pointer points to. The pointer is still a valid pointer; it points to the same bit of memory that it did before. However, after calling drop(), the object may have deleted itself, so that memory is no longer safe to use. That's why you should never use a pointer after calling drop() on the object that it points to.5. Here I don't understand. Are we dropping the pointer or the object?
It's not safe to assume that it is available.6. Here I don't understand why myNode is still available, but I do understand the rest of the line
Yup. It was created with a reference count of 1, you added it to myNode, which takes a reference and increases it to 2, then after you drop it, it goes back to 1 and is still extant. If for some reason the myNode object failed to take a reference, then calling drop() on it would reduce its reference count to 0, and the object would delete itself. This is actually what you'd want to happen, as nothing would be referencing it.7. Same here, anim gets dropped... or does it???
Code: Select all
#define SAFE_DROP(x) do { if(x) { x->drop(); x = 0; } } while(0)
...
CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(), smgr, 2);
ISceneNodeAnimator* anim = smgr->createRotationAnimator(vector3df(0.8f, 0, 0.8f));
if(anim)
{
myNode->addAnimator(anim);
SAFE_DROP(myNode);
SAFE_DROP(anim);
}