bool
ShaderGenerator::processGeometry(const osg::StateSet* original,
osg::ref_ptr<osg::StateSet>& replacement)
{
// do nothing if there's no GLSL support
if ( !_active )
return false;
// capture the active current state:
osg::ref_ptr<osg::StateSet> current = static_cast<StateEx*>(_state.get())->capture();
// check for a real osg::Program in the whole state stack. If it exists, bail out
// so that OSG can use the program already in the graph. We never override a
// full Program.
osg::StateAttribute* program = current->getAttribute(osg::StateAttribute::PROGRAM);
if ( dynamic_cast<osg::Program*>(program) != 0L )
return false;
// Copy or create a new stateset (that we may or may not use depending on
// what we find). Never modify an existing stateset!
osg::ref_ptr<osg::StateSet> newStateSet =
original ? osg::clone(original, osg::CopyOp::SHALLOW_COPY) :
new osg::StateSet();
// likewise, create a VP that we might populate.
osg::ref_ptr<VirtualProgram> vp = VirtualProgram::cloneOrCreate(original, newStateSet);
// we'll set this to true if the new stateset goes into effect and
// needs to be returned.
bool needNewStateSet = false;
bool needVertexFunction = false;
bool needFragmentFunction = false;
// give the VP a name if it needs one.
if ( vp->getName().empty() )
{
vp->setName( _name );
}
// Check whether the lighting state has changed and install a mode uniform.
// TODO: fix this
if ( original && original->getMode(GL_LIGHTING) != osg::StateAttribute::INHERIT )
{
needNewStateSet = true;
osg::StateAttribute::GLModeValue value = current->getMode(GL_LIGHTING);
newStateSet->addUniform( Registry::shaderFactory()->createUniformForGLMode(GL_LIGHTING, value) );
}
// start generating the shader source.
GenBuffers buf;
buf._stateSet = newStateSet.get();
// if the stateset changes any texture attributes, we need a new virtual program:
if (current->getTextureAttributeList().size() > 0)
{
bool wroteTexelDecl = false;
// Loop over all possible texture image units.
int maxUnit = Registry::capabilities().getMaxGPUTextureUnits();
for( int unit = 0; unit < maxUnit; ++unit )
{
if ( !wroteTexelDecl )
{
buf._fragBody << INDENT << MEDIUMP "vec4 texel; \n";
wroteTexelDecl = true;
}
osg::Texture* tex = dynamic_cast<osg::Texture*>( current->getTextureAttribute(unit, osg::StateAttribute::TEXTURE) );
if (accept(tex) && !ImageUtils::isFloatingPointInternalFormat(tex->getInternalFormat()))
{
osg::TexGen* texgen = dynamic_cast<osg::TexGen*>(current->getTextureAttribute(unit, osg::StateAttribute::TEXGEN));
osg::TexEnv* texenv = dynamic_cast<osg::TexEnv*>(current->getTextureAttribute(unit, osg::StateAttribute::TEXENV));
osg::TexMat* texmat = dynamic_cast<osg::TexMat*>(current->getTextureAttribute(unit, osg::StateAttribute::TEXMAT));
osg::PointSprite* sprite = dynamic_cast<osg::PointSprite*>(current->getTextureAttribute(unit, osg::StateAttribute::POINTSPRITE));
if ( apply(tex, texgen, texenv, texmat, sprite, unit, buf) == true )
{
needNewStateSet = true;
}
}
}
}
// Process the state attributes.
osg::StateSet::AttributeList& attrs = current->getAttributeList();
if ( apply(attrs, buf) )
{
needNewStateSet = true;
}
if ( needNewStateSet )
{
std::string version = GLSL_VERSION_STR;
std::string vertHeadSource;
vertHeadSource = buf._vertHead.str();
std::string vertBodySource;
//.........这里部分代码省略.........
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
// set up the usage document, in case we need to print out how to use this program.
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
arguments.getApplicationUsage()->addCommandLineOption("--image <filename>","Load an image and render it on a quad");
arguments.getApplicationUsage()->addCommandLineOption("--dem <filename>","Load an image/DEM and render it on a HeightField");
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line parameters");
arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display environmental variables available");
arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display keyboard & mouse bindings available");
arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display all command line, env vars and keyboard & mouse bindings.");
arguments.getApplicationUsage()->addCommandLineOption("--dragger <draggername>","Use the specified dragger for manipulation [TabPlaneDragger, TabPlaneTrackballDragger, TrackballDragger, Translate1DDragger, Translate2DDragger, TranslateAxisDragger, TabBoxDragger, TranslatePlaneDragger, Scale1DDragger, Scale2DDragger, RotateCylinderDragger, RotateSphereDragger]");
arguments.getApplicationUsage()->addCommandLineOption("--fixedDraggerSize","Fix the size of the dragger geometry in the screen space");
bool fixedSizeInScreen = false;
while (arguments.read("--fixedDraggerSize")) { fixedSizeInScreen = true; }
// construct the viewer.
osgViewer::Viewer viewer(arguments);
// add the window size toggle handler
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
// get details on keyboard and mouse bindings used by the viewer.
viewer.getUsage(*arguments.getApplicationUsage());
if (arguments.read("--test-NodeMask"))
{
const osg::ref_ptr<osg::Group> group = new osg::Group();
group->setNodeMask(0);
const osg::ref_ptr<osgManipulator::AntiSquish> antiSquish = new osgManipulator::AntiSquish();
group->addChild(antiSquish.get());
const osg::ref_ptr<osg::Node> node = new osg::Node();
node->setInitialBound(osg::BoundingSphere(osg::Vec3(0.0, 0.0, 0.0), 1.0));
antiSquish->addChild(node.get());
group->getBound();
return 1;
}
// if user request help write it out to cout.
bool helpAll = arguments.read("--help-all");
unsigned int helpType = ((helpAll || arguments.read("-h") || arguments.read("--help"))? osg::ApplicationUsage::COMMAND_LINE_OPTION : 0 ) |
((helpAll || arguments.read("--help-env"))? osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE : 0 ) |
((helpAll || arguments.read("--help-keys"))? osg::ApplicationUsage::KEYBOARD_MOUSE_BINDING : 0 );
if (helpType)
{
arguments.getApplicationUsage()->write(std::cout, helpType);
return 1;
}
// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
std::string dragger_name = "TabBoxDragger";
arguments.read("--dragger", dragger_name);
osg::Timer_t start_tick = osg::Timer::instance()->tick();
// read the scene from the list of file specified command line args.
osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFiles(arguments);
// if no model has been successfully loaded report failure.
bool tragger2Scene(true);
if (!loadedModel)
{
//std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
//return 1;
loadedModel = createDemoScene(fixedSizeInScreen);
tragger2Scene=false;
}
// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();
// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
}
osg::Timer_t end_tick = osg::Timer::instance()->tick();
//.........这里部分代码省略.........
int main(void){
osg::DisplaySettings::instance()->setNumMultiSamples( 4 );
viewer.setUpViewInWindow( 100, 50, 800, 600 );
viewer.getCamera()->setClearColor( osg::Vec4( 0.5,0.5,0.5,1) );
viewer.addEventHandler(new osgViewer::StatsHandler);
osg::Group* scene = new osg::Group;
// Création d'une boîte centrée à l'origine, de dimensions 2x3x4:
osg::Box* boite = new osg::Box(osg::Vec3(-10, 0, 0), 2,3,4);
osg::ShapeDrawable* boiteDrawable = new osg::ShapeDrawable(boite);
osg::Geode* geodeBoite = new osg::Geode();
geodeBoite->addDrawable(boiteDrawable);
osg::Sphere* sphere = new osg::Sphere( osg::Vec3(10,0,0), 1.0);
osg::ShapeDrawable* sphereDrawable = new osg::ShapeDrawable(sphere);
osg::Geode* geodeSphere = new osg::Geode();
geodeSphere->addDrawable(sphereDrawable);
osg::Capsule* capsule = new osg::Capsule(osg::Vec3(0, 0, 0), 1.0, 3.0);
osg::ShapeDrawable* capsuleDrawable = new osg::ShapeDrawable(capsule);
osg::Geode* geodeCapsule = new osg::Geode();
geodeCapsule->addDrawable(capsuleDrawable);
osg::Cone* cone = new osg::Cone(osg::Vec3(0, 10, 0), 1, 2);
osg::ShapeDrawable* coneDrawable = new osg::ShapeDrawable(cone);
osg::Geode* geodeCone= new osg::Geode();
geodeCone->addDrawable(coneDrawable);
osg::Material* matBoite = new osg::Material;
matBoite->setAmbient (osg::Material::FRONT_AND_BACK, osg::Vec4(0.5, 0.0, 0.0, 1.0));
matBoite->setDiffuse (osg::Material::FRONT_AND_BACK, osg::Vec4(0.9, 0.0, 0.0, 1.0));
matBoite->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0.2, 0.2, 0.2, 1.0));
matBoite->setShininess(osg::Material::FRONT_AND_BACK, 64);
osg::Material* matCone = new osg::Material;
matCone->setAmbient (osg::Material::FRONT_AND_BACK, osg::Vec4(0.5, 0.0, 0.5, 1.0));
matCone->setDiffuse (osg::Material::FRONT_AND_BACK, osg::Vec4(0.9, 0.0, 0.9, 1.0));
matCone->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0.2, 0.2, 0.2, 1.0));
matCone->setShininess(osg::Material::FRONT_AND_BACK, 64);
osg::Node* aregne = osgDB::readNodeFile("cow_high.3ds");
transformAregne->setPosition(osg::Vec3(5, 0, 0));
transformAregne->setScale(osg::Vec3(0.2, 0.2, 0.2));
transformAregne->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON);
transformAregne->addChild(aregne);
boiteDrawable->getOrCreateStateSet()->setAttributeAndModes(matBoite);
coneDrawable->getOrCreateStateSet()->setAttributeAndModes(matCone);
/*scene->addChild(geodeCapsule);
scene->addChild(geodeCone);
scene->addChild(geodeBoite);
scene->addChild(geodeSphere);
scene->addChild(transformAregne);*/
scene->addChild(aregne);
// Création d'une texture
osg::ref_ptr<osg::Texture2D> tex2D = new osg::Texture2D;
tex2D->setTextureSize(1024, 1024);
tex2D->setInternalFormat(GL_RGBA);
// Création d'une caméra qui effectuera son rendu dans la texture
osg::ref_ptr<osg::Camera> rttCamera =
createRTTCamera(osg::Camera::COLOR_BUFFER, tex2D.get());
// On indique la partie du graphe que la caméra devra rendre, ici toute la scène :
rttCamera->addChild(scene);
// Création d'une caméra permettant d'afficher un HUD qui couvrira tout l'écran
osg::ref_ptr<osg::Camera> hudCamera = createHUDCamera();
osg::Geode* screenQuad = createScreenQuad();
hudCamera->addChild(screenQuad);
osg::StateSet* stateset = screenQuad->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, tex2D.get());
// VOUS METTREZ ICI LE CODE DE LA QUESTION 7
// Création d'une nouvelle racine du graphe, à laquelle on rattache la caméra
// de rendu dans une texture, la caméra du HUD et la racine du graphe de la scène
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(rttCamera.get());
root->addChild(hudCamera.get());
root->addChild(scene);
// Indique au viewer la scène à affich
trackCone->setTrackNode(geodeCone);
trackCone->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER);
trackBoite->setTrackNode(geodeBoite);
trackBoite->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER);
trackSphere->setTrackNode(geodeSphere);
trackSphere->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER);
transformAregne->setUpdateCallback(new Deplacement);
viewer.setSceneData(scene);
osg::ref_ptr<GestionEvenements> gestionnaire = new GestionEvenements();
viewer.addEventHandler(gestionnaire.get());
//.........这里部分代码省略.........
请发表评论