root/OpenSceneGraph/trunk/src/osgUtil/GLObjectsVisitor.cpp @ 8360

Revision 8360, 5.0 kB (checked in by robert, 7 years ago)

From Stephane Lamoliatte, "Here is a patch that fix the strange bug describe on the osg-user group.
Finally it seems to not come from the empty geode. The origin of the problem seems to be the uniform initialization during the building of the program which call a glUseProgram.
If your scene never display the node that contains the shader and if there is no other shader on the scene, this "glUseProgram" is the only one that is called during your simulation. So, this shader is applied on all the scene.

I fix this bug by switching off the shader (by calling glUseProgram(0) ) during the compilation of a state which does not contain the shader.
"

  • 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#include <osgUtil/GLObjectsVisitor>
14#include <osg/Drawable>
15#include <osg/Notify>
16
17using namespace osg;
18using namespace osgUtil;
19
20GLObjectsVisitor::GLObjectsVisitor(Mode mode)
21{
22    setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
23
24    _mode = mode;
25
26}
27
28
29void GLObjectsVisitor::apply(osg::Node& node)
30{
31    if (node.getStateSet())
32    {
33        apply(*(node.getStateSet()));
34    }
35
36    traverse(node);
37}
38
39void GLObjectsVisitor::apply(osg::Geode& node)
40{
41    if (node.getStateSet())
42    {
43        apply(*(node.getStateSet()));
44    }
45
46    for(unsigned int i=0;i<node.getNumDrawables();++i)
47    {
48        Drawable* drawable = node.getDrawable(i);
49        if (drawable)
50        {
51            apply(*drawable);
52            if (drawable->getStateSet())
53            {
54                apply(*(drawable->getStateSet()));
55            }
56        }
57    }
58}
59
60void GLObjectsVisitor::apply(osg::Drawable& drawable)
61{
62    if (_drawablesAppliedSet.count(&drawable)!=0) return;
63   
64    _drawablesAppliedSet.insert(&drawable);
65
66    if (_mode&SWITCH_OFF_DISPLAY_LISTS)
67    {
68        drawable.setUseDisplayList(false);
69    }
70
71    if (_mode&SWITCH_ON_DISPLAY_LISTS)
72    {
73        drawable.setUseDisplayList(true);
74    }
75
76    if (_mode&COMPILE_DISPLAY_LISTS && _renderInfo.getState())
77    {
78        drawable.compileGLObjects(_renderInfo);
79    }
80
81    if (_mode&RELEASE_DISPLAY_LISTS)
82    {
83        drawable.releaseGLObjects(_renderInfo.getState());
84    }
85
86    if (_mode&SWITCH_ON_VERTEX_BUFFER_OBJECTS)
87    {
88        drawable.setUseVertexBufferObjects(true);
89    }
90
91    if (_mode&SWITCH_OFF_VERTEX_BUFFER_OBJECTS)
92    {
93        drawable.setUseVertexBufferObjects(false);
94    }
95}
96
97void GLObjectsVisitor::apply(osg::StateSet& stateset)
98{
99    if (_stateSetAppliedSet.count(&stateset)!=0) return;
100   
101    _stateSetAppliedSet.insert(&stateset);
102
103    if (_mode & COMPILE_STATE_ATTRIBUTES && _renderInfo.getState())
104    {
105        stateset.compileGLObjects(*_renderInfo.getState());
106       
107        osg::Program* program = dynamic_cast<osg::Program*>(stateset.getAttribute(osg::StateAttribute::PROGRAM));
108        if (program) _lastCompiledProgram = program;
109
110        if (_lastCompiledProgram.valid() && !stateset.getUniformList().empty())
111        {
112            osg::Program::PerContextProgram* pcp = _lastCompiledProgram->getPCP(_renderInfo.getState()->getContextID());
113            if (pcp)
114            {
115                pcp->useProgram();
116               
117                _renderInfo.getState()->setLastAppliedProgramObject(pcp);
118           
119                osg::StateSet::UniformList& ul = stateset.getUniformList();
120                for(osg::StateSet::UniformList::iterator itr = ul.begin();
121                    itr != ul.end();
122                    ++itr)
123                {
124                    pcp->apply(*(itr->second.first));
125                }
126            }
127        }
128        else if(_renderInfo.getState()->getLastAppliedProgramObject()){
129                           
130            GL2Extensions* extensions = GL2Extensions::Get(_renderInfo.getState()->getContextID(), true);
131            extensions->glUseProgram(0);
132            _renderInfo.getState()->setLastAppliedProgramObject(0);
133        }
134       
135    }
136
137    if (_mode & RELEASE_STATE_ATTRIBUTES)
138    {
139        stateset.releaseGLObjects(_renderInfo.getState());
140    }
141   
142    if (_mode & CHECK_BLACK_LISTED_MODES)
143    {
144        stateset.checkValidityOfAssociatedModes(*_renderInfo.getState());
145    }
146}
147
148GLObjectsOperation::GLObjectsOperation(GLObjectsVisitor::Mode mode):
149    osg::GraphicsOperation("GLObjectOperation",false),
150    _mode(mode)
151{
152}
153
154GLObjectsOperation::GLObjectsOperation(osg::Node* subgraph, GLObjectsVisitor::Mode mode):
155    osg::GraphicsOperation("GLObjectOperation",false),
156    _subgraph(subgraph),
157    _mode(mode)
158{
159}
160
161void GLObjectsOperation::operator () (osg::GraphicsContext* context)
162{
163    GLObjectsVisitor glObjectsVisitor(_mode);
164   
165    context->getState()->initializeExtensionProcs();
166
167    glObjectsVisitor.setState(context->getState());
168   
169    // osg::notify(osg::NOTICE)<<"GLObjectsOperation::before <<<<<<<<<<<"<<std::endl;
170    if (_subgraph.valid())
171    {
172        _subgraph->accept(glObjectsVisitor);
173    }
174    else
175    {
176        for(osg::GraphicsContext::Cameras::iterator itr = context->getCameras().begin();
177            itr != context->getCameras().end();
178            ++itr)
179        {
180            (*itr)->accept(glObjectsVisitor);
181        }
182    }
183    // osg::notify(osg::NOTICE)<<"GLObjectsOperation::after >>>>>>>>>>> "<<std::endl;
184}
Note: See TracBrowser for help on using the browser.