diff --git a/src/Demos/osggeometry/osggeometry.cpp b/src/Demos/osggeometry/osggeometry.cpp index 971ab4b9c..d9d452bb7 100644 --- a/src/Demos/osggeometry/osggeometry.cpp +++ b/src/Demos/osggeometry/osggeometry.cpp @@ -3,6 +3,9 @@ #include #include #include +#include + +#include #include @@ -32,7 +35,7 @@ // with the various primitives in it, and the main() which sets up a basic viewer window and // adds to the it the scene generated by createScene(). -osg::Geode* createScene() +osg::Node* createScene() { // create the Geode (Geometry Node) to contain all our osg::Geometry objects. osg::Geode* geode = new osg::Geode(); @@ -69,7 +72,7 @@ osg::Geode* createScene() // in a color array. osg::Vec4Array* colors = new osg::Vec4Array; // add a white color, colors take the form r,g,b,a with 0.0 off, 1.0 full on. - colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); // pass the color arry to points geometry, note the binding to tell the geometry // that only use one color for the whole object. @@ -120,7 +123,7 @@ osg::Geode* createScene() // set the colors as before, plus using the aobve osg::Vec4Array* colors = new osg::Vec4Array; - colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); linesGeom->setColorArray(colors); linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL); @@ -162,7 +165,7 @@ osg::Geode* createScene() // set the colors as before, plus using the aobve osg::Vec4Array* colors = new osg::Vec4Array; - colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); linesGeom->setColorArray(colors); linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL); @@ -209,7 +212,7 @@ osg::Geode* createScene() // set the colors as before, plus using the aobve osg::Vec4Array* colors = new osg::Vec4Array; - colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); linesGeom->setColorArray(colors); linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL); @@ -241,7 +244,7 @@ osg::Geode* createScene() // standard C pointer, as that in the case of it not being // assigned it will still be cleaned up automatically. osg::ref_ptr shared_colors = new osg::Vec4Array; - shared_colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + shared_colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); // same trick for shared normal. osg::ref_ptr shared_normals = new osg::Vec3Array; @@ -249,19 +252,31 @@ osg::Geode* createScene() + // Note on vertex ordering. + // While the OpenGL diagram should vertices specified in a clockwise direction + // in reality you need to specify coords for polygons into a anticlockwise direction + // for their front face to be pointing towards your, get this wrong and you could + // find back face culling removing the wrong faces of your models. The OpenGL diagram + // is just plain wrong, but its nice diagram so we'll keep it for now! + // create POLYGON { // create Geometry object to store all the vetices and lines primtive. osg::Geometry* polyGeom = new osg::Geometry(); // this time we'll a C arrays to initilize the vertices. + // note, anticlockwsie ordering. + // note II, OpenGL polygons must be convex plan polygons, otherwise + // undefined results will occur. If you have concave polygons or ones + // that cross over themselves then use the osgUtil::Tesselator to fix + // the polygons into a set of valid polygons. osg::Vec3 myCoords[] = { - osg::Vec3(-0.980488, -2.15188e-09, -0.094753), - osg::Vec3(-0.766264, -2.15188e-09, -0.0576758), - osg::Vec3(-0.807461, -2.15188e-09, -0.181267), - osg::Vec3(-1.0258, -2.15188e-09, -0.26778), - osg::Vec3(-1.0464, 9.18133e-09, -0.193626) + osg::Vec3(-1.0464, 0.0f, -0.193626), + osg::Vec3(-1.0258, 0.0f, -0.26778), + osg::Vec3(-0.807461, 0.0f, -0.181267), + osg::Vec3(-0.766264, 0.0f, -0.0576758), + osg::Vec3(-0.980488, 0.0f, -0.094753) }; int numCoords = sizeof(myCoords)/sizeof(osg::Vec3); @@ -296,17 +311,18 @@ osg::Geode* createScene() // create Geometry object to store all the vetices and lines primtive. osg::Geometry* polyGeom = new osg::Geometry(); + // note, anticlockwsie ordering. osg::Vec3 myCoords[] = { - osg::Vec3(-0.222464, 9.18133e-09, -0.13183), - osg::Vec3(-0.160668, 9.18133e-09, -0.0453167), - osg::Vec3(0.0247182, 9.18133e-09, -0.00823939), - osg::Vec3(0.0247182, 9.18133e-09, -0.156548), + osg::Vec3(0.0247182, 0.0f, -0.156548), + osg::Vec3(0.0247182, 0.0f, -0.00823939), + osg::Vec3(-0.160668, 0.0f, -0.0453167), + osg::Vec3(-0.222464, 0.0f, -0.13183), - osg::Vec3(0.13595, -2.15188e-09, -0.255421), - osg::Vec3(0.164788, 9.18133e-09, -0.0453167), - osg::Vec3(0.333696, 9.18133e-09, 0.0329576), - osg::Vec3(0.238942, -2.15188e-09, -0.251302) + osg::Vec3(0.238942, 0.0f, -0.251302), + osg::Vec3(0.333696, 0.0f, 0.0329576), + osg::Vec3(0.164788, 0.0f, -0.0453167), + osg::Vec3(0.13595, 0.0f, -0.255421) }; int numCoords = sizeof(myCoords)/sizeof(osg::Vec3); @@ -335,7 +351,253 @@ osg::Geode* createScene() geode->addDrawable(polyGeom); } - return geode; + // create QUAD_STRIP + { + // create Geometry object to store all the vetices and lines primtive. + osg::Geometry* polyGeom = new osg::Geometry(); + + // note, first coord at top, second at bottom, reverse to that buggy OpenGL image.. + osg::Vec3 myCoords[] = + { + osg::Vec3(0.733306, -2.15188e-09, -0.0741545), + osg::Vec3(0.758024, -2.15188e-09, -0.205985), + + osg::Vec3(0.885735, -2.15188e-09, -0.0576757), + osg::Vec3(0.885735, -2.15188e-09, -0.214224), + + osg::Vec3(0.964009, 9.18133e-09, -0.0370773), + osg::Vec3(1.0464, 9.18133e-09, -0.173027), + + osg::Vec3(1.11232, -2.15188e-09, 0.0123591), + osg::Vec3(1.12468, 9.18133e-09, -0.164788), + }; + + int numCoords = sizeof(myCoords)/sizeof(osg::Vec3); + + osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords); + + // pass the created vertex array to the points geometry object. + polyGeom->setVertexArray(vertices); + + // use the shared color array. + polyGeom->setColorArray(shared_colors.get()); + polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL); + + + // use the shared normal array. + polyGeom->setNormalArray(shared_normals.get()); + polyGeom->setNormalBinding(osg::Geometry::BIND_OVERALL); + + + // This time we simply use primitive, and hardwire the number of coords to use + // since we know up front, + polyGeom->addPrimitive(new osg::DrawArrays(osg::Primitive::QUAD_STRIP,0,numCoords)); + + + // add the points geomtry to the geode. + geode->addDrawable(polyGeom); + } + + // create TRIANGLES, TRIANGLE_STRIP and TRIANGLE_FAN all in one Geometry/ + { + // create Geometry object to store all the vetices and lines primtive. + osg::Geometry* polyGeom = new osg::Geometry(); + + // note, first coord at top, second at bottom, reverse to that buggy OpenGL image.. + osg::Vec3 myCoords[] = + { + // TRIANGLES 6 vertices, v0..v5 + // note in aniclockwise order. + osg::Vec3(-1.12056, -2.15188e-09, -0.840418), + osg::Vec3(-0.95165, -2.15188e-09, -0.840418), + osg::Vec3(-1.11644, 9.18133e-09, -0.716827), + + // note in aniclockwise order. + osg::Vec3(-0.840418, 9.18133e-09, -0.778623), + osg::Vec3(-0.622074, 9.18133e-09, -0.613835), + osg::Vec3(-1.067, 9.18133e-09, -0.609715), + + // TRIANGLE STRIP 6 vertices, v6..v11 + // note defined top point first, + // then anticlockwise for the next two points, + // then alternating to bottom there after. + osg::Vec3(-0.160668, -2.15188e-09, -0.531441), + osg::Vec3(-0.160668, -2.15188e-09, -0.749785), + osg::Vec3(0.0617955, 9.18133e-09, -0.531441), + osg::Vec3(0.168908, -2.15188e-09, -0.753905), + osg::Vec3(0.238942, -2.15188e-09, -0.531441), + osg::Vec3(0.280139, -2.15188e-09, -0.823939), + + // TRIANGLE FAN 5 vertices, v12..v16 + // note defined in anticlockwsie order. + osg::Vec3(0.844538, 9.18133e-09, -0.712708), + osg::Vec3(1.0258, 9.18133e-09, -0.799221), + osg::Vec3(1.03816, -2.15188e-09, -0.692109), + osg::Vec3(0.988727, 9.18133e-09, -0.568518), + osg::Vec3(0.840418, -2.15188e-09, -0.506723), + + }; + + int numCoords = sizeof(myCoords)/sizeof(osg::Vec3); + + osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords); + + // pass the created vertex array to the points geometry object. + polyGeom->setVertexArray(vertices); + + // use the shared color array. + polyGeom->setColorArray(shared_colors.get()); + polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL); + + + // use the shared normal array. + polyGeom->setNormalArray(shared_normals.get()); + polyGeom->setNormalBinding(osg::Geometry::BIND_OVERALL); + + + // This time we simply use primitive, and hardwire the number of coords to use + // since we know up front, + polyGeom->addPrimitive(new osg::DrawArrays(osg::Primitive::TRIANGLES,0,6)); + polyGeom->addPrimitive(new osg::DrawArrays(osg::Primitive::TRIANGLE_STRIP,6,6)); + polyGeom->addPrimitive(new osg::DrawArrays(osg::Primitive::TRIANGLE_FAN,12,5)); + + + // add the points geomtry to the geode. + geode->addDrawable(polyGeom); + } + + return geode; +} + + +// define a node callback to animation a transform as a cycle along the y axis, between 0 and 2.0. +class MyTransformCallback : public osg::NodeCallback +{ + + public: + + MyTransformCallback(float angularVelocity) + { + _angular_velocity = angularVelocity; + } + + virtual void operator() (osg::Node* node, osg::NodeVisitor* nv) + { + osg::Transform* transform = dynamic_cast(node); + if (nv && transform && nv->getFrameStamp()) + { + double time = nv->getFrameStamp()->getReferenceTime(); + transform->setMatrix(osg::Matrix::translate(0.0f,1.0f+cosf(time*_angular_velocity),0.0f)); + } + + // must continue subgraph traversal. + traverse(node,nv); + + } + + protected: + + float _angular_velocity; + +}; + + +osg::Node* createBackground() +{ + + // we'll create a texture mapped quad to sit behind the Geometry + osg::Image* image = osgDB::readImageFile("primitives.gif"); + if (!image) return NULL; + + + // create Geometry object to store all the vetices and lines primtive. + osg::Geometry* polyGeom = new osg::Geometry(); + + // note, anticlockwsie ordering. + osg::Vec3 myCoords[] = + { + osg::Vec3(-1.22908f,0.0f,1.0f), + osg::Vec3(-1.22908f,0.0f,-1.0f), + osg::Vec3(1.22908f,0.0f,-1.0f), + osg::Vec3(1.22908f,0.0f,1.0f) + }; + + int numCoords = sizeof(myCoords)/sizeof(osg::Vec3); + + // pass the created vertex array to the points geometry object. + polyGeom->setVertexArray(new osg::Vec3Array(numCoords,myCoords)); + + osg::Vec4Array* colors = new osg::Vec4Array; + colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + polyGeom->setColorArray(colors); + polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL); + + + // set the normal in the same way color. + osg::Vec3Array* normals = new osg::Vec3Array; + normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f)); + polyGeom->setNormalArray(normals); + polyGeom->setNormalBinding(osg::Geometry::BIND_OVERALL); + + osg::Vec2 myTexCoords[] = + { + osg::Vec2(0,1), + osg::Vec2(0,0), + osg::Vec2(1,0), + osg::Vec2(1,1) + }; + + int numTexCoords = sizeof(myCoords)/sizeof(osg::Vec3); + + // pass the created tex coord array to the points geometry object, + // and use it to set texture unit 0. + polyGeom->setTexCoordArray(0,new osg::Vec2Array(numTexCoords,myTexCoords)); + + // well use indices and DrawElements to define the primitive this time. + unsigned short myIndices[] = + { + 0, + 1, + 2, + 3 + }; + + int numIndices = sizeof(myIndices)/sizeof(unsigned short); + + // Theere are three variants of the DrawElements osg::Primitive, UByteDrawElements which + // contains unsigned char indicies, UShortDrawElements which contains unsigned short indices, + // and UIntDrawElements whcih contains ... unsigned int indices. + // The first parameter to DrawElements is + polyGeom->addPrimitive(new osg::UShortDrawElements(osg::Primitive::QUADS,4,myIndices)); + + // new we need to add the texture to the Drawable, we do so by creating a + // StateSet to contain the Texture StateAttribute. + osg::StateSet* stateset = new osg::StateSet; + + // set up the texture. + osg::Texture* texture = new osg::Texture; + texture->setImage(image); + + stateset->setAttributeAndModes(texture,osg::StateAttribute::ON); + + polyGeom->setStateSet(stateset); + + + // create the Geode (Geometry Node) to contain all our osg::Geometry objects. + osg::Geode* geode = new osg::Geode(); + + // add the points geomtry to the geode. + geode->addDrawable(polyGeom); + + //return geode; + + // create a tranform to move the background back and forward with. + + osg::Transform* transform = new osg::Transform(); + transform->setAppCallback(new MyTransformCallback(1.0f)); + transform->addChild(geode); + + return transform; } int main( int argc, char **argv ) @@ -355,8 +617,15 @@ int main( int argc, char **argv ) // parameters that have been matched. viewer.readCommandLine(commandLine); + + // create the model + osg::Group* root = new osg::Group; + root->addChild( createScene() ); + root->addChild( createBackground() ); + + // add model to viewer. - viewer.addViewport( createScene() ); + viewer.addViewport( root ); // register trackball maniupulators. viewer.registerCameraManipulator(new osgGA::TrackballManipulator);