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

Reply via email to