root/OpenSceneGraph/trunk/src/osgShadow/ShadowMap.cpp @ 7970

Revision 7970, 23.2 kB (checked in by robert, 7 years ago)

Set the CullSettings::InhertianceMask? to 0x0 as temporary measure till we
work out the best scheme to use w.r.t inhertiance of CullSettins?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osgShadow/ShadowMap>
15#include <osgShadow/ShadowedScene>
16#include <osg/Notify>
17#include <osg/ComputeBoundsVisitor>
18#include <osg/PolygonOffset>
19#include <osg/CullFace>
20#include <osg/io_utils>
21
22using namespace osgShadow;
23
24#include <iostream>
25//for debug
26#include <osg/LightSource>
27#include <osg/PolygonMode>
28#include <osg/Geometry>
29#include <osgDB/ReadFile>
30#include <osgText/Text>
31
32#define IMPROVE_TEXGEN_PRECISION 1
33
34//////////////////////////////////////////////////////////////////
35// fragment shader
36//
37static const char fragmentShaderSource_noBaseTexture[] =
38    "uniform sampler2DShadow osgShadow_shadowTexture; \n"
39    "uniform vec2 osgShadow_ambientBias; \n"
40    "\n"
41    "void main(void) \n"
42    "{ \n"
43    "    gl_FragColor = gl_Color * (osgShadow_ambientBias.x + shadow2DProj( osgShadow_shadowTexture, gl_TexCoord[0] ) * osgShadow_ambientBias.y); \n"
44    "}\n";
45
46//////////////////////////////////////////////////////////////////
47// fragment shader
48//
49static const char fragmentShaderSource_withBaseTexture[] =
50    "uniform sampler2D osgShadow_baseTexture; \n"
51    "uniform sampler2DShadow osgShadow_shadowTexture; \n"
52    "uniform vec2 osgShadow_ambientBias; \n"
53    "\n"
54    "void main(void) \n"
55    "{ \n"
56    "    vec4 color = gl_Color * texture2D( osgShadow_baseTexture, gl_TexCoord[0].xy ); \n"
57    "    gl_FragColor = color * (osgShadow_ambientBias.x + shadow2DProj( osgShadow_shadowTexture, gl_TexCoord[1] ) * osgShadow_ambientBias.y); \n"
58    "}\n";
59
60//////////////////////////////////////////////////////////////////
61// fragment shader
62//
63static const char fragmentShaderSource_debugHUD_texcoord[] =
64    "uniform sampler2D osgShadow_shadowTexture; \n"
65    " \n"
66    "void main(void) \n"
67    "{ \n"
68    "   vec4 texCoord = gl_TexCoord[1].xyzw; \n"
69    "   float value = texCoord.z / texCoord.w; \n"
70    "   gl_FragColor = vec4( value, value, value, 1.0 ); \n"
71    "} \n";
72
73static const char fragmentShaderSource_debugHUD[] =
74    "uniform sampler2D osgShadow_shadowTexture; \n"
75    " \n"
76    "void main(void) \n"
77    "{ \n"
78    "   vec4 texResult = texture2D(osgShadow_shadowTexture, gl_TexCoord[0].st ); \n"
79    "   float value = texResult.r; \n"
80    "   gl_FragColor = vec4( value, value, value, 0.8 ); \n"
81    "} \n";
82
83ShadowMap::ShadowMap():
84_baseTextureUnit(0),
85    _shadowTextureUnit(1),
86    _ambientBias(0.5f,0.5f),
87    _textureSize(1024,1024)
88{
89}
90
91ShadowMap::ShadowMap(const ShadowMap& copy, const osg::CopyOp& copyop):
92ShadowTechnique(copy,copyop),
93    _baseTextureUnit(copy._baseTextureUnit),
94    _shadowTextureUnit(copy._shadowTextureUnit),
95    _ambientBias(copy._ambientBias),
96    _textureSize(copy._textureSize)
97{
98}
99
100void ShadowMap::setTextureUnit(unsigned int unit)
101{
102    _shadowTextureUnit = unit;
103}
104
105void ShadowMap::setAmbientBias(const osg::Vec2& ambientBias)
106{
107    _ambientBias = ambientBias;
108    if (_ambientBiasUniform.valid()) _ambientBiasUniform->set(_ambientBias);
109}
110
111void ShadowMap::setTextureSize(const osg::Vec2s& textureSize)
112{
113    _textureSize = textureSize;
114    dirty();
115}
116
117void ShadowMap::setLight(osg::Light* light)
118{
119    _light = light;
120}
121
122
123void ShadowMap::setLight(osg::LightSource* ls)
124{
125    _ls = ls;
126    _light = _ls->getLight();
127}
128
129void ShadowMap::createUniforms()
130{
131    _uniformList.clear();
132
133    osg::Uniform* baseTextureSampler = new osg::Uniform("osgShadow_baseTexture",(int)_baseTextureUnit);
134    _uniformList.push_back(baseTextureSampler);
135
136    osg::Uniform* shadowTextureSampler = new osg::Uniform("osgShadow_shadowTexture",(int)_shadowTextureUnit);
137    _uniformList.push_back(shadowTextureSampler);
138
139    _ambientBiasUniform = new osg::Uniform("osgShadow_ambientBias",_ambientBias);
140    _uniformList.push_back(_ambientBiasUniform.get());
141
142}
143
144void ShadowMap::createShaders()
145{
146    // if we are not given shaders, use the default
147    if( _shaderList.empty() )
148    {
149        if (_shadowTextureUnit==0)
150        {
151            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_noBaseTexture);
152            _shaderList.push_back(fragment_shader);
153        }
154        else
155        {
156            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_withBaseTexture);
157            _shaderList.push_back(fragment_shader);
158
159        }
160    }
161}
162
163void ShadowMap::init()
164{
165    if (!_shadowedScene) return;
166
167    _texture = new osg::Texture2D;
168    _texture->setTextureSize(_textureSize.x(), _textureSize.y());
169    _texture->setInternalFormat(GL_DEPTH_COMPONENT);
170    _texture->setShadowComparison(true);
171    _texture->setShadowTextureMode(osg::Texture2D::LUMINANCE);
172    _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
173    _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
174
175    // the shadow comparison should fail if object is outside the texture
176    _texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
177    _texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
178    _texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
179
180    // set up the render to texture camera.
181    {
182        // create the camera
183        _camera = new osg::Camera;
184
185        _camera->setInheritanceMask(0x0);
186       
187        _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
188
189        _camera->setCullCallback(new CameraCullCallback(this));
190
191        _camera->setClearMask(GL_DEPTH_BUFFER_BIT);
192        //_camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
193        _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
194        _camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
195
196        // set viewport
197        _camera->setViewport(0,0,_textureSize.x(),_textureSize.y());
198
199        // set the camera to render before the main camera.
200        _camera->setRenderOrder(osg::Camera::PRE_RENDER);
201
202        // tell the camera to use OpenGL frame buffer object where supported.
203        _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
204        //_camera->setRenderTargetImplementation(osg::Camera::SEPERATE_WINDOW);
205
206        // attach the texture and use it as the color buffer.
207        _camera->attach(osg::Camera::DEPTH_BUFFER, _texture.get());
208
209        osg::StateSet* stateset = _camera->getOrCreateStateSet();
210
211
212#if 1
213        // cull front faces so that only backfaces contribute to depth map
214
215        osg::ref_ptr<osg::CullFace> cull_face = new osg::CullFace;
216        cull_face->setMode(osg::CullFace::FRONT);
217        stateset->setAttribute(cull_face.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
218        stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
219
220        // negative polygonoffset - move the backface nearer to the eye point so that backfaces
221        // shadow themselves
222        float factor = -1.0f;
223        float units = -1.0f;
224
225        osg::ref_ptr<osg::PolygonOffset> polygon_offset = new osg::PolygonOffset;
226        polygon_offset->setFactor(factor);
227        polygon_offset->setUnits(units);
228        stateset->setAttribute(polygon_offset.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
229        stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
230#else
231        // disabling cull faces so that only front and backfaces contribute to depth map
232        stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
233
234        // negative polygonoffset - move the backface nearer to the eye point
235        // so that front faces do not shadow themselves.
236        float factor = 1.0f;
237        float units = 1.0f;
238
239        osg::ref_ptr<osg::PolygonOffset> polygon_offset = new osg::PolygonOffset;
240        polygon_offset->setFactor(factor);
241        polygon_offset->setUnits(units);
242        stateset->setAttribute(polygon_offset.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
243        stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
244#endif
245    }
246
247    {
248        _stateset = new osg::StateSet;       
249        _stateset->setTextureAttributeAndModes(_shadowTextureUnit,_texture.get(),osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
250        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
251        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
252        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
253        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
254
255        _texgen = new osg::TexGen;
256
257        // add Program, when empty of Shaders then we are using fixed functionality
258        _program = new osg::Program;
259        _stateset->setAttribute(_program.get());
260
261        // create default shaders if needed
262        createShaders();
263
264        // add the shader list to the program
265        for(ShaderList::const_iterator itr=_shaderList.begin();
266            itr!=_shaderList.end();
267            ++itr)
268        {
269            _program->addShader(itr->get());
270        }
271
272        // create own uniforms
273        createUniforms();
274
275        // add the uniform list to the stateset
276        for(UniformList::const_iterator itr=_uniformList.begin();
277            itr!=_uniformList.end();
278            ++itr)
279        {
280            _stateset->addUniform(itr->get());
281        }
282
283        {
284            // fake texture for baseTexture, add a fake texture
285            // we support by default at least one texture layer
286            // without this fake texture we can not support
287            // textured and not textured scene
288
289            // TODO: at the moment the PSSM supports just one texture layer in the GLSL shader, multitexture are
290            //       not yet supported !
291
292            osg::Image* image = new osg::Image;
293            // allocate the image data, noPixels x 1 x 1 with 4 rgba floats - equivilant to a Vec4!
294            int noPixels = 1;
295            image->allocateImage(noPixels,1,1,GL_RGBA,GL_FLOAT);
296            image->setInternalTextureFormat(GL_RGBA);
297            // fill in the image data.
298            osg::Vec4* dataPtr = (osg::Vec4*)image->data();
299            osg::Vec4 color(1,1,1,1);
300            *dataPtr = color;
301            // make fake texture
302            osg::Texture2D* fakeTex = new osg::Texture2D;
303            fakeTex->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE);
304            fakeTex->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE);
305            fakeTex->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
306            fakeTex->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
307            fakeTex->setImage(image);
308            // add fake texture
309            _stateset->setTextureAttribute(_baseTextureUnit,fakeTex,osg::StateAttribute::ON);
310            _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_1D,osg::StateAttribute::OFF);
311            _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_2D,osg::StateAttribute::ON);
312            _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_3D,osg::StateAttribute::OFF);
313        }
314    }
315
316    _dirty = false;
317}
318
319
320void ShadowMap::update(osg::NodeVisitor& nv)
321{
322    _shadowedScene->osg::Group::traverse(nv);
323}
324
325void ShadowMap::cull(osgUtil::CullVisitor& cv)
326{
327    // record the traversal mask on entry so we can reapply it later.
328    unsigned int traversalMask = cv.getTraversalMask();
329
330    osgUtil::RenderStage* orig_rs = cv.getRenderStage();
331
332    // do traversal of shadow receiving scene which does need to be decorated by the shadow map
333    {
334        cv.pushStateSet(_stateset.get());
335
336        _shadowedScene->osg::Group::traverse(cv);
337
338        cv.popStateSet();
339
340    }
341
342    // need to compute view frustum for RTT camera.
343    // 1) get the light position
344    // 2) get the center and extents of the view frustum
345
346    const osg::Light* selectLight = 0;
347    osg::Vec4 lightpos;
348    osg::Vec3 lightDir;
349
350    //MR testing giving a specific light
351    osgUtil::PositionalStateContainer::AttrMatrixList& aml = orig_rs->getPositionalStateContainer()->getAttrMatrixList();
352    for(osgUtil::PositionalStateContainer::AttrMatrixList::iterator itr = aml.begin();
353        itr != aml.end();
354        ++itr)
355    {
356        const osg::Light* light = dynamic_cast<const osg::Light*>(itr->first.get());
357        if (light)
358        {
359            if( _light.valid()) {
360                if( _light.get() == light )
361                    selectLight = light;
362                else
363                    continue;
364            }
365            else
366                selectLight = light;
367
368            osg::RefMatrix* matrix = itr->second.get();
369            if (matrix)
370            {
371                lightpos = light->getPosition() * (*matrix);
372                lightDir = osg::Matrix::transform3x3( light->getDirection(), *matrix );
373            }
374            else 
375            {
376                lightpos = light->getPosition();
377                lightDir = light->getDirection();
378            }
379
380        }
381    }
382
383    osg::Matrix eyeToWorld;
384    eyeToWorld.invert(*cv.getModelViewMatrix());
385
386    lightpos = lightpos * eyeToWorld;     
387    lightDir = osg::Matrix::transform3x3( lightDir, eyeToWorld );
388    lightDir.normalize();
389
390    if (selectLight)
391    {
392
393        // set to ambient on light to black so that the ambient bias uniform can take it's affect
394        const_cast<osg::Light*>(selectLight)->setAmbient(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
395
396        //std::cout<<"----- VxOSG::ShadowMap selectLight spot cutoff "<<selectLight->getSpotCutoff()<<std::endl;
397
398        if(selectLight->getSpotCutoff() < 180.0f)   // spotlight, then we don't need the bounding box
399        {
400            osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z());
401            float spotAngle = selectLight->getSpotCutoff();
402            _camera->setProjectionMatrixAsPerspective(spotAngle, 1.0, 0.1, 1000.0);
403            _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f));
404        }
405        else
406        {
407            // get the bounds of the model.   
408            osg::ComputeBoundsVisitor cbbv(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
409            cbbv.setTraversalMask(getShadowedScene()->getCastsShadowTraversalMask());
410
411            _shadowedScene->osg::Group::traverse(cbbv);
412
413            osg::BoundingBox bb = cbbv.getBoundingBox();
414
415            if (lightpos[3]!=0.0)   // point light
416            {
417                osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z());
418
419                float centerDistance = (position-bb.center()).length();
420
421                float znear = centerDistance-bb.radius();
422                float zfar  = centerDistance+bb.radius();
423                float zNearRatio = 0.001f;
424                if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
425
426                float top   = (bb.radius()/centerDistance)*znear;
427                float right = top;
428
429                _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
430                _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f));
431            }
432            else    // directional light
433            {
434                // make an orthographic projection
435                osg::Vec3 lightDir(lightpos.x(), lightpos.y(), lightpos.z());
436                lightDir.normalize();
437
438                // set the position far away along the light direction
439                osg::Vec3 position = bb.center() + lightDir * bb.radius() * 2;
440
441                float centerDistance = (position-bb.center()).length();
442
443                float znear = centerDistance-bb.radius();
444                float zfar  = centerDistance+bb.radius();
445                float zNearRatio = 0.001f;
446                if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
447
448                float top   = bb.radius();
449                float right = top;
450
451                _camera->setProjectionMatrixAsOrtho(-right, right, -top, top, znear, zfar);
452                _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f));
453            }
454
455
456        }
457
458        cv.setTraversalMask( traversalMask &
459            getShadowedScene()->getCastsShadowTraversalMask() );
460
461        // do RTT camera traversal
462        _camera->accept(cv);
463
464        _texgen->setMode(osg::TexGen::EYE_LINEAR);
465
466#if IMPROVE_TEXGEN_PRECISION
467        // compute the matrix which takes a vertex from local coords into tex coords
468        // We actually use two matrices one used to define texgen
469        // and second that will be used as modelview when appling to OpenGL
470        _texgen->setPlanesFromMatrix( _camera->getProjectionMatrix() *
471                                      osg::Matrix::translate(1.0,1.0,1.0) *
472                                      osg::Matrix::scale(0.5f,0.5f,0.5f) );
473
474        // Place texgen with modelview which removes big offsets (making it float friendly)
475        osg::RefMatrix * refMatrix = new osg::RefMatrix
476            ( _camera->getInverseViewMatrix() * *cv.getModelViewMatrix() );
477
478        cv.getRenderStage()->getPositionalStateContainer()->
479             addPositionedTextureAttribute( _shadowTextureUnit, refMatrix, _texgen.get() );
480#else 
481        // compute the matrix which takes a vertex from local coords into tex coords
482        // will use this later to specify osg::TexGen..
483        osg::Matrix MVPT = _camera->getViewMatrix() *
484               _camera->getProjectionMatrix() *
485               osg::Matrix::translate(1.0,1.0,1.0) *
486               osg::Matrix::scale(0.5f,0.5f,0.5f);
487
488        _texgen->setPlanesFromMatrix(MVPT);
489
490        orig_rs->getPositionalStateContainer()->addPositionedTextureAttribute(_shadowTextureUnit, cv.getModelViewMatrix(), _texgen.get());
491#endif
492    } // if(selectLight)
493
494
495    // reapply the original traversal mask
496    cv.setTraversalMask( traversalMask );
497}
498
499void ShadowMap::cleanSceneGraph()
500{
501}
502
503///////////////////// Debug Methods
504
505////////////////////////////////////////////////////////////////////////////////
506// Callback used by debugging hud to display Shadow Map in color buffer
507// OSG does not allow to use the same GL Texture Id with different glTexParams.
508// Callback simply turns shadow compare mode off via GL while rendering hud and
509// restores it afterwards.
510////////////////////////////////////////////////////////////////////////////////
511class DrawableDrawWithDepthShadowComparisonOffCallback:
512    public osg::Drawable::DrawCallback
513{
514public:
515    //
516    DrawableDrawWithDepthShadowComparisonOffCallback
517        ( osg::Texture2D * texture, unsigned stage = 0 )
518            : _texture( texture ), _stage( stage )
519    {
520    }
521
522    virtual void drawImplementation
523        ( osg::RenderInfo & ri,const osg::Drawable* drawable ) const
524    {
525        if( _texture.valid() ) {
526            // make sure proper texture is currently applied
527            ri.getState()->applyTextureAttribute( _stage, _texture.get() );
528
529            // Turn off depth comparison mode
530            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
531                             GL_NONE );
532        }
533
534        drawable->drawImplementation(ri);
535
536        if( _texture.valid() ) {
537            // Turn it back on
538            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
539                             GL_COMPARE_R_TO_TEXTURE_ARB );
540        }
541    }
542
543    unsigned                       _stage;
544    osg::ref_ptr< osg::Texture2D > _texture;
545};
546////////////////////////////////////////////////////////////////////////////////
547osg::ref_ptr<osg::Camera> ShadowMap::makeDebugHUD()
548{
549    // Make sure we attach initialized texture to HUD
550    if( !_texture.valid() )    init();
551
552    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
553
554    camera->setInheritanceMask(0x0);
555
556    osg::Vec2 size(1280, 1024);
557    // set the projection matrix
558    camera->setProjectionMatrix(osg::Matrix::ortho2D(0,size.x(),0,size.y()));
559
560    // set the view matrix   
561    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
562    camera->setViewMatrix(osg::Matrix::identity());
563
564    // only clear the depth buffer
565    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
566    camera->setClearColor(osg::Vec4(0.2f, 0.3f, 0.5f, 0.2f));
567    //camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
568
569    // draw subgraph after main camera view.
570    camera->setRenderOrder(osg::Camera::POST_RENDER);
571
572    // we don't want the camera to grab event focus from the viewers main camera(s).
573    camera->setAllowEventFocus(false);
574
575    osg::Geode* geode = new osg::Geode;
576
577    osg::Vec3 position(10.0f,size.y()-100.0f,0.0f);
578    osg::Vec3 delta(0.0f,-120.0f,0.0f);
579    float length = 300.0f;
580
581    // turn the text off to avoid linking with osgText
582#if 0
583    std::string timesFont("fonts/arial.ttf");
584
585    {
586        osgText::Text* text = new  osgText::Text;
587        geode->addDrawable( text );
588
589        text->setFont(timesFont);
590        text->setPosition(position);
591        text->setText("Shadow Map HUD");
592
593        position += delta;
594    }
595#endif
596
597    osg::Vec3 widthVec(length, 0.0f, 0.0f);
598    osg::Vec3 depthVec(0.0f,length, 0.0f);
599    osg::Vec3 centerBase( 10.0f + length/2, size.y()-length/2, 0.0f);
600    centerBase += delta;
601
602    osg::Geometry *geometry = osg::createTexturedQuadGeometry
603        ( centerBase-widthVec*0.5f-depthVec*0.5f, widthVec, depthVec );
604
605    geode->addDrawable( geometry );
606
607    geometry->setDrawCallback
608        ( new DrawableDrawWithDepthShadowComparisonOffCallback( _texture.get() ) );
609
610    osg::StateSet* stateset = geode->getOrCreateStateSet();
611
612    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
613    stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
614    //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
615    stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
616
617    // test with regular texture
618    //stateset->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile("Images/lz.rgb")));
619
620    stateset->setTextureAttributeAndModes(0,_texture.get(),osg::StateAttribute::ON);
621
622    //test to check the texture coordinates generated during shadow pass
623#if 0
624    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
625    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
626    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
627    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
628
629    // create TexGen node
630    osg::ref_ptr<osg::TexGenNode> texGenNode = new osg::TexGenNode;
631    texGenNode->setTextureUnit(_shadowTextureUnit);
632    texGenNode->setTexGen(_texgen.get());
633    camera->addChild(texGenNode.get());
634#endif
635    //shader for correct display
636
637    osg::ref_ptr<osg::Program> program = new osg::Program;
638    stateset->setAttribute(program.get());
639
640    osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_debugHUD);
641    program->addShader(fragment_shader);
642
643    camera->addChild(geode);
644
645    return camera;
646}
647
648//////////////////////// End Debug Section
Note: See TracBrowser for help on using the browser.