Problem with a custom scene node

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Manawenuz
Posts: 22
Joined: Wed Jun 10, 2009 12:42 am
Location: France

Problem with a custom scene node

Post by Manawenuz »

Hello,

I am trying to make a custom scene node, and I would like to texture it. But no way, it just doesn't work. Here is the code:

Code: Select all

class CrosshairSceneNode : public ISceneNode {
protected:
	aabbox3d<f32> Box;
	S3DVertex Vertices[4];
	SMaterial Material;
public:
	CrosshairSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) : ISceneNode(parent, mgr, id) {
		Material.Wireframe = false;
		Material.Lighting = false;
		SColor col(0,255,255,255);
		Vertices[0] = S3DVertex(-1,1,5, 1,1,0, col, 0, 1);
		Vertices[1] = S3DVertex(1,1,5, 1,0,0, col, 1, 1);
		Vertices[2] = S3DVertex(1,-1,5, 0,1,1, col, 1, 0);
		Vertices[3] = S3DVertex(-1,-1,5, 0,0,1, col, 0, 0);
		
		this->setAutomaticCulling(EAC_OFF);
		Box.reset(Vertices[0].Pos);
		for (s32 i=1; i<4; ++i)
			Box.addInternalPoint(Vertices[i].Pos);
	}
	
	virtual void OnRegisterSceneNode()
	{
		if (IsVisible)
			SceneManager->registerNodeForRendering(this);
		
		ISceneNode::OnRegisterSceneNode();
	}
	
	virtual void render()
	{
		u16 indices[] = {0,1,2, 0,2,3};
		IVideoDriver* driver = SceneManager->getVideoDriver();
		
		driver->setMaterial(Material);
		driver->setTransform(ETS_WORLD, AbsoluteTransformation);
		driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 2);
	}
	
	virtual const core::aabbox3d<f32>& getBoundingBox() const
	{
		return Box;
	}
	
	virtual u32 getMaterialCount() const
	{
		return 1;
	}
	
	virtual video::SMaterial& getMaterial(u32 i)
	{
		return Material;
	}
	
	void setMaterialTexture(u32 textureLayer, video::ITexture* texture) {
		if (textureLayer >= video::MATERIAL_MAX_TEXTURES)
			return;
		for (u32 i=0; i<getMaterialCount(); ++i)
			getMaterial(i).setTexture(textureLayer, texture);
	}
};
I've looked here, but doing the same for setMaterialTexture doesn't seem to be enough.

Could you help me? Thanks!
Last edited by Manawenuz on Sat Dec 19, 2009 3:55 pm, edited 1 time in total.
Escen
Competition winner
Posts: 167
Joined: Sun Jul 19, 2009 11:27 am
Location: the Netherlands
Contact:

Post by Escen »

You have made 2 indices[] = {0,1,2, 0,2,3} and ask to draw 4 , it may crash on that.
replace with:

Code: Select all

driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 2);
It should work applied as follow:

Code: Select all

video::ITexture *Tex1;
    Tex1=driver->getTexture("../../media/detailmap3.jpg");
    myNode->setMaterialTexture(0,Tex1);
Manawenuz
Posts: 22
Joined: Wed Jun 10, 2009 12:42 am
Location: France

Post by Manawenuz »

Thanks for the answer!!

Changing this line

Code: Select all

driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 2);
has solved display bug, but now I still have a big white square in front of me (no texture mapped). But I can see in the terminal that the texture (crosshair.png) has been loaded, even if type this

Code: Select all

video::ITexture *Tex1; 
    Tex1=driver->getTexture("../../media/detailmap3.jpg"); 
    myNode->setMaterialTexture(0,Tex1);
I have also tried billboards, but I have exactly the same problem.
I really don't know what to do...

BTW, I'd prefer using a custom scene node, unless you can rotate a billboard around the target axis of the camera
Manawenuz
Posts: 22
Joined: Wed Jun 10, 2009 12:42 am
Location: France

Post by Manawenuz »

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

Post by CuteAlien »

I miss the time right now to write an example around this to test it (note that you get more responses when you paste stuff which people can just compile without having to invest some work first). But check 2 things - do you have a camera and do you actually render the scene? That's often forgotten.
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
Escen
Competition winner
Posts: 167
Joined: Sun Jul 19, 2009 11:27 am
Location: the Netherlands
Contact:

Post by Escen »

This is your class applied in the basic CostumSceneNode example.
I tweak your Vertices a little-bit, but if it is still not working you have to give more information.

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;
using namespace scene;
using namespace video;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif


class CrosshairSceneNode : public scene::ISceneNode
{
protected:
   core::aabbox3d<f32> Box;
   video::S3DVertex Vertices[4];
   video::SMaterial Material;
public:
   CrosshairSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) : ISceneNode(parent, mgr, id) {
      Material.Wireframe = false;
      Material.Lighting = false;
      SColor col(0,255,255,255);
      Vertices[0] = S3DVertex(0,0,0, 0,0,0, col, 0, 1);
      Vertices[1] = S3DVertex(0,10,0, 0,1,0, col, 0, 0);
      Vertices[2] = S3DVertex(15,10,0, 1,1,0, col, 1, 0);
      Vertices[3] = S3DVertex(15,0,0, 1,0,0, col, 1, 1);
      this->setAutomaticCulling(EAC_OFF);
      Box.reset(Vertices[0].Pos);
      for (s32 i=1; i<4; ++i)
         Box.addInternalPoint(Vertices[i].Pos);
   }

   virtual void OnRegisterSceneNode()
   {
      if (IsVisible)
         SceneManager->registerNodeForRendering(this);

      ISceneNode::OnRegisterSceneNode();
   }

   virtual void render()
   {
       u16 indices[] = {0,1,3, 1,2,3};
      IVideoDriver* driver = SceneManager->getVideoDriver();

      driver->setMaterial(Material);
      driver->setTransform(ETS_WORLD, AbsoluteTransformation);
      driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 2);
   }

   virtual const core::aabbox3d<f32>& getBoundingBox() const
   {
      return Box;
   }

   virtual u32 getMaterialCount() const
   {
      return 1;
   }

   virtual video::SMaterial& getMaterial(u32 i)
   {
      return Material;
   }

   void setMaterialTexture(u32 textureLayer, video::ITexture* texture) {
      if (textureLayer >= video::MATERIAL_MAX_TEXTURES)
         return;
      for (u32 i=0; i<getMaterialCount(); ++i)
         getMaterial(i).setTexture(textureLayer, texture);
   }
};


int main()
{
	// let user select driver type

	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 0;
	}

	// create device

	IrrlichtDevice *device = createDevice(driverType,
			core::dimension2d<u32>(640, 480), 16, false);

	if (device == 0)
		return 1; // could not create selected driver.

	// create engine and camera

	device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo");

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

        ICameraSceneNode* camera =smgr->addCameraSceneNodeFPS(0,50, 0.1, -1, 0, 1,false);
        camera->setPosition(core::vector3df(0,0,-40));


	//YOUR CLASS IS ABOUT TO FIRE HERE
	CrosshairSceneNode *myNode =
		new CrosshairSceneNode(smgr->getRootSceneNode(), smgr, 666);

    video::ITexture *Tex1;
    Tex1=driver->getTexture("../../media/detailmap3.jpg");
    myNode->setMaterialTexture(0,Tex1);

	myNode->drop();
	myNode = 0;
    //WOW that was amazing

	u32 frames=0;
	while(device->run())
	{
		driver->beginScene(true, true, video::SColor(0,100,100,100));

		smgr->drawAll();

		driver->endScene();
		if (++frames==100)
		{
			core::stringw str = L"Irrlicht Engine [";
			str += driver->getName();
			str += L"] FPS: ";
			str += (s32)driver->getFPS();

			device->setWindowCaption(str.c_str());
			frames=0;
		}
	}

	device->drop();

	return 0;
}
Manawenuz
Posts: 22
Joined: Wed Jun 10, 2009 12:42 am
Location: France

Post by Manawenuz »

Thank you very much for your answer!
Is this working for you? For me it doesn't and I really don't understand why... I have a white rectangle in front of me, without a texture, whereas it is said to be loaded in the terminal.
I use OpenGL, I am under Mac OS X Snow Leopard, with Irrlicht v1.5.2-SVN...
I try with a newer version and I tell what happens

EDIT: Well, same problem with Irrlicht 1.6 (if you need to know, it is XCode 3.2.1)
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Hm, above code is also working for me. Unfortunately I have no Mac to test it there :-(
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
Manawenuz
Posts: 22
Joined: Wed Jun 10, 2009 12:42 am
Location: France

Post by Manawenuz »

I am sad to announce you that it works on Ubuntu 9.10 (double boot).
So the problem is Mac OS X (I hoped I would never have to say it, but...)
If somebody has an idea about why it doesn't work...
Manawenuz
Posts: 22
Joined: Wed Jun 10, 2009 12:42 am
Location: France

Post by Manawenuz »

I am not sure of the answer, so I ask here:
According to you, should I create a new topic to deal with this mac-specific problem?
Escen
Competition winner
Posts: 167
Joined: Sun Jul 19, 2009 11:27 am
Location: the Netherlands
Contact:

Post by Escen »

Well... that's well done! lucky you.. :wink:
Unfortunately I also have no Mac test it :cry:

A new topic will reach more Mac users, I think.
Maybe you can use the code from above and place a link to this topic.

Cheers
Post Reply