• (转)一个简单的osg控件开发例子


    作者:boqing

    经常需要在对话框上添加osg的浏览功能,一开始是仿照osgviewerMFC的例子去写,可是每次在对话框上添加此功能的时候都要重复复制很多处代码,且位置和大小控制也不是很方便。因此写了个简单的OSG Active控件解决此问题。

    开发工具:vc2005

    OSG版本:osg2.2

     具体开发步骤:

    一 建立Active工程
    项目类型选择:MFC,模板选择MFC ActiveX Control

    下一步的向导中保持默认,点完成


    二 配置viewer
    定义viewer为成员函数

    osg::ref_ptr<osgViewer::Viewer>viewer;

    构造函数中初始化

    viewer=new osgViewer::Viewer;


    为了使得其能正常显示在拖动的空间中,大小和位置与拖出区域的大小和位置一致。编写configViewer函数

    #include <osgViewer/api/win32/GraphicsWindowWin32>

    void COSGControlCtrl::configViewer(HWND m_hWnd)

    {

        RECT rect;

        //得到控件的大小

        ::GetWindowRect(m_hWnd, &rect);

        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;

        osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);

        traits->x = 0;

        traits->y = 0;

        traits->width = rect.right - rect.left;

        traits->height = rect.bottom - rect.top;

        traits->windowDecoration = false;

        traits->doubleBuffer = true;

        traits->sharedContext = 0;

        traits->setInheritedWindowPixelFormat = true;

        traits->inheritedWindowData = windata;

        osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());

        osg::ref_ptr<osg::Camera> camera = new osg::Camera;

        camera->setGraphicsContext(gc);

        camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));

        viewer.addSlave(camera.get());

    }

    三 添加自定义方法setSceneData
    在类视图中展开OSGControlLib,右键单击_DOSGControl,选择添加->添加方法,按照下图进行填写

    确定后,在类COSGControlCtrl的实现中添加以下代码:

    void COSGControlCtrl::setSceneData(ULONG* data)

    {

        AFX_MANAGE_STATE(AfxGetStaticModuleState());

        // TODO: Add your dispatch handler code here

        if (!isSetSceneData)

        {

            configViewer(m_hWnd);

        }

        osg::Node *node=(osg::Node *)data;

        viewer->setSceneData(node);

        isSetSceneData=true;

    }

    isSetSceneData是类成员,构造函数中初始化为false,记录着是否曾经调用过viewer->setSceneData函数

    四 写静态线程函数
    在函数里主要是加入viewer.run()语句,这样的话osg的运行和程序的其它响应才能同时进行。

    声明:

    static UINT ThreadRun(LPVOID lparam);

    实现:

    UINT COSGControlCtrl::ThreadRun(LPVOID lparam)//请求状态。

    {

        ((osgViewer::Viewer *)(lparam))->run();

        return 0;

    }

    五 启动线程
    本来想在OnInitDialog函数中启动,可是检查后发现,COSGControlCtrl类并不提供此函数的重载,因此,只好写在OnDraw函数里,因为OnDraw函数一旦当前区域移动、被遮挡等情况下都要调用,因此我们还要保证OnDraw只运行一次。

    void COSGControlCtrl::OnDraw(

                CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)

    {

        if (!pdc)

            return;

        // TODO: Replace the following code with your own drawing code.

        static bool flag=true;

        if (flag)

        {

            MessageBox("OnDraw");

            flag=false;

           

            if(!isSetSceneData)

            {

                configViewer(m_hWnd);//配置默认的viewer

                viewer->setSceneData(osgDB::readNodeFile("cow.osg"));//默认数据

            }

            HANDLE hHandle=CreateThread(NULL,0,ThreadRun,(LPVOID)(viewer.get()),0,NULL);

            CloseHandle(hHandle);

        }

    }

    六 程序退出后结束run函数的循环
       

    void COSGControlCtrl::OnDestroy()

    {

        COleControl::OnDestroy();

        // TODO: Add your message handler code here

        viewer->setDone(true);

        Sleep(1000);

        viewer->stopThreading();

    }

    七 测试
    F7,编译通过,生成了解决方案,新打开vc,建一个对话框程序,右键点击“插入Active控件”,选择“OSGControl”,确定

    在对话框上拖出一个合适的区域,Ctrl+F5,运行,结果如下:


    给控件添加变量m_osg

    在合适的位置调用

    m_osg.setSceneData((ULONG*)(osgDB::readNodeFile("axes.osg")));

    就可以改变viewer的数据了

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yangdelong/archive/2009/07/14/4348212.aspx

  • 相关阅读:
    Linux下c++使用pthread库
    一半,一绊
    【codevs3945】 完美拓印
    【poj2942】 Knights of the Round Table
    【bzoj2730】 HNOI2012—矿场搭建
    【poj1177】 Picture
    Tarjan学习笔记
    联赛总结
    【poj3461】 Oulipo
    【csuoj1014】 西湖三人行
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/2445897.html
Copyright © 2020-2023  润新知