root/OpenSceneGraph/trunk/examples/osgvertexattributes/osgvertexattributes.cpp @ 10617

Revision 10617, 7.1 kB (checked in by robert, 5 years ago)

New osgvertexattributes example designed to test conversion of fixed function scene graphs to use vertex shaders
and vertex attributes.

Line 
1/* OpenSceneGraph example, osgvertexattributes.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osgUtil/ShaderGen>
20#include <osgDB/ReadFile>
21#include <osgDB/WriteFile>
22#include <osgViewer/Viewer>
23
24class ConvertToVertexAttibArrays : public osg::NodeVisitor
25{
26    public:
27
28        typedef std::pair<unsigned int, std::string> AttributeAlias;
29
30        ConvertToVertexAttibArrays():
31            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
32        {
33            // mappings taken from http://www.opengl.org/registry/specs/NV/vertex_program.txt
34            _vertexAlias = AttributeAlias(0, "osg_Vertex");
35            _normalAlias = AttributeAlias(2, "osg_Normal");
36            _colorAlias = AttributeAlias(3, "osg_Color");
37            _secondaryColorAlias = AttributeAlias(4, "osg_SecondaryColor");
38            _fogCoordAlias = AttributeAlias(5, "osg_FogCoord");
39            _texCoordAlias[0] = AttributeAlias(8, "osg_MultiTexCoord0");
40            _texCoordAlias[1] = AttributeAlias(9, "osg_MultiTexCoord1");
41            _texCoordAlias[2] = AttributeAlias(10, "osg_MultiTexCoord2");
42            _texCoordAlias[3] = AttributeAlias(11, "osg_MultiTexCoord3");
43            _texCoordAlias[4] = AttributeAlias(12, "osg_MultiTexCoord4");
44            _texCoordAlias[5] = AttributeAlias(13, "osg_MultiTexCoord5");
45            _texCoordAlias[6] = AttributeAlias(14, "osg_MultiTexCoord6");
46            _texCoordAlias[7] = AttributeAlias(15, "osg_MultiTexCoord7");
47        }
48
49
50        void apply(osg::Geode& geode)
51        {
52            for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
53            {
54                osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
55                if (geom) apply(*geom);
56            }
57        }
58
59        void apply(osg::Geometry& geom)
60        {
61            osg::notify(osg::NOTICE)<<"Found geometry "<<&geom<<std::endl;
62            if (geom.getVertexArray())
63            {
64                setVertexAttrib(geom, _vertexAlias, geom.getVertexArray(), false, osg::Geometry::BIND_PER_VERTEX);
65                geom.setVertexArray(0);
66            }
67
68            if (geom.getNormalArray())
69            {
70                setVertexAttrib(geom, _normalAlias, geom.getNormalArray(), true, geom.getNormalBinding());
71                geom.setNormalArray(0);
72            }
73
74            if (geom.getColorArray())
75            {
76                setVertexAttrib(geom, _colorAlias, geom.getColorArray(), true, geom.getColorBinding());
77                geom.setColorArray(0);
78            }
79
80            if (geom.getSecondaryColorArray())
81            {
82                setVertexAttrib(geom, _secondaryColorAlias, geom.getSecondaryColorArray(), true, geom.getSecondaryColorBinding());
83                geom.setSecondaryColorArray(0);
84            }
85
86            if (geom.getFogCoordArray())
87            {
88                // should we normalize the FogCoord array? Don't think so...
89                setVertexAttrib(geom, _fogCoordAlias, geom.getFogCoordArray(), false, geom.getSecondaryColorBinding());
90                geom.setFogCoordArray(0);
91            }
92
93            unsigned int maxNumTexCoords = geom.getNumTexCoordArrays();
94            if (maxNumTexCoords>8)
95            {
96                osg::notify(osg::NOTICE)<<"Warning: Ignoring "<<maxNumTexCoords-8<<" texture coordinate arrays, only 8 are currently supported in vertex attribute conversion code."<<std::endl;
97                maxNumTexCoords = 8;
98            }
99            for(unsigned int i=0; i<maxNumTexCoords; ++i)
100            {
101                if (geom.getTexCoordArray(i))
102                {
103                    setVertexAttrib(geom, _texCoordAlias[i], geom.getTexCoordArray(i), true, geom.getSecondaryColorBinding());
104                    geom.setTexCoordArray(i,0);
105                }
106                else
107                {
108                    osg::notify(osg::NOTICE)<<"Found empty TexCoordArray("<<i<<")"<<std::endl;
109                }
110            }
111        }
112
113        void setVertexAttrib(osg::Geometry& geom, const AttributeAlias& alias, osg::Array* array, bool normalize, osg::Geometry::AttributeBinding binding)
114        {
115            unsigned int index = alias.first;
116            const std::string& name = alias.second;
117            array->setName(name);
118            geom.setVertexAttribArray(index, array);
119            geom.setVertexAttribNormalize(index, normalize);
120            geom.setVertexAttribBinding(index, binding);
121
122            osg::notify(osg::NOTICE)<<"   vertex attrib("<<name<<", index="<<index<<", normalize="<<normalize<<" binding="<<binding<<")"<<std::endl;
123        }
124
125        AttributeAlias _vertexAlias;
126        AttributeAlias _normalAlias;
127        AttributeAlias _colorAlias;
128        AttributeAlias _secondaryColorAlias;
129        AttributeAlias _fogCoordAlias;
130        AttributeAlias _texCoordAlias[8];
131};
132
133
134
135int main(int argc, char *argv[])
136{
137    // use an ArgumentParser object to manage the program arguments.
138    osg::ArgumentParser arguments(&argc,argv);
139
140    // construct the viewer.
141    osgViewer::Viewer viewer(arguments);
142
143    std::string outputFileName;
144    while (arguments.read("-o",outputFileName)) {}
145
146    bool runShaderGen = true;
147    while (arguments.read("--shader-gen")) { runShaderGen = true; }
148    while (arguments.read("--no-shader-gen")) { runShaderGen = false; }
149
150    bool runConvertToVertexAttributes = true;
151    while (arguments.read("--vertex-attrib")) { runConvertToVertexAttributes = true; }
152    while (arguments.read("--no-vertex-attrib")) { runConvertToVertexAttributes = false; }
153
154    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
155    if (!loadedModel.get())
156    {
157        osg::notify(osg::NOTICE)<<"No model loaded, please specify a model filename."<<std::endl;
158        return 1;
159    }
160
161    if (runShaderGen)
162    {
163        // convert fixed function pipeline to shaders
164        osgUtil::ShaderGenVisitor sgv;
165        loadedModel->accept(sgv);
166    }
167
168    if (runConvertToVertexAttributes)
169    {
170        // find any conventional vertex, colour, normal and tex coords arrays and convert to vertex attributes
171        ConvertToVertexAttibArrays ctvaa;
172        loadedModel->accept(ctvaa);
173    }
174
175    if (!outputFileName.empty())
176    {
177        osgDB::writeNodeFile(*loadedModel, outputFileName);
178        return 0;
179    }
180
181    // add a viewport to the viewer and attach the scene graph.
182    viewer.setSceneData(loadedModel.get());
183
184    return viewer.run();
185}
Note: See TracBrowser for help on using the browser.