1 #include <osg/FragmentProgram>
2 #include <osg/io_utils>
3 
4 #include <iostream>
5 #include <sstream>
6 #include "osgDB/Registry"
7 #include "osgDB/Input"
8 #include "osgDB/Output"
9 #include "osgDB/fstream"
10 
11 #include "Matrix.h"
12 
13 using namespace osg;
14 using namespace osgDB;
15 using namespace std;
16 
17 // forward declare functions to use later.
18 bool FragmentProgram_readLocalData(Object& obj, Input& fr);
19 bool FragmentProgram_writeLocalData(const Object& obj, Output& fw);
20 
21 // register the read and write functions with the osgDB::Registry.
22 REGISTER_DOTOSGWRAPPER(FragmentProgram)
23 (
24     new osg::FragmentProgram,
25     "FragmentProgram",
26     "Object StateAttribute FragmentProgram",
27     &FragmentProgram_readLocalData,
28     &FragmentProgram_writeLocalData
29 );
30 
31 
FragmentProgram_readLocalData(Object & obj,Input & fr)32 bool FragmentProgram_readLocalData(Object& obj, Input& fr)
33 {
34     bool iteratorAdvanced = false;
35 
36     FragmentProgram& fragmentProgram = static_cast<FragmentProgram&>(obj);
37 
38     if (fr[0].matchWord("ProgramLocalParameter"))
39     {
40         int index;
41         Vec4 vec;
42         fr[1].getInt(index);
43         fr[2].getFloat(vec[0]);
44         fr[3].getFloat(vec[1]);
45         fr[4].getFloat(vec[2]);
46         fr[5].getFloat(vec[3]);
47         fr += 6;
48         iteratorAdvanced = true;
49         fragmentProgram.setProgramLocalParameter(index, vec);
50     }
51 
52     if (fr[0].matchWord("Matrix"))
53     {
54         int index;
55         fr[1].getInt(index);
56         fr += 2;
57         osg::Matrix matrix;
58         if (readMatrix(matrix,fr))
59         {
60             fragmentProgram.setMatrix(index, matrix);
61         }
62         iteratorAdvanced = true;
63     }
64 
65     if (fr.matchSequence("code {"))
66     {
67         std::string code;
68         fr += 2;
69         iteratorAdvanced = true;
70         int entry = fr[0].getNoNestedBrackets();
71         while (!fr.eof() && fr[0].getNoNestedBrackets() >= entry) {
72             if (fr[0].getStr()) {
73             code.append(std::string(fr[0].getStr()));
74             code += '\n';
75             }
76             ++fr;
77         }
78         fragmentProgram.setFragmentProgram(code);
79     }
80 
81     if( fr.matchSequence("file %s"))
82     {
83         std::string filename = fr[1].getStr();
84         fr += 2;
85         iteratorAdvanced = true;
86 
87         osgDB::ifstream vfstream( filename.c_str() );
88 
89         if( vfstream ) {
90             ostringstream vstream;
91             char ch;
92 
93             /* xxx better way to transfer a ifstream to a string?? */
94             while( vfstream.get(ch)) vstream.put(ch);
95 
96             fragmentProgram.setFragmentProgram( vstream.str() );
97         }
98     }
99 
100     return iteratorAdvanced;
101 }
102 
103 
FragmentProgram_writeLocalData(const Object & obj,Output & fw)104 bool FragmentProgram_writeLocalData(const Object& obj,Output& fw)
105 {
106     const FragmentProgram& fragmentProgram = static_cast<const FragmentProgram&>(obj);
107 
108     const FragmentProgram::LocalParamList& lpl = fragmentProgram.getLocalParameters();
109     FragmentProgram::LocalParamList::const_iterator i;
110     for(i=lpl.begin(); i!=lpl.end(); i++)
111     {
112         fw.indent() << "ProgramLocalParameter " << (*i).first << " " << (*i).second << std::endl;
113     }
114 
115     const FragmentProgram::MatrixList& mpl = fragmentProgram.getMatrices();
116     FragmentProgram::MatrixList::const_iterator mi;
117     for(mi=mpl.begin(); mi!=mpl.end(); mi++)
118     {
119         fw.indent() << "Matrix " << (*mi).first << " ";
120         writeMatrix((*mi).second,fw);
121     }
122 
123     std::vector<std::string> lines;
124     std::istringstream iss(fragmentProgram.getFragmentProgram());
125     std::string line;
126     while (std::getline(iss, line))
127     {
128         lines.push_back(line);
129     }
130 
131     fw.indent() << "code {\n";
132     fw.moveIn();
133 
134     std::vector<std::string>::const_iterator j;
135     for (j=lines.begin(); j!=lines.end(); ++j)
136     {
137         fw.indent() << "\"" << *j << "\"\n";
138     }
139 
140     fw.moveOut();
141     fw.indent() << "}\n";
142 
143     return true;
144 }
145