[osg-users] different materials for a geometry and highlight

Sebastian Messerschmidt sebastian.messerschmidt at gmx.de
Tue Sep 27 06:49:15 PDT 2016


Hi Gianni,

attached you find a quick example using a simple texture to let the user 
"draw" different colors at different positions.
Basically it modifies the image data and samples it back when drawing. 
I've created a mesh, but basically this would work with a simple quad 
too. Is this maybe closer to what you want?

Cheers
Sebastian

> SMesserschmidt wrote:
>> I can try to make a
>> minimal example, if you give me some time (I can do this after work).
>>
> Sebastian,
> yes thanks, when you have time is fine. In the meanwhile I try to understand the solutions you suggested.
>
> Regards,
> Gianni
>
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=68789#68789
>
>
>
>
>
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

-------------- next part --------------

#include <osg/Geometry>
#include <osg/Geode>
#include <osg/MatrixTransform>
#include <osg/PolygonOffset>

#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/MultiTouchTrackballManipulator>
#include <osg/PolygonMode>
#include <osg/LineWidth>
#include <osg/ShadeModel>

#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>

//#include <osgQt/GraphicsWindowQt>

#include <iostream>
const unsigned int DIMENSION = 64;

class SelectModelHandler : public osgGA::GUIEventHandler
{
public:
	SelectModelHandler(osg::ref_ptr<osg::Group> group, osg::Image* image)
		: _selector(0), currentPrimitiveSetIndex(0), _root(group), _image(image)
	{}

	virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
	{

		if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE &&
			ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON &&
			ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL)
		{
			osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
			if (viewer)
			{
				osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
				osgUtil::IntersectionVisitor iv(intersector.get());
				osg::Camera* camera = viewer->getCamera();
				camera->accept(iv);

				if (intersector->containsIntersections())
				{
					osgUtil::LineSegmentIntersector::Intersection result = *(intersector->getIntersections().begin());
					doUserOperations(result);
				}
			}
		}

		return false;
	}

	virtual void doUserOperations(osgUtil::LineSegmentIntersector::Intersection& result)
	{

		osg::Geometry* geom = dynamic_cast<osg::Geometry*>(result.drawable.get());
		osg::Vec3 tc;
		//the result seems slightly off 
		osg::Texture* tex = result.getTextureLookUp(tc);
		if (tex && tex->getImage(0))
		{
			tex->getImage(0)->setColor(osg::Vec4d(1, 1, 1, 1), tc);
			tex->getImage(0)->dirty();
			tex->dirtyTextureObject();
		}
	
	}
protected:
	osg::ref_ptr<osg::Geometry> _selector;
	unsigned int currentPrimitiveSetIndex;
	osg::ref_ptr<osg::Group> _root;
	osg::ref_ptr<osg::Image> _image;
};

osg::Vec3Array* buildVertices(unsigned int num_rows) 
{
	//create a grid	
	osg::Vec3Array* v = new osg::Vec3Array(num_rows* num_rows);
	for (unsigned int i = 0; i < num_rows; ++i)
	{
		for (unsigned int j = 0; j < num_rows; ++j)
		{
			(*v)[i * num_rows + j] = osg::Vec3(i, j, 0);
		}
	}
	return v;
}
osg::Vec2Array* buildTexCoords(unsigned int num_rows)
{
	//create a grid	
	osg::Vec2Array* v = new osg::Vec2Array(num_rows* num_rows);
	for (unsigned int i = 0; i < num_rows; ++i)
	{
		for (unsigned int j = 0; j < num_rows; ++j)
		{
			(*v)[i * num_rows + j] = osg::Vec2(i / static_cast<float>(num_rows -1), j / static_cast<float>(num_rows -1));
		}
	}
	return v;
}

osg::DrawElementsUInt* buildElements(unsigned int num_rows)
{
	osg::DrawElementsUInt* element = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);

	for (unsigned int i = 0; i < num_rows - 1; ++i)
	{
		for (unsigned int j = 0; j < num_rows - 1; j++)
		{
			unsigned int offset = i * num_rows + j;
			(*element).push_back(offset + 0);
			(*element).push_back(offset + 1);
			(*element).push_back(offset + num_rows);
			(*element).push_back(offset + 1);
			(*element).push_back(offset + num_rows + 1);
			(*element).push_back(offset + num_rows);
		}
	}
	return element;
}



osg::Vec4Array* buildColors(unsigned int num_rows) 
{
	osg::Vec4Array* colors = new osg::Vec4Array(num_rows * num_rows);
	std::fill(std::begin(*colors), std::end(*colors), osg::Vec4f(0.5,0.5,0.5,1.0));
	return colors;
}
osg::Image* makeDataImage(unsigned int num_rows)
{
	osg::Image* image = new osg::Image;
	
	image->allocateImage(num_rows, num_rows, 1, GL_RGB, GL_UNSIGNED_BYTE);
	for (unsigned int i = 0; i < num_rows; ++i)
	{
		for (unsigned int j = 0; j < num_rows; ++j)
		{
			osg::Vec2 uv(i / static_cast<float>(num_rows - 1), j / static_cast<float>(num_rows - 1));
			//checker
			//image->setColor(osg::Vec4(i / static_cast<float>(num_rows), j / static_cast<float>(num_rows), 0, 1), uv);
			 if (0 == i % 2 && j % 2 )
			 {
				 image->setColor(osg::Vec4(0, 0, 0, 1), uv);
			 }
			 else
			 {
				 image->setColor(osg::Vec4(1, 0, 0, 1), uv);
			 }

		}
	}
	return image;

}
osg::Geometry* buildGeometry(osg::Image* image) 
{
	osg::Geometry* geometry = new osg::Geometry;
	geometry->setDataVariance(osg::Object::DYNAMIC);
	geometry->setUseVertexBufferObjects(true);
	geometry->setVertexArray(buildVertices(DIMENSION));
	//geometry->setColorArray(buildColors(DIMENSION), osg::Array::BIND_PER_VERTEX);
	geometry->setTexCoordArray(0, buildTexCoords(DIMENSION));

	geometry->addPrimitiveSet(buildElements(DIMENSION));
	osg::Texture2D* tex = new osg::Texture2D(image);
	tex->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
	tex->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
	//osg::Texture2D* tex = new osg::Texture2D(osgDB::readImageFile("d:/work/data/models/checker.tif"));
	geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);
	return geometry;
}



osg::Node* createScene(osg::Image* image) {
	osg::Geode* geode = new osg::Geode;
	geode->addDrawable(buildGeometry(image));
	return geode;
}


void createShader() 
{
	
}

int main(int argc, char** argv)
{
	osg::ArgumentParser arguments(&argc, argv);

	osgViewer::Viewer viewer(arguments);
	viewer.setUpViewInWindow(0, 0, 1000, 1000, 1);

	osg::Image* data_image = makeDataImage(DIMENSION);

	osg::ref_ptr<osg::Group> root = new osg::Group;
	osg::ref_ptr<osg::Group> selection_root = new osg::Group;
	root->addChild(createScene(data_image));
	root->addChild(selection_root);
	
	osg::ref_ptr<SelectModelHandler> selector = new SelectModelHandler(selection_root, data_image);
	viewer.setSceneData(root);
	viewer.addEventHandler(selector.get());
	viewer.setCameraManipulator(new osgGA::TrackballManipulator);
	viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));


	// add the window size toggle handler
	viewer.addEventHandler(new osgViewer::WindowSizeHandler);
	
	viewer.run();
}



More information about the osg-users mailing list