查看: 3541|回复: 5

求助,关于osgText::Text

[复制链接]

该用户从未签到

发表于 2008-4-24 22:30:11 | 显示全部楼层 |阅读模式
不停的调用text->setText(msg),为什么程序会崩溃。调试的时候倒是正常的。
代码如下:
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <iostream>
#include <osgText/Text>
#include <osgGA/TrackballManipulator>

int main( int argc, char **argv )
{
        // read the scene from the list of file specified commandline args.
        osg::ref_ptr<osg::Group> group = new osg::Group;
        osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg");
        group->addChild(cow.get());

        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        osg::ref_ptr<osgText::Text> text = new osgText::Text;
        text->setText(L"HELLO WORLD 你好");
        text->setFont("fonts/simkai.ttf");
        text->setPosition(osg::Vec3f(100.0,100.0,-0.10));
        geode->addDrawable(text.get());

        osg::Camera* camera = new osg::Camera;
        camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        camera->setProjectionMatrixAsOrtho2D(0,1280,0,1024);
        camera->setViewMatrix(osg::Matrix::identity());
        camera->setClearMask(GL_DEPTH_BUFFER_BIT);
        camera->addChild(geode.get());
        camera->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);

        group->addChild(camera);
       
        // construct the viewer.
        osgViewer::Viewer viewer;

        // set the scene to render
        viewer.setSceneData(group.get());

    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
        viewer.realize();
        char msg[256];
        while (!viewer.done())
    {
        viewer.frame();
        double time = viewer.elapsedTime();
        sprintf(msg,"time = %f",time);
        text->setText(msg);
    }
   
    return 0;
}

代码的目的是为了显示程序已经运行多少时间。
谢谢。

该用户从未签到

 楼主| 发表于 2008-4-24 22:38:17 | 显示全部楼层
如果将   
text->setText(msg);
改为
text->setText(L"你好");
倒是没有问题,为什么呢?

该用户从未签到

发表于 2008-4-24 23:14:53 | 显示全部楼层
好像是你的msg空间并不是每次都释放了,,逐一累加的话,空间不足,以至程序崩溃~~~~~~~~~~~

该用户从未签到

 楼主| 发表于 2008-4-25 08:40:02 | 显示全部楼层
我用回调函数可以很好的工作,代码如下

char msg[256];

struct TextDrawCallback : public virtual osg:rawable::DrawCallback
{
    /** do customized draw code.*/
    virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const
    {
        osgText::Text* text = (osgText::Text*)drawable;
                text->setText(msg);

        text->drawImplementation(renderInfo);
    }
};

....
        text->setDrawCallback(new TextDrawCallback());
....

    while (!viewer.done())
    {
        viewer.frame();
                double time = viewer.elapsedTime();
                sprintf(msg,"time = %f",time);
    }


所以我怀疑是不是多线程的问题。

该用户从未签到

发表于 2008-4-25 08:53:47 | 显示全部楼层
尽量不要在主仿真循环中进行对场景节点的修改,必然会出现错误。对不断变更的节点使用setDataVariance可以缓解这一问题,但是仍不能保证稳定。
这其中的原因很简单:frame函数与渲染线程之间是异步运行的关系,frame函数的作用仅仅是给用户(APP,在其中完成回调的工作)线程发送了启动的信号,并按照APP/CULL(场景筛选)/DRAW(底层渲染);而由于OSG的线程并行机制,使得下一次frame函数到来时,APP线程重新开始,但DRAW线程不一定完成。从而提高了渲染的效率。
因此,如果渲染线程还在运行中,而用户又在线程以外改变了某个节点的值,就很难预测会发生什么事情。所以使用回调实现场景的动态更改是最好的选择~~

该用户从未签到

 楼主| 发表于 2008-4-25 09:52:06 | 显示全部楼层
原帖由 array 于 2008-4-25 08:53 发表
尽量不要在主仿真循环中进行对场景节点的修改,必然会出现错误。对不断变更的节点使用setDataVariance可以缓解这一问题,但是仍不能保证稳定。
这其中的原因很简单:frame函数与渲染线程之间是异步运行的关系,fram ...


谢谢,大体上明白了,虽然还不是很清晰:)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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