码迷,mamicode.com
首页 > 其他好文 > 详细

【转】osgCallback的实现方法

时间:2018-11-30 00:37:59      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:.sh   sse   rap   notice   lca   val   customize   filename   执行函数   

综述,可以得出回调的编写方法:
1、编写用户结构体,继承OSG中响应的虚函数结构图,如osg::NodeCallback;
2、重载回调执行函数,根据回调种类的不同,执行函数的名称也不同,可以参考osgCallBack中的设置
3、注意在回调执行的过程中,有一些必要的系统操作需要交由用户来完成,例如readNodeImplementation,Drawable::drawImplementation,traverse等,否则系统本身的渲染工作可能会不正常。
编译运行osgcallback之后,可以看到控制台不断输出各种回调的执行结果,用户可以根据自己的需要在不同的时间段进入不同的回调来完成所需的工作。   
参考文章地址:http://www.360doc.com/content/14/0619/23/12278894_388198735.shtml

  1 //更新遍历,重载操作符operator,当场景更新时,operator()的内容被调用,注意
  2 
  3 //需要添加traverse()以实现节点的继续遍历。可以参考src/osg/stateset.cpp,runUpdateCallBack()中的调用
  4 
  5 class UpdateCallback : public osg::NodeCallback
  6 
  7 {
  8 
  9         virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
 10 
 11         { 
 12 
 13             std::cout<<"update callback - pre traverse"<<node<<std::endl;
 14 
 15             traverse(node,nv);
 16 
 17             std::cout<<"update callback - post traverse"<<node<<std::endl;
 18 
 19         }
 20 
 21 };
 22 
 23  
 24 
 25 //拣选遍历,重载操作符operator(),当场景执行拣选优化时,operator()被调用,注意
 26 
 27 //需要添加traverse()以实现节点的继续遍历,可以参考include/osgUtil/CullVisitor,
 28 
 29 //handle_cull_callbacks_and_traverse()中的调用过程。
 30 
 31 class CullCallback : public osg::NodeCallback
 32 
 33 {
 34 
 35         virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
 36 
 37         { 
 38 
 39             std::cout<<"cull callback - pre traverse"<<node<<std::endl;
 40 
 41             traverse(node,nv);
 42 
 43             std::cout<<"cull callback - post traverse"<<node<<std::endl;
 44 
 45         }
 46 
 47 };
 48 
 49  
 50 
 51 //几何体绘制遍历,重载drawImplementation(),当几何体进行绘制时,函数的内容被调用,否则
 52 
 53 //将无法画出当前的几何形状。可以参考include/osg/Drawable,draw()中的调用过程
 54 
 55 class DrawableDrawCallback : public osg::Drawable::DrawCallback
 56 
 57 {
 58 
 59         virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const
 60 
 61         {
 62 
 63             std::cout<<"draw call back - pre drawImplementation"<<drawable<<std::endl;
 64 
 65             drawable->drawImplementation(renderInfo);
 66 
 67             std::cout<<"draw call back - post drawImplementation"<<drawable<<std::endl;
 68 
 69         }
 70 
 71 };
 72 
 73  
 74 
 75 //几何体更新遍历,重载函数update().当几何体更新时,其函数被调用。可以参考
 76 
 77 //include/osgUtil/UpdateVisitor, handle_geode_callback()中的调用过程。
 78 
 79 struct DrawableUpdateCallback : public osg::Drawable::UpdateCallback
 80 
 81 {
 82 
 83     virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)
 84 
 85     {
 86 
 87         std::cout<<"Drawable update callback "<<drawable<<std::endl;
 88 
 89     }
 90 
 91 };
 92 
 93  
 94 
 95 //几何体拣选遍历,重载函数cull。当几何体进行拣选优化时,函数的内容被调用。可以参考
 96 
 97 //src/osgutil/cullVisitor, apply(Geode&)函数中的调用过程
 98 
 99 struct DrawableCullCallback : public osg::Drawable::CullCallback
100 
101 {
102 
103     /** do customized cull code.*/
104 
105     virtual bool cull(osg::NodeVisitor*, osg::Drawable* drawable, osg::State* /*state*/) const
106 
107     {
108 
109         std::cout<<"Drawable cull callback "<<drawable<<std::endl;
110 
111         return false;
112 
113     }
114 
115 };
116 
117  
118 
119 class InsertCallbacksVisitor : public osg::NodeVisitor
120 
121 {
122 
123  
124 
125    public:
126 
127    
128 
129         InsertCallbacksVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
130 
131         {
132 
133         }
134 
135         
136 
137         virtual void apply(osg::Node& node)
138 
139         {
140 
141              node.setUpdateCallback(new UpdateCallback());
142 
143              node.setCullCallback(new CullCallback());
144 
145              traverse(node);
146 
147         }
148 
149  
150 
151         virtual void apply(osg::Geode& geode)
152 
153         {
154 
155             geode.setUpdateCallback(new UpdateCallback());
156 
157             
158 
159             //note, it makes no sense to attach a cull callback to the node
160 
161             //at there are no nodes to traverse below the geode, only
162 
163             //drawables, and as such the Cull node callbacks is ignored.
164 
165             //If you wish to control the culling of drawables
166 
167             //then use a drawable cullback...
168 
169  
170 
171             for(unsigned int i=0;i<geode.getNumDrawables();++i)
172 
173             {
174 
175                 geode.getDrawable(i)->setUpdateCallback(new DrawableUpdateCallback());
176 
177                 geode.getDrawable(i)->setCullCallback(new DrawableCullCallback());
178 
179                 geode.getDrawable(i)->setDrawCallback(new DrawableDrawCallback());
180 
181             }
182 
183         }
184 
185         
186 
187         virtual void apply(osg::Transform& node)
188 
189         {
190 
191             apply((osg::Node&)node);
192 
193         }
194 
195 };
196 
197  
198 
199 class MyReadFileCallback : public osgDB::Registry::ReadFileCallback
200 
201 {
202 
203 public:
204 
205     virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options)
206 
207     {
208 
209         std::cout<<"before readNode"<<std::endl;
210 
211         // note when calling the Registry to do the read you have to call readNodeImplementation NOT readNode, as this will
212 
213         // cause on infinite recusive loop.
214 
215         osgDB::ReaderWriter::ReadResult result = osgDB::Registry::instance()->readNodeImplementation(fileName,options);
216 
217         std::cout<<"after readNode"<<std::endl;
218 
219         return result;
220 
221     }
222 
223 };
224 
225  
226 
227 class CameraUpdateCallback : public osg::NodeCallback
228 
229 {
230 
231     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
232 
233     { 
234 
235         std::cout<<"Camera update callback - pre traverse"<<node<<std::endl;
236 
237         traverse(node,nv);
238 
239         std::cout<<"Camera update callback - post traverse"<<node<<std::endl;
240 
241     }
242 
243 };
244 
245  
246 
247 class CameraEventCallback : public osg::NodeCallback
248 
249 {
250 
251     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
252 
253     { 
254 
255         std::cout<<"Camera event callback - pre traverse"<<node<<std::endl;
256 
257         traverse(node,nv);
258 
259         std::cout<<"Camera event callback - post traverse"<<node<<std::endl;
260 
261     }
262 
263 };
264 
265  
266 
267 int main( int argc, char **argv )
268 
269 {
270 
271     // use an ArgumentParser object to manage the program arguments.
272 
273     osg::ArgumentParser arguments(&argc,argv);
274 
275    
276 
277     // set the osgDB::Registy read file callback to catch all requests for reading files.
278 
279     osgDB::Registry::instance()->setReadFileCallback(new MyReadFileCallback());
280 
281    
282 
283     // initialize the viewer.
284 
285     osgViewer::Viewer viewer;
286 
287  
288 
289     // load the nodes from the commandline arguments.
290 
291     osg::Node* rootnode = osgDB::readNodeFiles(arguments);
292 
293  
294 
295     // if not loaded assume no arguments passed in, try use default mode instead.
296 
297     if (!rootnode) rootnode = osgDB::readNodeFile("cow.osgt");
298 
299  
300 
301     if (!rootnode)
302 
303     {
304 
305         osg::notify(osg::NOTICE)<<"Please specify a file on the command line"<<std::endl;
306 
307  
308 
309         return 1;
310 
311     }
312 
313     
314 
315     // run optimization over the scene graph
316 
317     osgUtil::Optimizer optimzer;
318 
319     optimzer.optimize(rootnode);
320 
321      
322 
323     // insert all the callbacks
324 
325     InsertCallbacksVisitor icv;
326 
327     rootnode->accept(icv);
328 
329  
330 
331     viewer.getCamera()->setUpdateCallback(new CameraUpdateCallback());
332 
333     viewer.getCamera()->setEventCallback(new CameraEventCallback());
334 
335  
336 
337     // set the scene to render
338 
339     viewer.setSceneData(rootnode);
340 
341  
342 
343     return viewer.run();
344 
345 }

OSG源码中回调函数的执行过程

 1 //当你为你的节点设置了回调函数
 2 
 3 node.setUpdateCallback(new UpdateCallback());
 4 
 5  
 6 
 7 void ViewerBase::frame(double simulationTime)
 8 
 9 {
10 
11     updateTraversal();  /帧循环,更新回调
12 
13 }
14 
15  
16 
17 //回调函数的执行过程
18 
19  
20 
21 void Viewer::updateTraversal()
22 
23 {
24 
25          .........
26 
27     _scene->updateSceneGraph(*_updateVisitor);//_updateVisitor为osgUtil::UpdateVisitor,用来负责场景更新遍历
28 
29  
30 
31          .........
32 
33 }
34 
35  
36 
37 void Scene::updateSceneGraph(osg::NodeVisitor& updateVisitor)
38 
39 {
40 
41  
42 
43     if (getSceneData())
44 
45     {
46 
47         updateVisitor.setImageRequestHandler(getImagePager());
48 
49         getSceneData()->accept(updateVisitor);
50 
51     }
52 
53 }
54 
55  
56 
57 void Node::accept(osg::NodeVisitor& nv) { 
58 
59    if (nv.validNodeMask(*this))
60 
61    {
62 
63       nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); 
64 
65    }    
66 
67  } 
68 
69  
70 
71 void UpdateVisitor::apply(osg::Group& node)
72 
73 { handle_callbacks_and_traverse(node); }
74 
75  
76 
77  
78 
79 inline void handle_callbacks_and_traverse(osg::Node& node)
80 
81 {
82 
83      handle_callbacks(node.getStateSet());
84 
85      osg::NodeCallback* callback = node.getUpdateCallback();
86 
87      if (callback) (*callback)(&node,this);
88 
89  
90 
91      else if (node.getNumChildrenRequiringUpdateTraversal()>0) traverse(node);
92 
93 }  <strong>
94 
95 </strong>

 

【转】osgCallback的实现方法

标签:.sh   sse   rap   notice   lca   val   customize   filename   执行函数   

原文地址:https://www.cnblogs.com/tianshanhangui/p/10041694.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!