查看: 3094|回复: 3

连续加载几个模型后报错?

[复制链接]

该用户从未签到

发表于 2009-4-15 00:54:18 | 显示全部楼层 |阅读模式
  1. using namespace System;
  2. using namespace System::ComponentModel;
  3. using namespace System::Collections;
  4. using namespace System::Windows::Forms;
  5. using namespace System::Data;
  6. using namespace System::Drawing;

  7. #pragma once


  8. namespace OSGViewer {

  9.         osg::ref_ptr<osg::Group> root ;
  10.         osg::ref_ptr<osgViewer::Viewer> viewer;
  11.         bool renderok;

  12.         /// <summary>
  13.         /// frmMain 摘要
  14.         /// </summary>
  15.         public ref class frmMain : public System::Windows::Forms::Form
  16.         {
  17.         public:
  18.                 frmMain(void)
  19.                 {
  20.                         InitializeComponent();
  21.                         //
  22.                         //TODO: 在此处添加构造函数代码
  23.                         //
  24.                 }

  25.         protected:
  26.                 /// <summary>
  27.                 /// 清理所有正在使用的资源。
  28.                 /// </summary>
  29.                 ~frmMain()
  30.                 {
  31.                         if (components)
  32.                         {
  33.                                 delete components;
  34.                         }
  35.                 }
  36.         private: System::Windows::Forms::MenuStrip^  menuStrip;
  37.         protected:
  38.         private: System::Windows::Forms::ToolStripMenuItem^  文件FToolStripMenuItem;
  39.         private: System::Windows::Forms::ToolStripMenuItem^  打开ToolStripMenuItem;
  40.         private: System::Windows::Forms::ToolStripSeparator^  toolStripMenuItem1;
  41.         private: System::Windows::Forms::ToolStripMenuItem^  退出XToolStripMenuItem;
  42.         private: System::Windows::Forms::StatusStrip^  statusStrip1;
  43.         private: System::Windows::Forms::ToolStripStatusLabel^  toolStripStatusLabel1;
  44.         private: System::Windows::Forms::OpenFileDialog^  openFileDialog1;

  45.         private:
  46.                 /// <summary>
  47.                 /// 必需的设计器变量。
  48.                 /// </summary>
  49.                 System::ComponentModel::Container ^components;

  50. #pragma region Windows Form Designer generated code
  51.                 /// <summary>
  52.                 /// 设计器支持所需的方法 - 不要
  53.                 /// 使用代码编辑器修改此方法的内容。
  54.                 /// </summary>
  55.                 void InitializeComponent(void)
  56.                 {
  57.                         System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(frmMain::typeid));
  58.                         this->menuStrip = (gcnew System::Windows::Forms::MenuStrip());
  59.                         this->文件FToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
  60.                         this->打开ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
  61.                         this->toolStripMenuItem1 = (gcnew System::Windows::Forms::ToolStripSeparator());
  62.                         this->退出XToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
  63.                         this->statusStrip1 = (gcnew System::Windows::Forms::StatusStrip());
  64.                         this->toolStripStatusLabel1 = (gcnew System::Windows::Forms::ToolStripStatusLabel());
  65.                         this->openFileDialog1 = (gcnew System::Windows::Forms::OpenFileDialog());
  66.                         this->menuStrip->SuspendLayout();
  67.                         this->statusStrip1->SuspendLayout();
  68.                         this->SuspendLayout();
  69.                         //
  70.                         // menuStrip
  71.                         //
  72.                         this->menuStrip->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) {this->文件FToolStripMenuItem});
  73.                         this->menuStrip->Location = System::Drawing::Point(0, 0);
  74.                         this->menuStrip->Name = L"menuStrip";
  75.                         this->menuStrip->Size = System::Drawing::Size(632, 24);
  76.                         this->menuStrip->TabIndex = 0;
  77.                         this->menuStrip->Text = L"menuStrip";
  78.                         //
  79.                         // 文件FToolStripMenuItem
  80.                         //
  81.                         this->文件FToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(3) {this->打开ToolStripMenuItem,
  82.                                 this->toolStripMenuItem1, this->退出XToolStripMenuItem});
  83.                         this->文件FToolStripMenuItem->Name = L"文件FToolStripMenuItem";
  84.                         this->文件FToolStripMenuItem->Size = System::Drawing::Size(57, 20);
  85.                         this->文件FToolStripMenuItem->Text = L"文件(&F)";
  86.                         //
  87.                         // 打开ToolStripMenuItem
  88.                         //
  89.                         this->打开ToolStripMenuItem->Name = L"打开ToolStripMenuItem";
  90.                         this->打开ToolStripMenuItem->Size = System::Drawing::Size(152, 22);
  91.                         this->打开ToolStripMenuItem->Text = L"打开(&O)";
  92.                         this->打开ToolStripMenuItem->Click += gcnew System::EventHandler(this, &frmMain::打开ToolStripMenuItem_Click);
  93.                         //
  94.                         // toolStripMenuItem1
  95.                         //
  96.                         this->toolStripMenuItem1->Name = L"toolStripMenuItem1";
  97.                         this->toolStripMenuItem1->Size = System::Drawing::Size(149, 6);
  98.                         //
  99.                         // 退出XToolStripMenuItem
  100.                         //
  101.                         this->退出XToolStripMenuItem->Name = L"退出XToolStripMenuItem";
  102.                         this->退出XToolStripMenuItem->Size = System::Drawing::Size(152, 22);
  103.                         this->退出XToolStripMenuItem->Text = L"退出(&X)";
  104.                         this->退出XToolStripMenuItem->Click += gcnew System::EventHandler(this, &frmMain::退出XToolStripMenuItem_Click);
  105.                         //
  106.                         // statusStrip1
  107.                         //
  108.                         this->statusStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) {this->toolStripStatusLabel1});
  109.                         this->statusStrip1->Location = System::Drawing::Point(0, 428);
  110.                         this->statusStrip1->Name = L"statusStrip1";
  111.                         this->statusStrip1->Size = System::Drawing::Size(632, 22);
  112.                         this->statusStrip1->TabIndex = 1;
  113.                         this->statusStrip1->Text = L"statusStrip1";
  114.                         //
  115.                         // toolStripStatusLabel1
  116.                         //
  117.                         this->toolStripStatusLabel1->Name = L"toolStripStatusLabel1";
  118.                         this->toolStripStatusLabel1->Size = System::Drawing::Size(227, 17);
  119.                         this->toolStripStatusLabel1->Text = L"Windows 窗体应用程序+ OSG  制作:王毫安";
  120.                         //
  121.                         // openFileDialog1
  122.                         //
  123.                         this->openFileDialog1->Filter = L"ive文件|*.ive|osg文件|*.osg|所有文件|*.*";
  124.                         //
  125.                         // frmMain
  126.                         //
  127.                         this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
  128.                         this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
  129.                         this->ClientSize = System::Drawing::Size(632, 450);
  130.                         this->Controls->Add(this->statusStrip1);
  131.                         this->Controls->Add(this->menuStrip);
  132.                         this->Icon = (cli::safe_cast<System::Drawing::Icon^  >(resources->GetObject(L"$this.Icon")));
  133.                         this->MainMenuStrip = this->menuStrip;
  134.                         this->Name = L"frmMain";
  135.                         this->Text = L"OSG模型浏览器";
  136.                         this->Load += gcnew System::EventHandler(this, &frmMain::frmMain_Load);
  137.                         this->menuStrip->ResumeLayout(false);
  138.                         this->menuStrip->PerformLayout();
  139.                         this->statusStrip1->ResumeLayout(false);
  140.                         this->statusStrip1->PerformLayout();
  141.                         this->ResumeLayout(false);
  142.                         this->PerformLayout();

  143.                 }
  144. #pragma endregion

  145. #pragma region  自定义函数
  146.         private:
  147.                 // System::String转换为std::string
  148.                 std::string ConvertToString(System::String^ str)
  149.                 {
  150.                          int q=(int)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str);
  151.                          char* p=(char*)q;
  152.                          return std::string(p);
  153.                 }

  154.                 // 渲染
  155.                 static void render(void* ptr)
  156.                 {
  157.                         osgViewer::Viewer* viewer = (osgViewer::Viewer*)ptr;
  158.                         while (!viewer->done())
  159.                         {
  160.                                 viewer->frame();
  161.                         }

  162.                         renderok = true;
  163.                         _endthread();
  164.                 }

  165.                 // 初始化
  166.                 void InitViewer()
  167.                 {

  168.                         // Set window traits and gc
  169.                         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
  170.                         osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData( (HWND)this->Handle.ToPointer() );
  171.                         traits->x = 0;
  172.                         traits->y = 0;
  173.                         traits->width = this->ClientSize.Width;
  174.                         traits->height = this->ClientSize.Height;
  175.                         traits->windowDecoration = false;
  176.                         traits->doubleBuffer = true;
  177.                         traits->sharedContext = 0;
  178.                         traits->inheritedWindowData = windata;
  179.                         traits->setInheritedWindowPixelFormat = true;
  180.                         osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());

  181.                         // Create camera
  182.                         osg::ref_ptr<osg::Camera> camera;
  183.                         camera = new osg::Camera;
  184.                         camera->setGraphicsContext(gc);
  185.                         camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));

  186.                         // Create viewer
  187.                         viewer = new osgViewer::Viewer;
  188.                         viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
  189.                         viewer->setCameraManipulator(new osgGA::TrackballManipulator);
  190.                         viewer->addSlave(camera.get());

  191.                         // 快捷键 1;2;3;4 四种动画模式
  192.                         osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

  193.                         keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
  194.                         keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
  195.                         keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
  196.                         keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
  197.                         viewer->setCameraManipulator( keyswitchManipulator.get() );

  198.                         viewer->addEventHandler(new osgViewer::StatsHandler);

  199.                         // Set root node of the scene
  200.                         root = new osg::Group;
  201.                         viewer->setSceneData(root.get());
  202.                         viewer->realize();
  203.                        
  204.                         // Create a thread for the simulation loop
  205.                         renderok = false;
  206.                         _beginthread(&render, 0, viewer);
  207.                 }
  208.    
  209.                 // 加载模型文件
  210.                 void LoadModel(String^ fileName)
  211.                 {
  212.                         // 如果Viewer窗口关闭,则重新初始化Viewer窗口
  213.                     if(viewer->done())
  214.                         {
  215.                                 InitViewer();
  216.                         }
  217.                         //载入模型
  218.                         osg::ref_ptr<osg::Node> model;
  219.                         model= osgDB::readNodeFile( ConvertToString(fileName) );
  220.                         if( !model ) return;
  221.                         viewer->setSceneData( model.get() );
  222.                         viewer->realize();
  223.                 }


  224. #pragma endregion

  225. private: System::Void 打开ToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {

  226.                          if(openFileDialog1->ShowDialog() == Windows::Forms::DialogResult::OK)
  227.                          {
  228.                                  try
  229.                                  {
  230.                                         LoadModel(openFileDialog1->FileName);
  231.                                  }
  232.                                  catch(...)
  233.                                  {
  234.                                          MessageBox::Show("模型文件打开失败!","错误",MessageBoxButtons::OK,MessageBoxIcon::Error);
  235.                                  }
  236.                          }

  237.                  }
  238. private: System::Void frmMain_Load(System::Object^  sender, System::EventArgs^  e) {
  239.                         // 初始化Viewer窗口
  240.                         InitViewer();
  241.                  }
  242. private: System::Void 退出XToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
  243.                          // 退出
  244.                          this->Close();
  245.                  }
  246. };
  247. }
复制代码
我用windows 窗体应用程序 做的osg模型浏览器。连续打开6、7个模型后就报error.我估计是void LoadModel(String^ fileName)函数有问题,应该怎么优化?????????

[ 本帖最后由 playwww 于 2009-4-15 00:56 编辑 ]
Error.JPG

该用户从未签到

发表于 2009-4-15 09:02:48 | 显示全部楼层
建议不要每次都改变Viewer里面getSceneData的值,因为是多线程模式,反复realize()可能会有危险。推荐给Viewer设置一个new Group作为根节点,然后用addChild,setChild来加载模型。

此外楼主是用托管来实现C#与OSG的嵌合的吧?期待楼主能写一篇简单的教程,让大家都从中获益,  毕竟国内的.NET开发者也占了相当一部分。当然前提是有空余的时间,不必强求~~

该用户从未签到

 楼主| 发表于 2009-4-15 09:27:47 | 显示全部楼层
我主要想用c++/CLR使用OSG,这样界面的部分就不用愁了,托管和非托管混合编程。MFC做界面太愁人了。
我测试的方法如下:
1、新建项目->Visual C++->CLR->Window窗体应用程序
2、在工具箱里拖个菜单到默认生成的窗体Form1上,建个【文件】->【打开】菜单项
双击写如下代码(引用本论坛代码),
private: System::Void 打开ToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
    osg::ref_ptr<osg::Group> root = new osg::Group;
        osgViewer::Viewer viewer;
        viewer.setSceneData( osgDB::readNodeFile( "cow.osg" ) );
        viewer.run();
}
3、打开 stdafx.h 加入代码如下:
#include <osg/ref_ptr>
#include <osg/Group>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <iostream>
4、以上部分没什么特殊的,最主要的是修改项目属性。
(1)跟例子项目的属性配置一样。附加包含目录、附加库目录、附加依赖项等都照例子的改;
(2)OSG例子都不带【预编译头】,这里一定得保持默认带的,要不然编译慢4你;
原因看这个(http://www.cnblogs.com/hesicong/articles/1078366.html
(3)这步最主要,改【配置属性】->【常规】公告语言运行库支持:公共语言运行库支持(/clr);
这样托管非托管代码一起编译拉。
参考:http://hi.baidu.com/feifei0730/b ... 27aaef38012f66.html
(4)要是编译时提示超过了 PCH 的虚拟内存范围,修改如下
【配置属性】->【C/C++】->【命令行】最下面的 附加选项 填入 -Zm116
编译应该ok拉
运行,点菜单打开,就会出现闪光牛拉。
这回可以用托管组件做界面了,估计照s99做的mfc模型浏览器,也能出个.net版了。

模型浏览器的源码我发这里啦,斑竹帮忙改改。
http://www.vrchina.net/vr/viewthread.php?tid=10065&highlight=%2Bplaywww

该用户从未签到

发表于 2009-4-15 10:18:29 | 显示全部楼层
好的,多谢。有空我看一下。也欢迎楼主在教程区发文,大家共享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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