注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

辫子

这里的东东都转到了:hi.baidu.com/fairzy

 
 
 

日志

 
 

浮动窗体中的OpenGL多视图的实现[转]  

2008-08-04 09:05:13|  分类: OpenGL |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

浮动窗体中的OpenGL多视图的实现

作者:吉林大学 胡卓玮

下载本文示例源代码

关键字:OpenGL, 多视图, 浮动窗体

由于在工作中需要结合浮动窗体实现OpenGL的多视图,用于得到三维实体的三视图观察效果,通过参考其它资料,设计了一个程序框架,在此基础之上大家可以根据自己的需要进行扩充,实现需要的功能。

本程序中浮动窗体的实现从以下网站得到支持:www.datamekanix.com

程序实现效果图

关键技术实现介绍:一、OpenGL多视图的实现

平常我们的程序大部分都是建立一OpenGL设备上下文,但在本程序中,由于要实现三维实体的多视图观察功能,因此,需要建立多OpenGL设备上下文,并在需要的时候进行切换。

同一般的OpenGL程序一样,我们在每个视图类中都定义了每个视图所对应的设备描述上下文并在视图创建的时候建立了这个设备描述上下文。 //add in the header file of view class public: CClientDC* m_pDC; HGLRC m_hRC; //add in the init() function of view class m_hRC = wglCreateContext(m_pDC->GetSafeHdc()); 接着在某个视图需要更新的时候(一般在每个视图的OnDraw()函数中),将这个视图的设备上下文设为OpenGL当前的渲染上下文(OpenGL Rendering context)//add in the OnDraw() function of view class //set current device wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC); 二、视图类型的切换及当前视图类型的判断

由于同一视图在不同的时刻根据用户的需要可能有不同的功能,因此需要在几个视图之间进行功能的切换。本程序选取一个视图作为主视图,而另外两个视图作为子视图。视图的类有一下几种:上、下视图,前、后视图,左、右视图。为此设计了枚举类型变量用于指示视图的类型。为了保证不同视图类型之间的有效切换,即不会产生重复的类型,设计了一个类用于操作视图之间的类型切换。

为了减小程序编制的负担,所有子视图共享一个视图类,而每个视图的当前类型是存储在这个视图类之外的,因此在每个视图绘制的时候都需要判断自己的类型。这样便出现了无法在子视图类中判断自己当前的视图类型的情况。为此在子视图类中增加了一个成员变量用于记录自己的类型。 //add in the header file of child view class //view ID, it will be assigned by parentframe when this program begin //[childviewA id = 1; childviewB id = 2] int m_ViewID 然后在程序运行之初,浮动窗体创建之后,对每个浮动窗体所包含的子视图的类型进行设置。 //add in the OnCreate() function of CMainFrame class AssignViewID(); //the definition of AssignViewID() void CMainFrame::AssignViewID() { CEdit3DMDoc* pdoc = (CEdit3DMDoc*)m_pMainView->GetDocument(); if(pdoc) { POSITION pos = pdoc->GetFirstViewPosition(); CView* pview; int tempid = 1; while (pos != NULL) { pview = pdoc->GetNextView(pos); if (pview->IsKindOf(RUNTIME_CLASS(CChildOGLView))) { CChildOGLView* pchildview = (CChildOGLView*)pview; pchildview->m_ViewID = tempid; tempid += 1; } } } } 我们看到这里需要从文档类中检索出所有子视图(CChildOGLView),因此,在子视图创建的时候需要把自己加入到文档中。 //add in the OnCreate() function of child view class AddMetoDoc(); //the definition of AddMetoDoc() void CChildOGLView::AddMetoDoc() { CEdit3DMDoc* pdoc = (CEdit3DMDoc*)GetDocument(); if(pdoc != NULL) { pdoc->AddView(this); } } 至此,本程序的关键功能已经实现,在主视图和子视图的绘制函数部分便可以通过判断当前视图的类型进行不同内容的绘制。 //in the DrawScene() function of main view //To get the current view type ViewType currentviewtype; CMainFrame* pframe = (CMainFrame*)GetParentFrame(); currentviewtype = pframe->m_ViewArrange.m_MainViewType; glViewport(0, 0, m_oldRect.right, m_oldRect.bottom); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); CEdit3DMDoc* pdoc = GetDocument(); if(pdoc != NULL) { pdoc->m_3DMani.SetProjection(currentviewtype, 0); pdoc->m_3DMani.DrawBound(currentviewtype); } glFinish(); SwapBuffers(wglGetCurrentDC()); //in the DrawScene() function of child view ViewType currentviewtype; CMainFrame* pframe = (CMainFrame*)AfxGetMainWnd(); if(m_ViewID == 1) { currentviewtype = pframe->m_ViewArrange.m_ChildViewAType; } else if(m_ViewID == 2) { currentviewtype = pframe->m_ViewArrange.m_ChildViewBType; } glViewport(0, 0, m_oldRect.right, m_oldRect.bottom); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); CEdit3DMDoc* pdoc = GetDocument(); if(pdoc != NULL) { pdoc->m_3DMani.SetProjection(currentviewtype, 0); pdoc->m_3DMani.DrawBound(currentviewtype); } glFinish(); SwapBuffers(wglGetCurrentDC()); 各位读者可以在此基础之上根据各自的需要实现不同的功能。需要指出的是,程序中包含了我们在系统开发中所需要的三维实体模型类,你可以对它进行修改或者替换为自己的数据结构,欢迎大家对本文提出建议,期待与大家进行合作!

作者信息:

作者单位:吉林大学地球探测科学技术学院测绘工程系

欢迎访问作者的主页:forevergis.6to23.com

作者联系方式:forevergis@sina.com.cn

  评论这张
 
阅读(46)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018