查看: 5171|回复: 6

有没有高手关于callback有个详细点的教程

[复制链接]

该用户从未签到

发表于 2008-4-28 12:19:19 | 显示全部楼层 |阅读模式
这两天看了callback相关的技术,但是内容感觉太多,也找不多更多的资料。
什么updatecallback,cullcallback,drawcallback,eventcallback,readfilecallback...
这些callback都分别在什么地方调用,做什么用。

能有高手给个全面一点的解释就太好了。
谢谢。

该用户从未签到

发表于 2008-4-28 12:38:08 | 显示全部楼层
同问~~

该用户从未签到

发表于 2008-4-28 19:40:09 | 显示全部楼层
是不是指针函数实现的呢? OSG遍历或者触发相关消息、条件的时候自动调用?

该用户从未签到

 楼主| 发表于 2008-4-28 21:52:15 | 显示全部楼层

关于EventCallback及其用法

根据example里面的代码及自己的猜想,做了下面的代码用来测试EventCallback的在何时调用,及怎么使用EventCallback。
猜想:在系统发生Event(具体Event类型参将class GUIEventAdapter中的enum EventType)时,调用各个EventCallback,在Callback中根据回调函数的所有者,以及事件的类型来决定做何响应。

以下自己拼凑出来的测试代码。

#include <osgViewer/Viewer>
#include <osg/Group>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <iostream>
#include <string>

osg::Node* rootnode = NULL;
osg::Camera* camera = NULL;

class myEventCallback : public osg::NodeCallback
{
public:
        std::string msgout;

        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
        {
                msgout = "";
                if(node == rootnode)
                        msgout += "rootnode ";
                else if(node = (osg::Node*)camera)
                        msgout+= "camera ";


                if (nv->getVisitorType()==osg::NodeVisitor::EVENT_VISITOR)
                {
                        osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
                        if (ev)
                        {
//                                osgGA::GUIActionAdapter* aa = ev->getActionAdapter();
                                osgGA::EventQueue::Events& events = ev->getEvents();
                                for(osgGA::EventQueue::Events::iterator itr=events.begin();
                                        itr!=events.end(); ++itr)
                                {
                                        handle(*(*itr));
                                }
                        }
                }
        }
        virtual bool handle(const osgGA::GUIEventAdapter& ea)
        {
                switch(ea.getEventType())
                {
                case(osgGA::GUIEventAdapter::MOVE):
                        {
                                msgout+="MOVE!\n";
                                std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter:RAG):
                        {
                                msgout+="DRAG!\n";
                                std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter::KEYDOWN):
                        {
                                msgout+="KEYDOWN!\n";
                                std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter::KEYUP):
                        {
                                msgout+="KEYUP!\n";
                                std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter::FRAME):
                        {
                                //                                                msgout+="FRAME!\n";
                                //std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter::RESIZE):
                        {
                                msgout+="RESIZE!\n";
                                std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter::DOUBLECLICK):
                        {
                                msgout+="DOUBLECLICK!\n";
                                std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter:USH):
                        {
                                msgout+="USH!\n";
                                std::cout<<msgout;
                                break;
                        }
                case(osgGA::GUIEventAdapter::RELEASE):
                        {
                                msgout+="RELEASE!\n";
                                std::cout<<msgout;
                                break;
                        }
                default:
                        msgout+="ELSE EVENT!\n";
                        std::cout<<msgout;
                        break;
                }
                return false;
        }
};

int main( int argc, char **argv )
{
    // initialize the viewer.
    osgViewer::Viewer viewer;

        rootnode = osgDB::readNodeFile("cow.osg");

    camera = viewer.getCamera();
        camera->setEventCallback(new myEventCallback());
    rootnode->setEventCallback(new  myEventCallback());

    // 为了看到console窗口的输出,将viewer设置为窗口的形式,而不是全屏。
        viewer.setSceneData(rootnode);
        {
                osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
                traits->x = 100 ;
                traits->y = 100;
                traits->width = 600;
                traits->height = 480;
                traits->windowDecoration = true;
                traits->doubleBuffer = true;
                traits->sharedContext = 0;
                osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

                osg::ref_ptr<osg::Camera> camera = viewer.getCamera();
                camera->setGraphicsContext(gc.get());
                camera->setViewport(new osg::Viewport(0,0, traits->width, traits->height));
                GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
                camera->setDrawBuffer(buffer);
                camera->setReadBuffer(buffer);
        }
    return viewer.run();
}

该用户从未签到

发表于 2008-4-28 22:12:50 | 显示全部楼层
原帖由 wontor 于 2008-4-28 12:19 发表
这两天看了callback相关的技术,但是内容感觉太多,也找不多更多的资料。
什么updatecallback,cullcallback,drawcallback,eventcallback,readfilecallback...
这些callback都分别在什么地方调用,做什么用。

能 ...


上述回调的调用时机,参考osgcallback可以得到大部分的答案,另一个直接有效的方法就是浏览OSG的源代码。
在Viewer::eventTraversal函数中(viewer.cpp,784-810),将遍历所有的节点并执行accept方法,从而实现EventCallback
而在随后执行的updateTraversal函数中(frame函数中这两个过程将顺序执行),将实现节点的UpdateCallback方法。所以这两个回调应当说本质上没有什么区别

该用户从未签到

 楼主| 发表于 2008-4-28 22:29:15 | 显示全部楼层
原帖由 array 于 2008-4-28 22:12 发表


上述回调的调用时机,参考osgcallback可以得到大部分的答案,另一个直接有效的方法就是浏览OSG的源代码。
在Viewer::eventTraversal函数中(viewer.cpp,784-810),将遍历所有的节点并执行accept方法,从而实现 ...


首先感谢array的热心帮助。

看代码是一种有效的方法,但能够在OSG那么多代码中准确定位可不是一件容易的事。
看着看着就迷失了。当然了,代码上还是需要下大工夫的。
再次感谢。
先去看看viewer的代码去

该用户从未签到

发表于 2008-4-29 00:18:58 | 显示全部楼层
学习学习~~
原帖由 array 于 2008-4-28 22:12 发表


上述回调的调用时机,参考osgcallback可以得到大部分的答案,另一个直接有效的方法就是浏览OSG的源代码。
在Viewer::eventTraversal函数中(viewer.cpp,784-810),将遍历所有的节点并执行accept方法,从而实现 ...
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表