OpenSceneGraph/examples/osgshadergen/osgshadergen.cpp
Robert Osfield 1fd5eefbcf From Maciej Krol, "As promised to Roland I assembled simple shader generator. ShaderGenVisitor converts accumulated fixed function pipeline state sets to ones with shader programs. Generated state sets are attached to geometries and stored in ShaderGenCache for reuse.
Very simple cases of state configuration are supported (all the ones I really need):
- single per pixel not attenuated non spot light source ON/OFF
- exp2 fog ON/OFF
- diffuse texture in rgb + optional specular gloss in alpha (Texture unit 0) ON/OFF
- normal map texture (Texture unit 1 and Tangent in VertexAttribArray 6) ON/OFF
- blending and alpha testing (not in shader pipeline)

To view fixed function pipeline files and paged databases simply run >osgshadergen myfile.osg"
2009-03-23 11:53:06 +00:00

168 lines
5.7 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commericial and non commericial applications,
* as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <osgDB/ReadFile>
#include <osgUtil/ShaderGen>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <iostream>
class ShaderGenReadFileCallback : public osgDB::Registry::ReadFileCallback
{
public:
ShaderGenReadFileCallback()
{
}
virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& filename, const osgDB::ReaderWriter::Options* options)
{
osgDB::ReaderWriter::ReadResult result = osgDB::Registry::ReadFileCallback::readNode(filename, options);
if (osg::Node *node = result.getNode())
{
_visitor.reset();
node->accept(_visitor);
}
return result;
}
void setRootStateSet(osg::StateSet *stateSet) { _visitor.setRootStateSet(stateSet); }
osg::StateSet *getRootStateSet() const { return _visitor.getRootStateSet(); }
protected:
osgUtil::ShaderGenVisitor _visitor;
};
int main(int argc, char** argv)
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+
" is an example of conversion of fixed function pipeline to GLSL");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
osgViewer::Viewer viewer(arguments);
unsigned int helpType = 0;
if ((helpType = arguments.readHelpType()))
{
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;
}
if (arguments.argc()<=1)
{
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
return 1;
}
// set up the camera manipulators.
{
osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
std::string pathfile;
char keyForAnimationPath = '5';
while (arguments.read("-p",pathfile))
{
osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
if (apm || !apm->valid())
{
unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
keyswitchManipulator->selectMatrixManipulator(num);
++keyForAnimationPath;
}
}
viewer.setCameraManipulator( keyswitchManipulator.get() );
}
// add the state manipulator
viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
// add the thread model handler
viewer.addEventHandler(new osgViewer::ThreadingHandler);
// add the window size toggle handler
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
// add the stats handler
viewer.addEventHandler(new osgViewer::StatsHandler);
// add the help handler
viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
// add the record camera path handler
viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);
// add the LOD Scale handler
viewer.addEventHandler(new osgViewer::LODScaleHandler);
// add the screen capture handler
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
// Register shader generator callback
ShaderGenReadFileCallback *readFileCallback = new ShaderGenReadFileCallback;
// All read nodes will inherit root state set.
readFileCallback->setRootStateSet(viewer.getCamera()->getStateSet());
osgDB::Registry::instance()->setReadFileCallback(readFileCallback);
// load the data
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
if (!loadedModel)
{
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
return 1;
}
// 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);
return 1;
}
viewer.setSceneData( loadedModel.get() );
viewer.realize();
return viewer.run();
}