Jump to content

How to Render Points?


photo

Recommended Posts

The objective I want to achieve is rendering Point Cloud data. First,  I try to use renderPoint3D(), it works great but can not handle huge data set. Therefore,  I follow the Unigine Scripte Samples  "samples/shaders/particles_00.cpp"  and rewrite into c++ project. But nothing was in the screen.  Any suggestion to modify my code? Thanks in advanced! 

Here is my code:

ObjectDynamicPtr  pod;

int AppWorldLogic::init()
{
	pod = ObjectDynamic::create();
		
	pod->setName("POINTS");
	pod->setMaterial("particles", "*");
	pod->setSurfaceProperty("surface_base", "*");

	pod->setSurfaceMode(ObjectDynamic::MODE_POINTS, 0);
	pod->setMaterialNodeType(Node::OBJECT_MESH_DYNAMIC);
	pod->setInstancing(0);

	ObjectDynamic::Attribute *attrib = new ObjectDynamic::Attribute;
	const ObjectDynamic::Attribute attributes2[] = { { 0, ObjectDynamic::TYPE_FLOAT, 3 } ,{ 12, ObjectDynamic::TYPE_FLOAT, 2 } };

	pod->setVertexFormat(attributes2, 2);
	pod->addPoints(65536);
	for (int i = 0; i < pod->getNumIndices(); i++)
	{
		vec3 vertex = vec3(Game::get()->getRandomFloat(-128.0f, 128.0f), Game::get()->getRandomFloat(-128.0f, 128.0f), Game::get()->getRandomFloat(2.0f, 64.0f));
		pod->addVertexFloat(0, vertex, 3);
		vec2 xy = vec2(Game::get()->getRandomFloat(0.2f, 0.8f), Game::get()->getRandomFloat(0.0f, 3.1415));
		pod->setVertexFloat(1, vec4(xy,0,0),2);
	}
	pod->flushVertex();

	BoundBox bb = BoundBox(vec3(-128, -128, 2), vec3(128, 128, 64));
	pod->setBoundBox(bb);
 }

 

Link to comment

Hi d83v83,

Try modifying your code in init() as follows:

int AppWorldLogic::init() {
	pod = ObjectDynamic::create();

	pod->setName("POINTS");
	pod->setMaterial("particles", "*"); //	<- this material, along with the shaders it uses, must be copied to your project's data folder
	pod->setSurfaceProperty("surface_base", "*");

	pod->setSurfaceMode(ObjectDynamic::MODE_POINTS, 0);
	pod->setInstancing(0);

	ObjectDynamic::Attribute attributes[2] = { { 0, ObjectDynamic::TYPE_FLOAT, 3 }, { 12, ObjectDynamic::TYPE_FLOAT, 2 } };
	pod->setVertexFormat(attributes, 2);

	pod->addPoints(65536);
	for (int i = 0; i < pod->getNumIndices(); i++)
	{
		vec3 vertex = vec3(Game::get()->getRandomFloat(-128.0f, 128.0f), Game::get()->getRandomFloat(-128.0f, 128.0f), Game::get()->getRandomFloat(2.0f, 64.0f));
		pod->addVertexFloat(0, vertex, 3);
		vec2 xy = vec2(Game::get()->getRandomFloat(0.2f, 0.8f), Game::get()->getRandomFloat(0.0f, 3.1415));
		pod->setVertexFloat(1, vec4(xy, 0, 0), 2);
	}

	BoundBox bb = BoundBox(vec3(-128, -128, 2), vec3(128, 128, 64));
	pod->setBoundBox(bb);
  	return 1;
}

And make sure you've copied the following folders from the  samples/shaders/ folder to your project's data folder:

  • shaders/particles
  • shaders/materials 

Hope this helps!

Thank you!

Link to comment

As I can see from your attached files, you did not try the code I posted above.

Either try the code above, or try commenting the following line in your AppWorldLogic.cpp :

//pod->setMaterialNodeType(Node::OBJECT_MESH_DYNAMIC);

or replacing it with:

pod->setMaterialNodeType(Node::OBJECT_DYNAMIC);

This method actually enables a sort of filter to prevent assignment of inappropriate materials.

The point is that the "particles" material you use can be assigned to OBJECT_DYNAMIC nodes only (see the shader tag below)

<?xml version="1.0" encoding="utf-8"?>
<base_material name="particles" editable="0" version="2.5.0.2">
	<blend src="one" dest="one"/>
	<options depth_mask="0" cast_shadow="0" cast_world_shadow="0" transparent="2"/>
	<shader pass="ambient" node="object_dynamic" vertex="shaders/particles/vertex.shader" geometry="shaders/particles/geometry.shader" fragment="shaders/particles/fragment.shader"/>
	<texture name="diffuse" wrap="clamp">core/textures/particles_base_diffuse.dds</texture>
</base_material>

while your filter was set to OBJECT_MESH_DYNAMIC.

So, your code after the modification may look like this:

int AppWorldLogic::init()
{
	// Write here code to be called on world initialization: initialize resources for your world scene during the world start.
	pod = ObjectDynamic::create();

	pod->setName("POINTS");
	pod->setMaterial("particles", "*");
	pod->setSurfaceProperty("surface_base", "*");

	pod->setSurfaceMode(ObjectDynamic::MODE_POINTS, 0);
	//pod->setMaterialNodeType(Node::OBJECT_MESH_DYNAMIC);
	pod->setMaterialNodeType(Node::OBJECT_DYNAMIC);
	pod->setInstancing(0);

	ObjectDynamic::Attribute *attrib = new ObjectDynamic::Attribute;
	const ObjectDynamic::Attribute attributes2[] = { { 0, ObjectDynamic::TYPE_FLOAT, 3 } ,{ 12, ObjectDynamic::TYPE_FLOAT, 2 } };

	pod->setVertexFormat(attributes2, 2);
	pod->addPoints(65536);
	for (int i = 0; i < pod->getNumIndices(); i++)
	{
		vec3 vertex = vec3(Game::get()->getRandomFloat(-128.0f, 128.0f), Game::get()->getRandomFloat(-128.0f, 128.0f), Game::get()->getRandomFloat(2.0f, 64.0f));
		pod->addVertexFloat(0, vertex, 3);
		vec2 xy = vec2(Game::get()->getRandomFloat(0.2f, 0.8f), Game::get()->getRandomFloat(0.0f, 3.1415));
		pod->setVertexFloat(1, vec4(xy, 0, 0), 2);
	}

	BoundBox bb = BoundBox(vec3(-128, -128, 2), vec3(128, 128, 64));
	pod->setBoundBox(bb);


	return 1;
}

And don't forget to clear your pod pointer in the shutdown(), as not doing so causes a crash:

int AppWorldLogic::shutdown()
{
	// Write here code to be called on world shutdown: delete resources that were created during world script execution to avoid memory leaks.
	
	pod.clear();
  
	return 1;
}

This should solve your issue, and you'll be able to see your points rendered.

Thank you!

Link to comment

Sorry, I didn't  recognize the difference between your post and my.  After deleting the line  "pod->setMaterialNodeType(Node::OBJECT_MESH_DYNAMIC);", it works! Wonderful! 

 

Link to comment
×
×
  • Create New...