Hi Sebastian, after looking at your example I understood a shader is not needed, right? The solution you suggest is to apply a texture instead of changing color. In my case the image of the texture would be a monochromatic image. If all that is correct, then I have few questions. I modified my previous example to insert your solution there.
1) Since most part of the road surface may be not associated to a "material", then I thought of adding a BIND_OVERALL default grey color. Does it make sense? 2) On the basis of point 1) is it possible to add a texture only to triangles affected by a "material". In your example you added a texture to the overall geometry. Isn't that a problem if the road has a bunch of vertices? I mean, that bunch of vertices would be duplicated to create texture coords. 3) In the attached example Ididn't understand how to set the image just to the picked triangle so that it will be shown of the "current" color. (In my example pushing 1,2,3 and 4 keys changes the current color). 4) I have to read some documentation about textures since I didn't understand how texture coords should be defined and the effect of: texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); 5) I tried to create different texture coords (see #ifdef in the attached code) but "result.getTextureLookUp(tc);" in "doUserOperations" method does not seem to work. Anyway even with your implementation of "buildTexCoords" the selection is pretty odd. Regards, Gianni ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68807#68807
#include "stdafx.h" #include <iostream> #include <osg/Geometry> #include <osg/Geode> #include <osg/Material> #include <osg/PolygonOffset> #include <osgViewer/ViewerEventHandlers> #include <osgGA/TrackballManipulator> #include <osgGA/StateSetManipulator> const unsigned int DIMENSION = 4; class SelectModelHandler : public osgGA::GUIEventHandler { public: SelectModelHandler() : selectedColor(0.5f, 0.5f, 0.5f, 1.0f) {} 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 ); } } } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1) { selectedColor.set(1.0f, 0.0f, 0.0f, 1.0f); } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2) { selectedColor.set(0.0f, 1.0f, 0.0f, 1.0f); } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3) { selectedColor.set(0.0f, 0.0f, 1.0f, 1.0f); } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_4) { selectedColor.set(1.0f, 0.0f, 1.0f, 1.0f); } 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(selectedColor, tc); tex->getImage(0)->dirty(); tex->dirtyTextureObject(); } } protected: osg::Vec4 selectedColor; }; osg::Image* makeDataImage(unsigned int rows) { osg::Image* image = new osg::Image; image->allocateImage(rows, rows, 1, GL_RGB, GL_UNSIGNED_BYTE); for (unsigned int i = 0; i < rows; ++i) { for (unsigned int j = 0; j < rows; ++j) { osg::Vec2 uv(i / static_cast<float>(rows - 1), j / static_cast<float>(rows - 1)); image->setColor(osg::Vec4(1, 0, 0, 1), uv); } } return image; } osg::Vec2Array* buildTexCoords(unsigned int num_rows) { #if 1 //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; #else osg::Vec2Array* textureCoords = new osg::Vec2Array; textureCoords->push_back(osg::Vec2(0,0)); textureCoords->push_back(osg::Vec2(1,0)); textureCoords->push_back(osg::Vec2(0,1)); textureCoords->push_back(osg::Vec2(1,1)); return textureCoords; #endif } osg::Vec3Array* buildVertices() { osg::Vec3Array* vertices = new osg::Vec3Array; vertices->push_back(osg::Vec3(0,0,0)); vertices->push_back(osg::Vec3(10,0,0)); vertices->push_back(osg::Vec3(10,10,0)); vertices->push_back(osg::Vec3(0,10,0)); vertices->push_back(osg::Vec3(20,0,0)); vertices->push_back(osg::Vec3(20,10,0)); vertices->push_back(osg::Vec3(20,20,0)); vertices->push_back(osg::Vec3(10,20,0)); vertices->push_back(osg::Vec3(0,20,0)); return vertices; } osg::DrawElementsUInt* buildElements() { osg::DrawElementsUInt* element = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); element->push_back(0); element->push_back(1); element->push_back(2); element->push_back(0); element->push_back(2); element->push_back(3); ////////////////////////////////////////////////////////////////////////// element->push_back(1); element->push_back(4); element->push_back(5); element->push_back(1); element->push_back(5); element->push_back(2); ////////////////////////////////////////////////////////////////////////// element->push_back(2); element->push_back(5); element->push_back(6); element->push_back(2); element->push_back(6); element->push_back(7); ////////////////////////////////////////////////////////////////////////// element->push_back(3); element->push_back(2); element->push_back(7); element->push_back(3); element->push_back(7); element->push_back(8); return element; } osg::Vec4Array* buildColors() { osg::Vec4Array* colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); return colors; } osg::Geometry* buildGeometry() { osg::Geometry* geometry = new osg::Geometry; geometry->setDataVariance(osg::Object::DYNAMIC); geometry->setUseVertexBufferObjects(true); geometry->setVertexArray(buildVertices()); geometry->setColorArray(buildColors(), osg::Array::BIND_OVERALL); geometry->setTexCoordArray(0, buildTexCoords(DIMENSION)); geometry->addPrimitiveSet(buildElements()); osg::Image* image = makeDataImage(DIMENSION); osg::Texture2D* texture = new osg::Texture2D(image); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); return geometry; } osg::Node* createScene() { osg::Geode* geode = new osg::Geode; geode->addDrawable(buildGeometry()); return geode; } void addWireframe(osg::Group* root, osg::Node* scene) { osg::ref_ptr<osg::Group> decorator = new osg::Group; decorator->setNodeMask(0x1); //disable wireframe by default osg::StateSet* stateset = decorator->getOrCreateStateSet(); osg::PolygonOffset* polyoffset = new osg::PolygonOffset; polyoffset->setFactor(-1.0f); polyoffset->setUnits(-1.0f); stateset->setAttributeAndModes(polyoffset, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); osg::PolygonMode* polymode = new osg::PolygonMode; polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); stateset->setAttributeAndModes(polymode, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); osg::Material* material = new osg::Material; stateset->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF); stateset->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); decorator->addChild(scene); root->addChild(decorator); } int main( int argc, char** argv ) { osg::ArgumentParser arguments(&argc, argv); osgViewer::Viewer viewer(arguments); osg::Group* root = new osg::Group; osg::Node* scene = createScene(); root->addChild(scene); addWireframe(root, scene); viewer.setSceneData(root); viewer.addEventHandler(new SelectModelHandler()); 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(); }
_______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org