From 7d50c8e6344cd59a8c3c0469f4a3d855a95975f7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 25 Feb 2015 16:59:43 +0000 Subject: [PATCH] From Michael McDonnell, "I have changed the code so that the plus key increases both the inner and outer tessellation. The minus key decrease both the inner and outer tessellation. You can still use the arrow keys to control inner and outer tessellation separately." From Robert Osfield, clean up the code to fix warnings and make the coding style more consistent with the rest of the OSG. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14716 16af8721-9629-0410-8352-f15c8da7e697 --- .../osgtessellationshaders.cpp | 97 ++++++++++++++----- 1 file changed, 73 insertions(+), 24 deletions(-) diff --git a/examples/osgtessellationshaders/osgtessellationshaders.cpp b/examples/osgtessellationshaders/osgtessellationshaders.cpp index 9ca266f98..ab1e6d1d3 100644 --- a/examples/osgtessellationshaders/osgtessellationshaders.cpp +++ b/examples/osgtessellationshaders/osgtessellationshaders.cpp @@ -1,6 +1,13 @@ /* A demonstration of Tessellation Shaders in OpenScenegraph. + * + * Instructions: + * Press plus to increase tesselation and minus to decrease it. + * Press right arrow to increase inner tesselation and left arrow to decrease it. + * Press up arrow to increase outer tesselation and down arrow to decrease it. + * * Original code by Philip Rideout * Adapted to OpenScenegraph by John Kaniarz + * Additional work by Michael Mc Donnell */ #include @@ -113,7 +120,8 @@ static const char* fragSource = { "}\n" }; -osg::ref_ptr CreateIcosahedron(osg::Program *program){ +osg::ref_ptr CreateIcosahedron(osg::Program *program) +{ osg::Geode *geode=new osg::Geode(); osg::Geometry *geometry = new osg::Geometry(); const unsigned int Faces[] = { @@ -166,7 +174,9 @@ osg::ref_ptr CreateIcosahedron(osg::Program *program){ geode->addDrawable(geometry); return geode; } -osg::ref_ptr createProgram(){ + +osg::ref_ptr createProgram() +{ osg::Program *program = new osg::Program(); program->addShader(new osg::Shader(osg::Shader::VERTEX,vertSource)); program->addShader(new osg::Shader(osg::Shader::TESSCONTROL,tessControlSource)); @@ -179,38 +189,74 @@ osg::ref_ptr createProgram(){ return program; } -float tessInner=1.0f; -float tessOuter=1.0f; -osg::ref_ptr tessInnerU = new osg::Uniform("TessLevelInner",tessInner); -osg::ref_ptr tessOuterU = new osg::Uniform("TessLevelOuter",tessOuter); - -class KeyboardEventHandler : public osgGA::GUIEventHandler { +class KeyboardEventHandler : public osgGA::GUIEventHandler +{ public: - KeyboardEventHandler():osgGA::GUIEventHandler(){} - virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& gaa){ + KeyboardEventHandler(osg::ref_ptr tessInnerU, osg::ref_ptr tessOuterU): + _tessInnerU(tessInnerU), + _tessOuterU(tessOuterU) + { + tessInnerU->get(_tessInner); + tessOuterU->get(_tessOuter); + } + + virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& gaa) + { if(ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN){ switch (ea.getKey()){ case osgGA::GUIEventAdapter::KEY_Up: - tessOuter++; - tessOuterU->set(tessOuter); + increaseOuterTesselation(); return true; case osgGA::GUIEventAdapter::KEY_Down: - tessOuter--; - tessOuter=std::max(1.0f,tessOuter); - tessOuterU->set(tessOuter); + decreaseOuterTesselation(); return true; case osgGA::GUIEventAdapter::KEY_Left: - tessInner--; - tessInner=std::max(1.0f,tessInner); - tessInnerU->set(tessInner); + decreaseInnerTesselation(); return true; case osgGA::GUIEventAdapter::KEY_Right: - tessInner++; - tessInnerU->set(tessInner); + increaseInnerTesselation(); + return true; + case osgGA::GUIEventAdapter::KEY_Plus: + case osgGA::GUIEventAdapter::KEY_KP_Add: + increaseInnerTesselation(); + increaseOuterTesselation(); + return true; + case osgGA::GUIEventAdapter::KEY_Minus: + case osgGA::GUIEventAdapter::KEY_KP_Subtract: + decreaseInnerTesselation(); + decreaseOuterTesselation(); return true; } } - return osgGA::GUIEventHandler::handle(ea,gaa); + return osgGA::GUIEventHandler::handle(ea, gaa); + } + +private: + osg::ref_ptr _tessInnerU; + osg::ref_ptr _tessOuterU; + float _tessInner; + float _tessOuter; + + void increaseInnerTesselation() + { + _tessInnerU->set(++_tessInner); + } + + void decreaseInnerTesselation() + { + _tessInner = std::max(1.0f, _tessInner-1.0f); + _tessInnerU->set(_tessInner); + } + + void increaseOuterTesselation() + { + _tessOuterU->set(++_tessOuter); + } + + void decreaseOuterTesselation() + { + _tessOuter = std::max(1.0f, _tessOuter-1.0f); + _tessOuterU->set(_tessOuter); } }; @@ -220,6 +266,9 @@ int main(int argc, char* argv[]) viewer.setUpViewInWindow(100,100,800,600); osg::ref_ptr program = createProgram(); osg::ref_ptr geode = CreateIcosahedron(program.get()); + osg::ref_ptr tessInnerU = new osg::Uniform("TessLevelInner", 1.0f); + osg::ref_ptr tessOuterU = new osg::Uniform("TessLevelOuter", 1.0f); + osg::StateSet *state; state = geode->getOrCreateStateSet(); state->addUniform(new osg::Uniform("AmbientMaterial",osg::Vec3(0.04f, 0.04f, 0.04f))); @@ -229,7 +278,7 @@ int main(int argc, char* argv[]) state->addUniform(tessOuterU.get()); state->setAttribute(new osg::PatchParameter(3)); state->setAttribute(program.get()); - + // switch on the uniforms that track the modelview and projection matrices osgViewer::Viewer::Windows windows; viewer.getWindows(windows); @@ -241,8 +290,8 @@ int main(int argc, char* argv[]) s->setUseModelViewAndProjectionUniforms(true); s->setUseVertexAttributeAliasing(true); } - - viewer.addEventHandler(new KeyboardEventHandler()); + + viewer.addEventHandler(new KeyboardEventHandler(tessInnerU, tessOuterU)); viewer.setSceneData(geode.get()); return viewer.run(); }