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

Revision 7913, 23.1 kB (checked in by robert, 6 years ago)

From Wojciech Lewandowski, "Attached is modified osgShadow::ShadowMap?. I changed following things:


1:
Shadow map camera sets ABSOLUTE_RF_INHERIT_VIEWPOINT refernce frame.


2:
Light Direction by matrix multiplications replaced with transform3x3 multiplication.


3:
I made DebugingHUD functional by adding special draw callback. Former version was simply drawing pale square.


4:
I was tempted to make 4 th change but decided to not do it. Instead I put it whith #if VIEW_DEPNDENT_TEXGEN. If you decide you may let it go.


When objects are not centered at 0,0,0 coord but in some distant location (for example at surface of earth ellipsoid) shadow texgen suffers from inadequate precision of float matrices. I changed that by premultiplying Texgen matrix (using OSG double matrices) with inverse modelview and applying it later with ModelView? identity matrix. This tweak may be appropriate for OverlayNode? texgen as well.


I left former version because I suspect that this change will make osgShadow::ShadowMap? view dependant. Currently texgen matrix remains the same no matter what View displays it. With my change it wuld be different for each view. This touches the subject of View Dependent Shadow Techniques that J-S asked recently."

  • 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->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
186
187        _camera->setCullCallback(new CameraCullCallback(this));
188
189        _camera->setClearMask(GL_DEPTH_BUFFER_BIT);
190        //_camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
191        _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
192        _camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
193
194        // set viewport
195        _camera->setViewport(0,0,_textureSize.x(),_textureSize.y());
196
197        // set the camera to render before the main camera.
198        _camera->setRenderOrder(osg::Camera::PRE_RENDER);
199
200        // tell the camera to use OpenGL frame buffer object where supported.
201        _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
202        //_camera->setRenderTargetImplementation(osg::Camera::SEPERATE_WINDOW);
203
204        // attach the texture and use it as the color buffer.
205        _camera->attach(osg::Camera::DEPTH_BUFFER, _texture.get());
206
207        osg::StateSet* stateset = _camera->getOrCreateStateSet();
208
209
210#if 1
211        // cull front faces so that only backfaces contribute to depth map
212
213        osg::ref_ptr<osg::CullFace> cull_face = new osg::CullFace;
214        cull_face->setMode(osg::CullFace::FRONT);
215        stateset->setAttribute(cull_face.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
216        stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
217
218        // negative polygonoffset - move the backface nearer to the eye point so that backfaces
219        // shadow themselves
220        float factor = -1.0f;
221        float units = -1.0f;
222
223        osg::ref_ptr<osg::PolygonOffset> polygon_offset = new osg::PolygonOffset;
224        polygon_offset->setFactor(factor);
225        polygon_offset->setUnits(units);
226        stateset->setAttribute(polygon_offset.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
227        stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
228#else
229        // disabling cull faces so that only front and backfaces contribute to depth map
230        stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
231
232        // negative polygonoffset - move the backface nearer to the eye point
233        // so that front faces do not shadow themselves.
234        float factor = 1.0f;
235        float units = 1.0f;
236
237        osg::ref_ptr<osg::PolygonOffset> polygon_offset = new osg::PolygonOffset;
238        polygon_offset->setFactor(factor);
239        polygon_offset->setUnits(units);
240        stateset->setAttribute(polygon_offset.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
241        stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
242#endif
243    }
244
245    {
246        _stateset = new osg::StateSet;       
247        _stateset->setTextureAttributeAndModes(_shadowTextureUnit,_texture.get(),osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
248        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
249        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
250        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
251        _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
252
253        _texgen = new osg::TexGen;
254
255        // add Program, when empty of Shaders then we are using fixed functionality
256        _program = new osg::Program;
257        _stateset->setAttribute(_program.get());
258
259        // create default shaders if needed
260        createShaders();
261
262        // add the shader list to the program
263        for(ShaderList::const_iterator itr=_shaderList.begin();
264            itr!=_shaderList.end();
265            ++itr)
266        {
267            _program->addShader(itr->get());
268        }
269
270        // create own uniforms
271        createUniforms();
272
273        // add the uniform list to the stateset
274        for(UniformList::const_iterator itr=_uniformList.begin();
275            itr!=_uniformList.end();
276            ++itr)
277        {
278            _stateset->addUniform(itr->get());
279        }
280
281        {
282            // fake texture for baseTexture, add a fake texture
283            // we support by default at least one texture layer
284            // without this fake texture we can not support
285            // textured and not textured scene
286
287            // TODO: at the moment the PSSM supports just one texture layer in the GLSL shader, multitexture are
288            //       not yet supported !
289
290            osg::Image* image = new osg::Image;
291            // allocate the image data, noPixels x 1 x 1 with 4 rgba floats - equivilant to a Vec4!
292            int noPixels = 1;
293            image->allocateImage(noPixels,1,1,GL_RGBA,GL_FLOAT);
294            image->setInternalTextureFormat(GL_RGBA);
295            // fill in the image data.
296            osg::Vec4* dataPtr = (osg::Vec4*)image->data();
297            osg::Vec4 color(1,1,1,1);
298            *dataPtr = color;
299            // make fake texture
300            osg::Texture2D* fakeTex = new osg::Texture2D;
301            fakeTex->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE);
302            fakeTex->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE);
303            fakeTex->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
304            fakeTex->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
305            fakeTex->setImage(image);
306            // add fake texture
307            _stateset->setTextureAttribute(_baseTextureUnit,fakeTex,osg::StateAttribute::ON);
308            _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_1D,osg::StateAttribute::OFF);
309            _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_2D,osg::StateAttribute::ON);
310            _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_3D,osg::StateAttribute::OFF);
311        }
312    }
313
314    _dirty = false;
315}
316
317
318void ShadowMap::update(osg::NodeVisitor& nv)
319{
320    _shadowedScene->osg::Group::traverse(nv);
321}
322
323void ShadowMap::cull(osgUtil::CullVisitor& cv)
324{
325    // record the traversal mask on entry so we can reapply it later.
326    unsigned int traversalMask = cv.getTraversalMask();
327
328    osgUtil::RenderStage* orig_rs = cv.getRenderStage();
329
330    // do traversal of shadow receiving scene which does need to be decorated by the shadow map
331    {
332        cv.pushStateSet(_stateset.get());
333
334        _shadowedScene->osg::Group::traverse(cv);
335
336        cv.popStateSet();
337
338    }
339
340    // need to compute view frustum for RTT camera.
341    // 1) get the light position
342    // 2) get the center and extents of the view frustum
343
344    const osg::Light* selectLight = 0;
345    osg::Vec4 lightpos;
346    osg::Vec3 lightDir;
347
348    //MR testing giving a specific light
349    osgUtil::PositionalStateContainer::AttrMatrixList& aml = orig_rs->getPositionalStateContainer()->getAttrMatrixList();
350    for(osgUtil::PositionalStateContainer::AttrMatrixList::iterator itr = aml.begin();
351        itr != aml.end();
352        ++itr)
353    {
354        const osg::Light* light = dynamic_cast<const osg::Light*>(itr->first.get());
355        if (light)
356        {
357            if( _light.valid()) {
358                if( _light.get() == light )
359                    selectLight = light;
360                else
361                    continue;
362            }
363            else
364                selectLight = light;
365
366            osg::RefMatrix* matrix = itr->second.get();
367            if (matrix)
368            {
369                lightpos = light->getPosition() * (*matrix);
370                lightDir = osg::Matrix::transform3x3( light->getDirection(), *matrix );
371            }
372            else 
373            {
374                lightpos = light->getPosition();
375                lightDir = light->getDirection();
376            }
377
378        }
379    }
380
381    osg::Matrix eyeToWorld;
382    eyeToWorld.invert(*cv.getModelViewMatrix());
383
384    lightpos = lightpos * eyeToWorld;     
385    lightDir = osg::Matrix::transform3x3( lightDir, eyeToWorld );
386    lightDir.normalize();
387
388    if (selectLight)
389    {
390
391        // set to ambient on light to black so that the ambient bias uniform can take it's affect
392        const_cast<osg::Light*>(selectLight)->setAmbient(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
393
394        //std::cout<<"----- VxOSG::ShadowMap selectLight spot cutoff "<<selectLight->getSpotCutoff()<<std::endl;
395
396        if(selectLight->getSpotCutoff() < 180.0f)   // spotlight, then we don't need the bounding box
397        {
398            osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z());
399            float spotAngle = selectLight->getSpotCutoff();
400            _camera->setProjectionMatrixAsPerspective(spotAngle, 1.0, 0.1, 1000.0);
401            _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f));
402        }
403        else
404        {
405            // get the bounds of the model.   
406            osg::ComputeBoundsVisitor cbbv(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
407            cbbv.setTraversalMask(getShadowedScene()->getCastsShadowTraversalMask());
408
409            _shadowedScene->osg::Group::traverse(cbbv);
410
411            osg::BoundingBox bb = cbbv.getBoundingBox();
412
413            if (lightpos[3]!=0.0)   // point light
414            {
415                osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z());
416
417                float centerDistance = (position-bb.center()).length();
418
419                float znear = centerDistance-bb.radius();
420                float zfar  = centerDistance+bb.radius();
421                float zNearRatio = 0.001f;
422                if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
423
424                float top   = (bb.radius()/centerDistance)*znear;
425                float right = top;
426
427                _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
428                _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f));
429            }
430            else    // directional light
431            {
432                // make an orthographic projection
433                osg::Vec3 lightDir(lightpos.x(), lightpos.y(), lightpos.z());
434                lightDir.normalize();
435
436                // set the position far away along the light direction
437                osg::Vec3 position = bb.center() + lightDir * bb.radius() * 2;
438
439                float centerDistance = (position-bb.center()).length();
440
441                float znear = centerDistance-bb.radius();
442                float zfar  = centerDistance+bb.radius();
443                float zNearRatio = 0.001f;
444                if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
445
446                float top   = bb.radius();
447                float right = top;
448
449                _camera->setProjectionMatrixAsOrtho(-right, right, -top, top, znear, zfar);
450                _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f));
451            }
452
453
454        }
455
456        cv.setTraversalMask( traversalMask &
457            getShadowedScene()->getCastsShadowTraversalMask() );
458
459        // do RTT camera traversal
460        _camera->accept(cv);
461
462        _texgen->setMode(osg::TexGen::EYE_LINEAR);
463
464#if IMPROVE_TEXGEN_PRECISION
465        // compute the matrix which takes a vertex from local coords into tex coords
466        // We actually use two matrices one used to define texgen
467        // and second that will be used as modelview when appling to OpenGL
468        _texgen->setPlanesFromMatrix( _camera->getProjectionMatrix() *
469                                      osg::Matrix::translate(1.0,1.0,1.0) *
470                                      osg::Matrix::scale(0.5f,0.5f,0.5f) );
471
472        // Place texgen with modelview which removes big offsets (making it float friendly)
473        osg::RefMatrix * refMatrix = new osg::RefMatrix
474            ( _camera->getInverseViewMatrix() * *cv.getModelViewMatrix() );
475
476        cv.getRenderStage()->getPositionalStateContainer()->
477             addPositionedTextureAttribute( _shadowTextureUnit, refMatrix, _texgen.get() );
478#else 
479        // compute the matrix which takes a vertex from local coords into tex coords
480        // will use this later to specify osg::TexGen..
481        osg::Matrix MVPT = _camera->getViewMatrix() *
482               _camera->getProjectionMatrix() *
483               osg::Matrix::translate(1.0,1.0,1.0) *
484               osg::Matrix::scale(0.5f,0.5f,0.5f);
485
486        _texgen->setPlanesFromMatrix(MVPT);
487
488        orig_rs->getPositionalStateContainer()->addPositionedTextureAttribute(_shadowTextureUnit, cv.getModelViewMatrix(), _texgen.get());
489#endif
490    } // if(selectLight)
491
492
493    // reapply the original traversal mask
494    cv.setTraversalMask( traversalMask );
495}
496
497void ShadowMap::cleanSceneGraph()
498{
499}
500
501///////////////////// Debug Methods
502
503////////////////////////////////////////////////////////////////////////////////
504// Callback used by debugging hud to display Shadow Map in color buffer
505// OSG does not allow to use the same GL Texture Id with different glTexParams.
506// Callback simply turns shadow compare mode off via GL while rendering hud and
507// restores it afterwards.
508////////////////////////////////////////////////////////////////////////////////
509class DrawableDrawWithDepthShadowComparisonOffCallback:
510    public osg::Drawable::DrawCallback
511{
512public:
513    //
514    DrawableDrawWithDepthShadowComparisonOffCallback
515        ( osg::Texture2D * texture, unsigned stage = 0 )
516            : _texture( texture ), _stage( stage )
517    {
518    }
519
520    virtual void drawImplementation
521        ( osg::RenderInfo & ri,const osg::Drawable* drawable ) const
522    {
523        if( _texture.valid() ) {
524            // make sure proper texture is currently applied
525            ri.getState()->applyTextureAttribute( _stage, _texture.get() );
526
527            // Turn off depth comparison mode
528            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
529                             GL_NONE );
530        }
531
532        drawable->drawImplementation(ri);
533
534        if( _texture.valid() ) {
535            // Turn it back on
536            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
537                             GL_COMPARE_R_TO_TEXTURE_ARB );
538        }
539    }
540
541    unsigned                       _stage;
542    osg::ref_ptr< osg::Texture2D > _texture;
543};
544////////////////////////////////////////////////////////////////////////////////
545osg::ref_ptr<osg::Camera> ShadowMap::makeDebugHUD()
546{
547    // Make sure we attach initialized texture to HUD
548    if( !_texture.valid() )    init();
549
550    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
551
552    osg::Vec2 size(1280, 1024);
553    // set the projection matrix
554    camera->setProjectionMatrix(osg::Matrix::ortho2D(0,size.x(),0,size.y()));
555
556    // set the view matrix   
557    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
558    camera->setViewMatrix(osg::Matrix::identity());
559
560    // only clear the depth buffer
561    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
562    camera->setClearColor(osg::Vec4(0.2f, 0.3f, 0.5f, 0.2f));
563    //camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
564
565    // draw subgraph after main camera view.
566    camera->setRenderOrder(osg::Camera::POST_RENDER);
567
568    // we don't want the camera to grab event focus from the viewers main camera(s).
569    camera->setAllowEventFocus(false);
570
571    osg::Geode* geode = new osg::Geode;
572
573    osg::Vec3 position(10.0f,size.y()-100.0f,0.0f);
574    osg::Vec3 delta(0.0f,-120.0f,0.0f);
575    float length = 300.0f;
576
577    // turn the text off to avoid linking with osgText
578#if 0
579    std::string timesFont("fonts/arial.ttf");
580
581    {
582        osgText::Text* text = new  osgText::Text;
583        geode->addDrawable( text );
584
585        text->setFont(timesFont);
586        text->setPosition(position);
587        text->setText("Shadow Map HUD");
588
589        position += delta;
590    }
591#endif
592
593    osg::Vec3 widthVec(length, 0.0f, 0.0f);
594    osg::Vec3 depthVec(0.0f,length, 0.0f);
595    osg::Vec3 centerBase( 10.0f + length/2, size.y()-length/2, 0.0f);
596    centerBase += delta;
597
598    osg::Geometry *geometry = osg::createTexturedQuadGeometry
599        ( centerBase-widthVec*0.5f-depthVec*0.5f, widthVec, depthVec );
600
601    geode->addDrawable( geometry );
602
603    geometry->setDrawCallback
604        ( new DrawableDrawWithDepthShadowComparisonOffCallback( _texture.get() ) );
605
606    osg::StateSet* stateset = geode->getOrCreateStateSet();
607
608    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
609    stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
610    //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
611    stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
612
613    // test with regular texture
614    //stateset->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile("Images/lz.rgb")));
615
616    stateset->setTextureAttributeAndModes(0,_texture.get(),osg::StateAttribute::ON);
617
618    //test to check the texture coordinates generated during shadow pass
619#if 0
620    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
621    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
622    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
623    stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
624
625    // create TexGen node
626    osg::ref_ptr<osg::TexGenNode> texGenNode = new osg::TexGenNode;
627    texGenNode->setTextureUnit(_shadowTextureUnit);
628    texGenNode->setTexGen(_texgen.get());
629    camera->addChild(texGenNode.get());
630#endif
631    //shader for correct display
632
633    osg::ref_ptr<osg::Program> program = new osg::Program;
634    stateset->setAttribute(program.get());
635
636    osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_debugHUD);
637    program->addShader(fragment_shader);
638
639    camera->addChild(geode);
640
641    return camera;
642}
643
644//////////////////////// End Debug Section
Note: See TracBrowser for help on using the browser.