[solved]Something wrong with DrawMeshBuffer and camera angle

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
kidhr
Posts: 9
Joined: Fri Oct 01, 2010 5:04 pm

[solved]Something wrong with DrawMeshBuffer and camera angle

Post by kidhr »

Hello

Is this a bug ?

I am trying to make a new scene node with grass quads.
I use a HillPlaneMesh and Meshbuffers
I draw some quads in MeshBuffers with DrawMeshBuffer

When i rotate my camera with a specific angle the quads are not drawn ???
132° in my sample.

The code below is just for test

Thanks in advance

Code: Select all


#include <irrlicht.h>
#include "CGrassNode.h"

#pragma comment(lib, "Irrlicht.lib")

using namespace irr;

int main(int argc, char **argv)
{

	// irrlicht parametres
	irr::SIrrlichtCreationParameters param;
	param.DriverType = video::EDT_OPENGL;
	param.WindowSize = core::dimension2di(800,600);
	param.Fullscreen = false;
	param.Vsync = false;
	param.Bits = 16;
	param.AntiAlias = false;
	IrrlichtDevice * device = createDeviceEx(param);


    // get irr pointers
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager * smgr = device->getSceneManager();
    gui::IGUIEnvironment * guienv = device->getGUIEnvironment();

	// add camera fps
	scene::ICameraSceneNode * cam =  smgr->addCameraSceneNodeFPS(0,100,0.5f);
	cam->setFarValue(200000.0f);
	cam->setNearValue(0.1f);
	cam->setPosition(core::vector3df(45,20,35));
	cam->setTarget(core::vector3df(0,50,100));
	device->getCursorControl()->setVisible(false);

	c8 * detailMap01 = "Media/dmapgrass06.jpg";
	c8 * grassTexture = "Media/GrassBillboard.png";

	scene::IAnimatedMesh * plane = smgr->addHillPlaneMesh ("test", core::dimension2d< f32 > (10,10), core::dimension2d< u32 > (10,10), 0,0.0f, core::dimension2d< f32 >(0.0f, 0.0f),core::dimension2d< f32 > (10.0f, 10.0f)); 
	scene::ISceneNode *  planeNode = smgr->addAnimatedMeshSceneNode(plane);
    planeNode ->setPosition(core::vector3df(0,0,0));
	planeNode ->setScale(core::vector3df(10.0f,0.0f,10.0f));
    planeNode ->setMaterialTexture(0, driver->getTexture(detailMap01));
	planeNode->setMaterialFlag(EMF_LIGHTING, false); 
	planeNode->setMaterialFlag(video::EMF_BACK_FACE_CULLING,false); 

	 SGrassParameters paramGrass;

	 paramGrass.device = device;
	 paramGrass.heightMapFile = "";
	 paramGrass.invertColorMapFile = "";
	 paramGrass.grassTextureFile = grassTexture;
	 paramGrass.density = GRASS_LOW;
	 paramGrass.posMap = core::vector3df(0.0f,0.0f,0.0f);
	 paramGrass.scaleMap = core::vector3df(10.0f,0.0f,10.0f);
	 paramGrass.sizeGrass = core::dimension2df(100.0f,100.0f);
	 paramGrass.scaleGrass = core::vector3df(1.0f,1.0f,1.0f);
	 paramGrass.elevationCeil = 100.0f;
	 paramGrass.elevationFloor = 0.0f;

	 CGrassNode * grass = new CGrassNode(0, smgr, -1);
	if (!grass)
	{
		printf("Grass not Load !!!!");
		return 1;
	}
	// create grass 
	if (!grass->create(paramGrass))
	{
		printf("Grass not create!!!!");
		return 1;
	}

	grass->setMaterialFlag(video::EMF_LIGHTING, false);
	grass->setMaterialType(video::EMT_SOLID);
	grass->setMaterialFlag(video::EMF_BACK_FACE_CULLING,false); 

	//set grass texture
	if (!grass->setTexture( paramGrass.grassTextureFile))
	{
		printf("Grass texture not load!!!!");
		return 1;
	}

	// loop application
	int lastFPS = -1;
    while(device->run())
    {
		driver->beginScene();
		smgr->drawAll();
        driver->endScene();

		// show fps in title
		int fps = driver->getFPS();
		if (lastFPS != fps)
		{
			core::stringw str = driver->getName();
			str += L" FPS: ";
			str += (s32)driver->getFPS();
			str+=L" primitivecount=";
			str+=(s32)driver->getPrimitiveCountDrawn();
			str += L"   POS  X : ";
			str += cam->getAbsolutePosition().X;
			str += L" Y : ";
			str += cam->getAbsolutePosition().Y,
			str += L" Z : ";
			str += cam->getAbsolutePosition().Z;
			str += L" CameraROT Y  : ";
			str += cam->getRotation().Y;

		  device->setWindowCaption(str.c_str() );
		}
	}

    // clear device
    device->drop();

    return 0;
}

#ifndef __C_GRASS_NODE_H_INCLUDED__
#define __C_GRASS_NODE_H_INCLUDED__


#include <irrlicht.h>

using namespace irr; 
using namespace core;
using namespace scene;
using namespace video;
using namespace io;

enum E_GRASS_DENSITY
{
	GRASS_HIGH = 1000,
	GRASS_MEDIUM = 500,
	GRASS_LOW = 100,
	GRASS_EXTRALOW = 10
};

struct SGrassParameters
{
	 irr::IrrlichtDevice * device;
	 io::path heightMapFile;
	 io::path invertColorMapFile;
	 io::path grassTextureFile;
	 E_GRASS_DENSITY density;
	 core::vector3df posMap;
	 core::vector3df scaleMap;
	 core::dimension2df sizeGrass;
	 core::vector3df scaleGrass;
	 f32 elevationCeil;
	 f32 elevationFloor;
};

class CGrassNode : public  irr::scene::ISceneNode
{
public:

	//! constructor
CGrassNode(scene::ISceneNode* parent, scene::ISceneManager* smgr, s32 id);
	//destructor
	~CGrassNode();

	//! Returns the material based on the zero based index i.
	virtual video::SMaterial& getMaterial(u32 i);

	//! Returns amount of materials used by this scene node.
	virtual u32 getMaterialCount() const;

	//! pre render
	virtual void OnRegisterSceneNode();

	//! Animate the clouds
	virtual void OnAnimate(u32 timeMs);

	//! render
	virtual void render();

	//! returns the axis aligned bounding box of this node
	virtual const core::aabbox3d<f32>& getBoundingBox() const;

	//return grassmesh
	inline scene::IMesh* getMesh(){return this->_grassMesh;}

	//create the grass blades
	bool create(const SGrassParameters& SGrassParam);
	void setMaterialType(video::E_MATERIAL_TYPE Mat);
	void setMaterialFlag(video::E_MATERIAL_FLAG Mat, bool Flag);
	bool setTexture(const io::path& textureFileName);
	void setRenderDistance(f32 Distance);

private :
	/*****************************/
	/*	attributes				*/
	/*****************************/
	//irlicht
	irr::IrrlichtDevice * _device;
	irr::scene::ISceneManager* _smgr;
    irr::core::aabbox3d<irr::f32> _box;
    irr::video::SMaterial _material;
	u32 _sizeOfTile;
	u32 _nbTiles;
	f32 _renderDistance ;
	scene::SMesh* _grassMesh;
	scene::SMeshBuffer * buffer;
	/*****************************/
	/*	methods					 */
	/*****************************/
	bool getGridNbTiles(u32 size);
};


#endif  // __C_QUAD_SCENE_NODE_H_INCLUDED__


#include <irrlicht.h>
#include "CGrassNode.h"

using namespace irr; 
using namespace core;
using namespace scene;
using namespace video;
using namespace io;

//----------------------------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------------------------
CGrassNode::CGrassNode(irr::scene::ISceneNode* parent, irr::scene::ISceneManager* smgr, irr::s32 id)
								: irr::scene::ISceneNode(parent!=0? parent : smgr->getRootSceneNode(), smgr, id)
{

	_device = 0;
	_smgr = smgr;
	_sizeOfTile = 0;
	_nbTiles = 0;
	_renderDistance = 0.0f ;
	DebugDataVisible=true;
}

//----------------------------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------------------------
CGrassNode::~CGrassNode()
{

}
//----------------------------------------------------------------------------------------
// Create Grass
//----------------------------------------------------------------------------------------
bool CGrassNode::create(const SGrassParameters& SGrassParam)
{
		// create grass mesh
		 _grassMesh = new scene::SMesh();
		 _nbTiles = 1;
		 u32 distance = 0;
		for(u16 i=0;i<_nbTiles;i++)
		{
			buffer = new irr::scene::SMeshBuffer();

			irr::u32 NbsVertices=0;
			irr::u32 NbsIndices = 0;
			irr::u32 indiceIndex = 0;

			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(0.0 + distance , 10.0 , 0.0),
										   irr::core::vector3df(0.0, 0.0, 1.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(0.0, 0.0)));
			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(10.0 + distance, 10.0, 0.0),
										   irr::core::vector3df(0.0, 0.0, 1.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(1.0, 0.0)));
			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(10.0 + distance, 0.0, 0.0),
										   irr::core::vector3df(0.0, 0.0, 1.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(1.0, 1.0)));
			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(0.0 + distance, 0.0, 0.0),
										   irr::core::vector3df(0.0, 0.0, 1.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(0.0, 1.0)));

			buffer->Indices.push_back(0);
			buffer->Indices.push_back(1);
			buffer->Indices.push_back(2);
			buffer->Indices.push_back(3);
			buffer->Indices.push_back(0);
			buffer->Indices.push_back(2);


			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(0.0+100.0+ distance, 10.0, 0.0),
										   irr::core::vector3df(0.0, 0.0,0.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(0.0, 0.0)));
			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(10.0+100+ distance, 10.0, 0.0),
										   irr::core::vector3df(0.0, 0.0, 0.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(1.0, 0.0)));
			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(10.0+100+ distance, 0.0, 0.0),
										   irr::core::vector3df(0.0, 0.0, 0.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(1.0, 1.0)));
			buffer->Vertices.push_back(irr::video::S3DVertex(
										   irr::core::vector3df(0.0+100+ distance, 0.0, 0.0),
										   irr::core::vector3df(0.0, 0.0, 0.0), irr::video::SColor(255,255,255,255),
										   irr::core::vector2df(0.0, 1.0)));

			buffer->Indices.push_back(4);
			buffer->Indices.push_back(5);
			buffer->Indices.push_back(6);
			buffer->Indices.push_back(7);
			buffer->Indices.push_back(4);
			buffer->Indices.push_back(6);

			buffer->recalculateBoundingBox();
			buffer->setHardwareMappingHint(irr::scene::EHM_STATIC);
			buffer->setDirty();
			_grassMesh->addMeshBuffer(buffer);
			distance+=100.0f;
		}

		return true;
}

//----------------------------------------------------------------------------------------
// render Grass
//----------------------------------------------------------------------------------------
void CGrassNode::render()
{

    video::IVideoDriver* driver = _smgr->getVideoDriver();
	driver->setTransform(video::ETS_WORLD,AbsoluteTransformation);	

	
		for(u16 i=0;i<_nbTiles;i++)
		{
			driver->setMaterial(_grassMesh->getMeshBuffer(i)->getMaterial());
			driver->drawMeshBuffer(_grassMesh->getMeshBuffer(i));

		}
	//driver->setMaterial(buffer->getMaterial());
	//driver->drawMeshBuffer(buffer);
  //  }
}


//----------------------------------------------------------------------------------------
// Register the Grass Node
//----------------------------------------------------------------------------------------
void CGrassNode:: OnRegisterSceneNode()
{
    if(IsVisible)
        SceneManager->registerNodeForRendering(this);

    ISceneNode::OnRegisterSceneNode();
}

//----------------------------------------------------------------------------------------
// Animate
//----------------------------------------------------------------------------------------
void CGrassNode::OnAnimate(u32 timeMs)
{
}

//----------------------------------------------------------------------------------------
// set Grass material type for each buffer
//----------------------------------------------------------------------------------------
void CGrassNode::setMaterialType(video::E_MATERIAL_TYPE Mat)
{

		for(u16 i=0;i<_nbTiles;i++)
		{
				_grassMesh->getMeshBuffer(i)->getMaterial().MaterialType = Mat;
		}

}

//----------------------------------------------------------------------------------------
// set grass material flag for each buffer
//----------------------------------------------------------------------------------------
void CGrassNode::setMaterialFlag(video::E_MATERIAL_FLAG Mat, bool Flag)
{

		for(u16 i=0;i<_nbTiles;i++)
		{
				_grassMesh->getMeshBuffer(i)->getMaterial().setFlag(Mat, Flag);
		}

}

//---------------------------------------------------------------------------------------
// Get Materia0l
//----------------------------------------------------------------------------------------
irr::video::SMaterial& CGrassNode::getMaterial(irr::u32 i)
{
    return _material;
}


//----------------------------------------------------------------------------------------
// set grass material and texture 
//----------------------------------------------------------------------------------------
bool CGrassNode::setTexture(const io::path& textureFileName)
{
	video::IVideoDriver * driver = _smgr->getVideoDriver();
	video::ITexture * tex = 0;
	tex = driver->getTexture(textureFileName);
	if (!tex)
		return false;

			for(u16 i=0;i<_nbTiles;i++)
		{
				_grassMesh->getMeshBuffer(i)->getMaterial().setTexture(0, tex);
		}

	return true;
}

//---------------------------------------------------------------------------------------
// Get box
//----------------------------------------------------------------------------------------
const irr::core::aabbox3d<irr::f32>& CGrassNode::getBoundingBox() const
{
    return _box;
}

irr::u32 CGrassNode::getMaterialCount() const
{
    return 1;
}


Last edited by kidhr on Sun Oct 31, 2010 2:23 pm, edited 2 times in total.
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

I have the same problem: http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=40162

Do you turn off any z-buffers or z-writing at any point?
kidhr
Posts: 9
Joined: Fri Oct 01, 2010 5:04 pm

Post by kidhr »

I have tried with z-buffer true and false in Material buffer.

With the flag is set to false, i don't see my quads
With the flag is set to true, the problem subsiste

Something I've found : when the problem occurs, the number of Primitives is modified, it's decrease.
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

Post by Darktib »

Maybe something wrong with automatic culling ? Try deactivating it.
kidhr
Posts: 9
Joined: Fri Oct 01, 2010 5:04 pm

Post by kidhr »

Thanks a lot Darktib, It's working fine with setAutomaticCulling(scene::EAC_OFF);

I've tried with almost all parameters but no EAC_OFF

Something to do with setMaterialFlag(video::EMF_BACK_FACE_CULLING,false) ?
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

Not for me. The problem for me persists regardless of whether back face culling is on or off.

Turning off automatic culling really isn't a good idea unless you have a very small amount of geometry. No automatic culling means everything out of the camera's bounds is still drawn, right? That would slow everything down.
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

agamemnus wrote:Not for me. The problem for me persists regardless of whether back face culling is on or off.

Turning off automatic culling really isn't a good idea unless you have a very small amount of geometry. No automatic culling means everything out of the camera's bounds is still drawn, right? That would slow everything down.
Yep. Try drawing the bounding box to see if it is really correct. I also use EAC_FRUSTUM_BOX for culling.
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

Is there a quick and dirty way to draw the bounding box?
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

if you do a quick search on the forum you'll get the results in 5 seconds
http://irrlicht.sourceforge.net/phpBB2/ ... ht=edsbbox
kidhr
Posts: 9
Joined: Fri Oct 01, 2010 5:04 pm

Post by kidhr »

Hello

I have made many tries but only setAutomaticCulling(scene::EAC_OFF) is ok at this time.
Also working with EAC_OCC_QUERY

My code for drawing the bounding box

Code: Select all

void CGrassNode::render()
{

    video::IVideoDriver* driver = _smgr->getVideoDriver();	
	driver->setTransform(video::ETS_WORLD,AbsoluteTransformation);	

		for(u16 i=0;i<_nbTiles;i++)
		{
			driver->setMaterial(_grassMesh->getMeshBuffer(i)->getMaterial());
			driver->drawMeshBuffer(_grassMesh->getMeshBuffer(i));

			// for debug purposes only:
			if (DebugDataVisible)
			{
				//driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
				video::SMaterial m;
				m.Lighting = false;
				driver->setMaterial(m);
				driver->draw3DBox(_grassMesh->getMeshBuffer(i)->getBoundingBox(), video::SColor(0,255,255,255));
			}
		}
}
And the Result

Image


The quads and the bounding box disappear when my camera rotates
kidhr
Posts: 9
Joined: Fri Oct 01, 2010 5:04 pm

Post by kidhr »

I think I've find the trick.

My function getBoundingBox in my custom node was not correct

The function doesn't return the good bounding box


With return the mesh bounding box, it is ok
Like This
//---------------------------------------------------------------------------------------
// Get box
//----------------------------------------------------------------------------------------
const irr::core::aabbox3d<irr::f32>& CGrassNode::getBoundingBox() const
{
return _grassMesh->getBoundingBox();
}

Sorry and thanks for help :oops:
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

Virion wrote:if you do a quick search on the forum you'll get the results in 5 seconds
http://irrlicht.sourceforge.net/phpBB2/ ... ht=edsbbox
Thanks!

I would not have thought to search for "boundingbox" or "edsbbox", though...

Edit:

Not a bounding box problem for me. I actually did find a bounding box issue (too big bounding boxes), but even after fixing that, obviously that did not fix my original problem (since they were too big, not too small).
Post Reply