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
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org