OSG + MFC单文档 实现第一个程序
来源:互联网 发布:qq飞车a车数据库 编辑:程序博客网 时间:2024/05/20 11:48
OSG + MFC单文档 实现第一个程序
前言:本文参考OSG 例子编写,建立在读者已经学会配置OSG环境基础上。
1.首先创建一个MFC单文档程序,步骤省略部分为默认;
2.文件拓展名加入(*.ive),读者如果不需要加载此类型模型,可以不写;
3.暂时不需要ActiveX控件,取消;点击完成;
4.新建一个C++类,内容和OSG例子中的类相同,例如类名:CRenderOSG;
其 RenderOSG.h 文件内容:
#pragma once#include <osgViewer/Viewer>#include <osgViewer/ViewerEventHandlers>#include <osgViewer/api/win32/GraphicsWindowWin32>#include <osgGA/TrackballManipulator>#include <osgGA/KeySwitchMatrixManipulator>#include <osgDB/DatabasePager>#include <osgDB/Registry>#include <osgDB/ReadFile>#include <osgUtil/Optimizer>#include <string>class cOSG{public: cOSG(HWND hWnd); ~cOSG(); void InitOSG(std::string filename); //初始化OSG,传入模型文件名 void InitManipulators(void); //初始化操作器 void InitSceneGraph(void); //初始化场景 void InitCameraConfig(void); //相机配置 void SetupWindow(void); //建立窗口 void SetupCamera(void); //建立相机 void PreFrameUpdate(void); //绘制前处理 void PostFrameUpdate(void); //绘制后处理 void Done(bool value) { mDone = value; } bool Done(void) { return mDone; } static void Render(void* ptr); //渲染 osgViewer::Viewer* getViewer() { return mViewer; }private: bool mDone; std::string m_ModelName; //模型名 HWND m_hWnd; //窗口句柄 osgViewer::Viewer* mViewer; osg::ref_ptr<osg::Group> mRoot; //根结点 osg::ref_ptr<osg::Node> mModel; //模型文件 osg::ref_ptr<osgGA::TrackballManipulator> trackball;//操作器 osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator; //加入keyswitch选择操作器};class CRenderingThread : public OpenThreads::Thread{public: CRenderingThread( cOSG* ptr ); virtual ~CRenderingThread(); virtual void run();protected: cOSG* _ptr; bool _done;};
RenderOSG.cpp 文件内容如下:
// MFC_OSG.cpp : implementation of the cOSG class//#include "stdafx.h"#include "RenderOSG.h"cOSG::cOSG(HWND hWnd) : m_hWnd(hWnd) {}cOSG::~cOSG(){ mViewer->setDone(true); Sleep(1000); mViewer->stopThreading(); delete mViewer;}void cOSG::InitOSG(std::string modelname){ // Store the name of the model to load m_ModelName = modelname; // Init different parts of OSG InitManipulators(); InitSceneGraph(); InitCameraConfig();}void cOSG::InitManipulators(void){ // Create a trackball manipulator trackball = new osgGA::TrackballManipulator(); // Create a Manipulator Switcher keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; // Add our trackball manipulator to the switcher keyswitchManipulator->addMatrixManipulator( '1', "Trackball", trackball.get()); // Init the switcher to the first manipulator (in this case the only manipulator) keyswitchManipulator->selectMatrixManipulator(0); // Zero based index Value}void cOSG::InitSceneGraph(void){ // Init the main Root Node/Group mRoot = new osg::Group; // Load the Model from the model name mModel = osgDB::readNodeFile(m_ModelName); if (!mModel) return; // Optimize the model osgUtil::Optimizer optimizer; optimizer.optimize(mModel.get()); optimizer.reset(); // Add the model to the scene mRoot->addChild(mModel.get());}void cOSG::InitCameraConfig(void){ // Local Variable to hold window size data RECT rect; // Create the viewer for this window mViewer = new osgViewer::Viewer(); // Add a Stats Handler to the viewer mViewer->addEventHandler(new osgViewer::StatsHandler); // Get the current window size ::GetWindowRect(m_hWnd, &rect); // Init the GraphicsContext Traits osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; // Init the Windata Variable that holds the handle for the Window to display OSG in. osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd); // Setup the traits parameters 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; // Create the Graphics Context osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get()); // Init Master Camera for this View osg::ref_ptr<osg::Camera> camera = mViewer->getCamera(); // Assign Graphics Context to the Camera camera->setGraphicsContext(gc); // Set the viewport for the Camera camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height)); // Set projection matrix and camera attribtues camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); camera->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.4f, 1.0f)); camera->setProjectionMatrixAsPerspective( 30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0, 1000.0); // Add the Camera to the Viewer //mViewer->addSlave(camera.get()); mViewer->setCamera(camera.get()); // Add the Camera Manipulator to the Viewer mViewer->setCameraManipulator(keyswitchManipulator.get()); // Set the Scene Data mViewer->setSceneData(mRoot.get()); // Realize the Viewer mViewer->realize(); // Correct aspect ratio /*double fovy,aspectRatio,z1,z2; mViewer->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2); aspectRatio=double(traits->width)/double(traits->height); mViewer->getCamera()->setProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);*/}void cOSG::PreFrameUpdate(){ // Due any preframe updates in this routine}void cOSG::PostFrameUpdate(){ // Due any postframe updates in this routine}void cOSG::Render(void* ptr){ cOSG* osg = (cOSG*)ptr; osgViewer::Viewer* viewer = osg->getViewer(); // You have two options for the main viewer loop // viewer->run() or // while(!viewer->done()) { viewer->frame(); } //viewer->run(); while(!viewer->done()) { osg->PreFrameUpdate(); viewer->frame(); osg->PostFrameUpdate(); //Sleep(10); // Use this command if you need to allow other processes to have cpu time } // For some reason this has to be here to avoid issue: // if you have multiple OSG windows up // and you exit one then all stop rendering AfxMessageBox(_T("Exit Rendering Thread")); _endthread();}CRenderingThread::CRenderingThread( cOSG* ptr ): OpenThreads::Thread(), _ptr(ptr), _done(false){}CRenderingThread::~CRenderingThread(){ _done = true; while( isRunning() ) OpenThreads::Thread::YieldCurrentThread();}void CRenderingThread::run(){ if ( !_ptr ) { _done = true; return; } osgViewer::Viewer* viewer = _ptr->getViewer(); do { _ptr->PreFrameUpdate(); viewer->frame(); _ptr->PostFrameUpdate(); } while ( !testCancel() && !viewer->done() && !_done );}
5.完成上述操作后,通过类向导添加如下消息响应:
6.在XXXView.h 中,头文件别忘了,添加如下成员变量:
protected: cOSG* mOSG; //HANDLE mThreadHandle; CRenderingThread* mThreadHandle;
构造函数对指针进行初始化:
CZZU_OSGView::CZZU_OSGView():mOSG(0L){// TODO: 在此处添加构造代码}
7.在OnCreate函数中,添加:
int CZZU_OSGView::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CView::OnCreate(lpCreateStruct) == -1)return -1;// Now that the window is created setup OSGmOSG = new cOSG(m_hWnd);return 0;}
8.在OnDestroy()函数中,进行 delete:
void CZZU_OSGView::OnDestroy(){delete mThreadHandle;if(mOSG != 0) delete mOSG;//WaitForSingleObject(mThreadHandle, 1000);CView::OnDestroy();}
9.OnEraseBkgnd()函数,返回真:
BOOL CZZU_OSGView::OnEraseBkgnd(CDC* pDC){// TODO: 在此添加消息处理程序代码和/或调用默认值//return CView::OnEraseBkgnd(pDC);return true;}
10.为了防止按Esc退出渲染,需要在OnKeyDown ()函数中,
void CZZU_OSGView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){// TODO: 在此添加消息处理程序代码和/或调用默认值//CView::OnKeyDown(nChar, nRepCnt, nFlags);// 防止按Esc退出if(nChar == VK_ESCAPE){GetParent()->SendMessage(WM_CLOSE);}}
11.运行程序,发现什么都没有;
12.需要添加一个虚函数,实现更新;
更新函数代码如下:
void CZZU_OSGView::OnInitialUpdate(){CView::OnInitialUpdate();// Init the osg classmOSG->InitOSG("cow.osg");// Start the thread to do OSG Rendering//mThreadHandle = (HANDLE)_beginthread(&cOSG::Render, 0, mOSG); mThreadHandle = new CRenderingThread(mOSG);mThreadHandle->start();}
13.完成上述,运行程序:
阅读全文
1 0
- OSG + MFC单文档 实现第一个程序
- Archie OSG Step By Step③ OSG+VS2010+MFC单文档程序框架构建
- 单文档程序添加OSG
- 第一个MFC程序
- 第一个MFC程序
- 第一个MFC程序!!!
- MFC单文档程序流程
- MFC单文档(SDI)全屏程序实现方法
- OSG+MFC对话框程序
- Linux学习gcc——调试第一个OSG程序
- MFC 删除单文档程序的菜单栏
- MFC中 单文档程序 删除工具栏
- MFC单文档程序初始化对话框方法
- MFC 单文档程序的运行过程
- MFC中单文档程序框架
- MFC--单文档程序(框架)
- MFC单文档程序架构解析
- MFC单文档程序 双缓冲绘图
- eclipse查看导入jar包源码
- 九度1015:还是A+B
- JQuery 导航
- Unity3D 脚本生命周期
- KMP
- OSG + MFC单文档 实现第一个程序
- 贪心算法之——最长上升子序列
- 获取百度地图相关代码
- vs智能提示英文转为中文
- 前端JS案例(一):倒计时
- 使用 rem 设置文字大小
- 欢迎使用CSDN-markdown编辑器
- Babel原理(待学习)
- 关于 Android 7.0 适配中 FileProvider 部分的总结