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

  程序实现效果图:

关键技术实现介绍:

  一、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 = ;
  while (pos != NULL)
  {
   pview = pdoc->GetNextView(pos);
   if (pview->IsKindOf(RUNTIME_CLASS(CChildOGLView)))
   {
    CChildOGLView* pchildview = (CChildOGLView*)pview;
    pchildview->m_ViewID = tempid;
    tempid += ;
   }
  }
 }
}

我们看到这里需要从文档类中检索出所有子视图(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(, , 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, );
 pdoc->m_3DMani.DrawBound(currentviewtype);
}
glFinish();
SwapBuffers(wglGetCurrentDC()); //in the DrawScene() function of child view
ViewType currentviewtype;
CMainFrame* pframe = (CMainFrame*)AfxGetMainWnd();
if(m_ViewID == )
{
 currentviewtype = pframe->m_ViewArrange.m_ChildViewAType;
}
else if(m_ViewID == )
{
 currentviewtype = pframe->m_ViewArrange.m_ChildViewBType;
}
glViewport(, , 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, );
 pdoc->m_3DMani.DrawBound(currentviewtype);
}
glFinish();
SwapBuffers(wglGetCurrentDC());

各位读者可以在此基础之上根据各自的需要实现不同的功能。需要指出的是,程序中包含了我们在系统开发中所需要的三维实体模型类,你可以对它进行修改或者替换为自己的数据结构,欢迎大家对本文提出建议,期待与大家进行合作!

(作者:胡卓玮责任编辑:方舟)

[转]浮动窗体中的OpenGL多视图的实现的更多相关文章

  1. 《MFC dialog中加入OpenGL窗体》

    <MFC dialog中加入OpenGL窗体> 最近学习了如何在MFC对话框程序中加入OpenGL窗体的方法,在这里将自己的实现过程归纳一下. 步骤零: 加入PictureControl控 ...

  2. Qt Examples - Boxes (在Qt场景视图中结合OpenGL渲染)

    QT自带例程Boxes使用QT Graphics View框架实现了2D图形和3D图形的混合渲染,综合性比较强,整合知识较多,值得学习. 可以使用鼠标通过以下方式控制演示中的元素: 按住鼠标左键的同时 ...

  3. MFC中添加OpenGL

    WINDOWS下展示OpenGL有多种形式: MFC 或 win32,该如何向MFC中添加OpenGL?下面是介绍最简单OpenGL框架. 1.首先通过VS建立MFC应用程序-MyOpenGL,选择单 ...

  4. android 浮动窗体学习笔记及个人理解(仿360手机助手)

    很感谢原文作者 http://blog.csdn.net/guolin_blog/article/details/8689140 经自己理解 程序执行界面例如以下图: 1.程序入口界面 2.小浮动窗体 ...

  5. OpenGl And 视图

    OpenGl And 视图 标签(空格分隔): game 简介 本文主要介绍坐标系的观念, 以及在openGL中的视图及其相关的变换. 大纲 视图.模型.投影变换概念 Opengl中对各种变换的支持 ...

  6. 在Android应用中使用OpenGL

    Android为OpenGL  ES支持提供了GLSurfaceView组件,这个组件用于显示3D图形.GLSurfaceView本身并不提供绘制3D图形的功能,而是由GLSurfaceView.Re ...

  7. Silverlight浮动窗体 floatablewindow 非模态对话框

    1.http://www.cnblogs.com/yinxiangpei/articles/2613913.html 说明:Silverlight的ChildWindow组件给我们的开发带来了便利,比 ...

  8. 强行在MFC窗体中渲染Cocos2d-x 3.6

    [前言] 把Cocos2dx渲染到另一个应用程序框架中的方法,在2.x时代有很多大神已经实现了,而3.x的做法网上几乎找不着.这两天抽空强行折腾了一下,不敢独享,贴出来供大家参考. [已知存在的问题] ...

  9. OpenGL模型视图变换、投影变换、视口变换的理解

    OpenGL中不设置模型,投影,视口,所绘制的几何图形的坐标只能是-1到1(X轴向右,Y轴向上,Z轴垂直屏幕向外). 产生目标场景的过程类似于用照相机进行拍照: (1)把照相机固定在三角架上,并让他对 ...

随机推荐

  1. 【java基础】从反射开始(Reflection)

    Java学习笔记 https://github.com/SnailDev/java-learning 和我一起启程... 反射(Reflection) 定义 在运行状态中, 对于任意的一个类,都能够知 ...

  2. CassiniDev源码学习 - 可替代IIS的单机Web Form解决方案

    最近一个项目是将web版的程序,改为单机版.话说这个web版号称当年十几个人用了至少3个月的时间开发,后来三年还不断有修改,而现在要在1个月内由一个人完成,这简直是不可能完成的任务!直觉告诉我,重写肯 ...

  3. sys模块 常用函数

    sys模块是和python解释器打交道的 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) s ...

  4. Code Signal_练习题_commonCharacterCount

    Given two strings, find the number of common characters between them. Example For s1 = "aabcc&q ...

  5. BZOJ4977: [[Lydsy1708月赛]跳伞求生

    传送门 直接贪心 考虑到 \(n\) 个人的贡献都是 \(a_i\),另外 \(m\) 个人的贡献都是 \(c_i-b_i\) 首先 \(a_i>b_j\) 的限制不好做,所以将 \(a,b\) ...

  6. Android View的事件分发机制和滑动冲突解决方案

    这篇文章会先讲Android中View的事件分发机制,然后再介绍Android滑动冲突的形成原因并给出解决方案.因水平有限,讲的不会太过深入,只希望各位看了之后对事件分发机制的流程有个大概的概念,并且 ...

  7. angularjs -- 路由监听

    前几天,项目在做一个功能时需要在页面切换之前关闭正在执行的函数.尝试了几种方式都不行,最后想到既然angularjs是通过理由切换页面,那就在路由上面做文章吧.AngularJS在路由发生改变时,可以 ...

  8. Vue 框架-05-动态绑定 css 样式

    Vue 框架-05-动态绑定 css 样式 今天的小实例是关于 Vue 框架动态绑定 css 样式,这也是非常常用的一个部分 首先说一下 动态绑定,相对的大家都知道静态绑定,静态绑定的话,直接加 cl ...

  9. android 每个块半径不同的扇形图,自定义view

    1.首先看效果图 2.自定义PieChartView,继承自View,下边为PieChartView代码 package com.yingjinbao.im.peach.customview; imp ...

  10. B/S与C/S架构、B/S架构协议

    软件有三大类型 单机类型.CS类型(Outlook.QQ.大型游戏).BS类型 BS结构中的协议 在BS结构中,首先使用到DNS协议:网络传输部分使用TCP/IP参考模型,其中网络接入层没有相应协议, ...