root/OpenSceneGraph/trunk/src/osgFX/AnisotropicLighting.cpp @ 13041

Revision 13041, 8.8 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osgFX/AnisotropicLighting>
2#include <osgFX/Registry>
3
4#include <osg/VertexProgram>
5#include <osg/Texture2D>
6#include <osg/TexEnv>
7
8#include <osgDB/ReadFile>
9
10#include <sstream>
11
12using namespace osgFX;
13
14namespace
15{
16
17    // a state attribute class that grabs the initial inverse view matrix
18    // and sends it to a VertexProgram.
19    // NOTE: due to lack of support for per-context parameters in VertexProgram,
20    // this class will send the matrix to the vp only while the first context
21    // is being rendered. All subsequent contexts will use the first context's
22    // matrix.
23    class ViewMatrixExtractor: public osg::StateAttribute {
24    public:
25        ViewMatrixExtractor()
26        :    osg::StateAttribute(),
27            _vp(0),
28            _param(0),
29            _first_context(-1)
30        {
31        }
32
33        ViewMatrixExtractor(const ViewMatrixExtractor& copy, const osg::CopyOp& copyop)
34        :    osg::StateAttribute(copy, copyop),
35            _vp(static_cast<osg::VertexProgram *>(copyop(copy._vp.get()))),
36            _param(copy._param),
37            _first_context(-1)
38        {
39        }
40
41        ViewMatrixExtractor(osg::VertexProgram *vp, int param)
42        :    osg::StateAttribute(),
43            _vp(vp),
44            _param(param),
45            _first_context(-1)
46        {
47        }
48
49        META_StateAttribute(osgFX, ViewMatrixExtractor, VIEWMATRIXEXTRACTOR);
50
51        int compare(const osg::StateAttribute &sa) const
52        {
53            COMPARE_StateAttribute_Types(ViewMatrixExtractor, sa);
54            if (_vp.get() != rhs._vp.get()) return -1;
55            if (_param < rhs._param) return -1;
56            if (_param > rhs._param) return 1;
57            return 0;
58        }
59
60        void apply(osg::State& state) const
61        {
62            if (_first_context == -1) {
63                _first_context = state.getContextID();
64            }
65            if (state.getContextID() == (unsigned int)_first_context) {
66                if (_vp.valid()) {
67                    osg::Matrix M = state.getInitialInverseViewMatrix();
68                    for (int i=0; i<4; ++i) {
69                        _vp->setProgramLocalParameter(_param+i, osg::Vec4(M(0, i), M(1, i), M(2, i), M(3, i)));
70                    }
71                }
72            }
73        }
74
75    private:
76        mutable osg::ref_ptr<osg::VertexProgram> _vp;
77        int _param;
78        mutable int _first_context;
79    };
80
81}
82
83namespace
84{
85
86    osg::Image* create_default_image()
87    {
88        const int _texturesize = 16;
89        osg::ref_ptr<osg::Image> image = new osg::Image;
90        image->setImage(_texturesize, _texturesize, 1, 3, GL_RGB, GL_UNSIGNED_BYTE, new unsigned char[3*_texturesize*_texturesize], osg::Image::USE_NEW_DELETE);
91        for (int i=0; i<_texturesize; ++i) {
92            for (int j=0; j<_texturesize; ++j) {
93                float s = static_cast<float>(j) / (_texturesize-1);
94                float t = static_cast<float>(i) / (_texturesize-1);
95                float lum = t * 0.75f;
96                float red = lum + 0.2f * powf(cosf(s*10), 3.0f);
97                float green = lum;
98                float blue = lum + 0.2f * powf(sinf(s*10), 3.0f);
99                if (red > 1) red = 1;
100                if (red < 0) red = 0;
101                if (blue > 1) blue = 1;
102                if (blue < 0) blue = 0;
103                *(image->data(j, i)+0) = static_cast<unsigned char>(red * 255);
104                *(image->data(j, i)+1) = static_cast<unsigned char>(green * 255);
105                *(image->data(j, i)+2) = static_cast<unsigned char>(blue * 255);
106            }
107        }
108        return image.release();
109    }
110
111}
112
113namespace
114{
115
116    Registry::Proxy proxy(new AnisotropicLighting);
117
118    class DefaultTechnique: public Technique {
119    public:
120
121        DefaultTechnique(int lightnum, osg::Texture2D *texture)
122        :    Technique(),
123            _lightnum(lightnum),
124            _texture(texture)
125        {
126        }
127
128        void getRequiredExtensions(std::vector<std::string>& extensions) const
129        {
130            extensions.push_back("GL_ARB_vertex_program");
131        }
132
133    protected:
134
135        void define_passes()
136        {
137            std::ostringstream vp_oss;
138            vp_oss <<
139                "!!ARBvp1.0\n"
140                "PARAM c5 = { 0, 0, 0, 1 };"
141                "PARAM c4 = { 0, 0, 0, 0 };"
142                "TEMP R0, R1, R2, R3, R4, R5, R6, R7, R8, R9;"
143                "ATTRIB v18 = vertex.normal;"
144                "ATTRIB v16 = vertex.position;"
145                "PARAM s259[4] = { state.matrix.mvp };"
146                "PARAM s18 = state.light[" << _lightnum << "].position;"
147                "PARAM s223[4] = { state.matrix.modelview };"
148                "PARAM c0[4] = { program.local[0..3] };"
149                "    DP4 result.position.x, s259[0], v16;"
150                "    DP4 result.position.y, s259[1], v16;"
151                "    DP4 result.position.z, s259[2], v16;"
152                "    DP4 result.position.w, s259[3], v16;"
153                "    MOV R9, c0[0];"
154                "    MUL R0, R9.y, s223[1];"
155                "    MAD R0, R9.x, s223[0], R0;"
156                "    MAD R0, R9.z, s223[2], R0;"
157                "    MAD R8, R9.w, s223[3], R0;"
158                "    DP4 R0.x, R8, v16;"
159                "    MOV R7, c0[1];"
160                "    MUL R1, R7.y, s223[1];"
161                "    MAD R1, R7.x, s223[0], R1;"
162                "    MAD R1, R7.z, s223[2], R1;"
163                "    MAD R6, R7.w, s223[3], R1;"
164                "    DP4 R0.y, R6, v16;"
165                "    MOV R5, c0[2];"
166                "    MUL R1, R5.y, s223[1];"
167                "    MAD R1, R5.x, s223[0], R1;"
168                "    MAD R1, R5.z, s223[2], R1;"
169                "    MAD R4, R5.w, s223[3], R1;"
170                "    DP4 R0.z, R4, v16;"
171                "    MOV R3, c0[3];"
172                "    MUL R1, R3.y, s223[1];"
173                "    MAD R1, R3.x, s223[0], R1;"
174                "    MAD R1, R3.z, s223[2], R1;"
175                "    MAD R1, R3.w, s223[3], R1;"
176                "    DP4 R0.w, R1, v16;"
177                "    MOV R1.x, R9.w;"
178                "    MOV R1.y, R7.w;"
179                "    MOV R1.z, R5.w;"
180                "    MOV R1.w, R3.w;"
181                "    ADD R2, R1, -R0;"
182                "    DP4 R0.x, R2, R2;"
183                "    RSQ R1.x, R0.x;"
184                "    DP4 R0.x, R9, s18;"
185                "    DP4 R0.y, R7, s18;"
186                "    DP4 R0.z, R5, s18;"
187                "    DP4 R0.w, R3, s18;"
188                "    DP4 R1.y, R0, R0;"
189                "    RSQ R1.y, R1.y;"
190                "    MUL R3, R1.y, R0;"
191                "    MAD R2, R1.x, R2, R3;"
192                "    DP4 R1.x, R2, R2;"
193                "    RSQ R1.x, R1.x;"
194                "    MUL R1, R1.x, R2;"
195                "    DP3 R2.x, R8.xyzx, v18.xyzx;"
196                "    DP3 R2.y, R6.xyzx, v18.xyzx;"
197                "    DP3 R2.z, R4.xyzx, v18.xyzx;"
198                "    MOV R2.w, c4.x;"
199                "    DP4 R1.x, R1, R2;"
200                "    MAX result.texcoord[0].x, R1.x, c4.x;"
201                "    DP4 R0.x, R0, R2;"
202                "    MAX result.texcoord[0].y, R0.x, c4.x;"
203                "END\n";
204
205            osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
206
207            osg::ref_ptr<osg::VertexProgram> vp = new osg::VertexProgram;
208            vp->setVertexProgram(vp_oss.str());
209            ss->setAttributeAndModes(vp.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
210
211            ss->setAttributeAndModes(new ViewMatrixExtractor(vp.get(), 0), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
212
213            ss->setTextureAttributeAndModes(0, _texture.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
214
215            osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
216            texenv->setMode(osg::TexEnv::DECAL);
217            ss->setTextureAttributeAndModes(0, texenv.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
218
219            #if !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
220                ss->setMode( GL_ALPHA_TEST, osg::StateAttribute::OFF );
221            #else
222                OSG_NOTICE<<"Warning: osgFX::AnisotropicLighting unable to disable GL_ALPHA_TEST."<<std::endl;
223            #endif
224
225            addPass(ss.get());
226        }
227
228    private:
229        int _lightnum;
230        osg::ref_ptr<osg::Texture2D> _texture;
231    };
232
233}
234
235
236AnisotropicLighting::AnisotropicLighting()
237:    Effect(),
238    _lightnum(0),
239    _texture(new osg::Texture2D)
240{
241    _texture->setImage(create_default_image());
242    _texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
243    _texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
244}
245
246AnisotropicLighting::AnisotropicLighting(const AnisotropicLighting& copy, const osg::CopyOp& copyop)
247:    Effect(copy, copyop),
248    _lightnum(copy._lightnum),
249    _texture(static_cast<osg::Texture2D *>(copyop(copy._texture.get())))
250{
251}
252
253bool AnisotropicLighting::define_techniques()
254{
255    addTechnique(new DefaultTechnique(_lightnum, _texture.get()));
256    return true;
257}
Note: See TracBrowser for help on using the browser.