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
This commit is contained in:
Robert Osfield 2015-02-25 16:59:43 +00:00
parent e7d41377be
commit 7d50c8e634

View File

@ -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 <osg/Program>
@ -113,7 +120,8 @@ static const char* fragSource = {
"}\n"
};
osg::ref_ptr<osg::Geode> CreateIcosahedron(osg::Program *program){
osg::ref_ptr<osg::Geode> 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<osg::Geode> CreateIcosahedron(osg::Program *program){
geode->addDrawable(geometry);
return geode;
}
osg::ref_ptr<osg::Program> createProgram(){
osg::ref_ptr<osg::Program> 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,39 +189,75 @@ osg::ref_ptr<osg::Program> createProgram(){
return program;
}
float tessInner=1.0f;
float tessOuter=1.0f;
osg::ref_ptr<osg::Uniform> tessInnerU = new osg::Uniform("TessLevelInner",tessInner);
osg::ref_ptr<osg::Uniform> 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<osg::Uniform> tessInnerU, osg::ref_ptr<osg::Uniform> 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);
}
private:
osg::ref_ptr<osg::Uniform> _tessInnerU;
osg::ref_ptr<osg::Uniform> _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);
}
};
int main(int argc, char* argv[])
@ -220,6 +266,9 @@ int main(int argc, char* argv[])
viewer.setUpViewInWindow(100,100,800,600);
osg::ref_ptr<osg::Program> program = createProgram();
osg::ref_ptr<osg::Geode> geode = CreateIcosahedron(program.get());
osg::ref_ptr<osg::Uniform> tessInnerU = new osg::Uniform("TessLevelInner", 1.0f);
osg::ref_ptr<osg::Uniform> 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)));
@ -242,7 +291,7 @@ int main(int argc, char* argv[])
s->setUseVertexAttributeAliasing(true);
}
viewer.addEventHandler(new KeyboardEventHandler());
viewer.addEventHandler(new KeyboardEventHandler(tessInnerU, tessOuterU));
viewer.setSceneData(geode.get());
return viewer.run();
}