http://www.c3dn.net/archiver/?tid-48.html

想象一下,我们在原始森林里寻找宝藏,没有地图,没有GPS,那结果应该只有一种:不但找不到目标地点,而且很容易迷失方向。同样,在OpenGL绘制的场景中漫游,往往只能看到局部的场景,而无法确定自己现在处于大场景中哪个位置。所以,一个具有定位功能的GPS是十分必要的。

接下来,我们也基于OpenGL和MFC开发一个简约版的GPS,以便实时指示我们漫游时当前所在的位置。实现效果如下: 实现技术:VC++ 、MFC、GDI、OpenGL实现步骤:1.在MFC下实现漫游      (1).建立MFC单文档项目,配置OpenGL环境          配置MFC下的OpenGL环境环境比较繁琐,在这里就不详细介绍了,详情参考:     http://www.cnblogs.com/yanhuiw/articles/1794462.html       (2).实现漫游         在场景中,我们可以来回走动,去我们想要去的地方,这个主要通过漫游来实现。漫游功能使用Camera类实现。(感谢可爱的刘大侠为我们实现这么完美的Camera类)。 2.绘制漫游场景        这个简约版的小地图功能需要一个场景,方便我们在其中来回徘徊。我绘制了一个小小的网格地形以及一架古怪的飞机。

代码如下: [*]// 画网格线

[*]glBegin(GL_LINES);  [*]    glColor3f(0.0f,0.0f,0.0f);  [*]    int i;  [*]    for(i=-4;i<=4;i++)  [*]    {  [*]        glVertex3d(-2.5, 0.02, 2.5/4.0*(double)i);  [*]        glVertex3d( 2.5, 0.02, 2.5/4.0*(double)i);  [*]    }  [*]    for(i=-4;i<=4;i++)  [*]    {  [*]        glVertex3d( 2.5/4.0*(double)i, 0.02, -2.5 );  [*]        glVertex3d( 2.5/4.0*(double)i, 0.02, 2.5 );  [*]    }  [*]glEnd();  [*] [*]// 飞机头

[*]DrawChannel(-1,0,0,0.0,0.5,-1.0);  [*]DrawChannel(-1,0,0,0.0,0.5,1.0);  [*] [*]// 机身

[*]glPushMatrix();  [*]    glRotatef(90.0f,0.0f,0.0f,1.0f);  [*]    auxSolidCylinder(0.2,2);  [*]glPopMatrix();  [*] [*]// 机翼

[*]glPushMatrix();  [*]    //glTranslatef(0.0f,0.0f,0.0f);

[*]    auxSolidBox(0.5,0.2,1.5);  [*]glPopMatrix();  [*] [*]// 尾部

[*]glPushMatrix();  [*]    glTranslatef(1.0f,0.0f,0.0f);  [*]    auxSolidCube(0.5);  [*]glPopMatrix();

3.显示小地图     (1).制作小地图图片    用截图工具将场景的俯视图截取出来。效果如下:

制作的小地图(小地图.bmp)保存在当前项目文件夹中,然后将图片导入项目中:

1).打开资源视图

2).导入位图

3).导入到位图资源中,命名为“IDB_MINMAP”,效果如下:

(2).显示小地图             使用非模式对话框显示地图,实现步骤如下:             1).新建对话框,命名为“IDD_DIALOG_MINMAP”,在对话框Style选项卡中去掉“Title bar”复选框,在Extended Styles选项卡中选上“Client edge”复选框。 效果如下:

2).制作关闭按钮,删除“OK”按钮,将“Cancel”按钮中的文本改成“x”;对话框的高宽各为100,对话框最终效果如下:

3).显示对话框。首先新建一个类CMinmapDlg对应以上对话框,然后新建菜单项“显示地图”,命名为“ID_MENUITEM_MINMAP”,效果如图:

添加菜单项的响应函数,如图所示:

以非模式对话框的形式显示对话框,在OnMenuitemMinmap代码如下:

[*]// 创建小地图对话框

[*]if (minMap == NULL)  [*]{  [*]    minMap = new CMinmapDlg();  [*]    minMap->Create(IDD_DIALOG_MINMAP,NULL);  [*]}  [*] [*]// 显示/隐藏对话框

[*]if (minMap->IsWindowVisible())  [*]{  [*]    minMap->ShowWindow(SW_HIDE);  [*]}  [*]else

[*]{  [*]    minMap->ShowWindow(SW_SHOW);  [*]}

效果如图: (3).绘制定位点         在CMinmapDlg类中定义两个变量int xPos;int yPos,用来标识二维点,然后在构造函数中给他们分别赋初始值为90,190。

对话框加载背景图后,才绘制定位点。定位点为黄色边框,里面用红色填充。所以应该在OnPain中添加如下代码:

[*]// 绘制定位点

[*]CPen pen(PS_SOLID,2,RGB(255,255,0));    // 用黄色钢笔画图

[*]dc.SelectObject(&pen);  [*]CBrush *pBrush=new CBrush(RGB(255,0,0));// 用红色画刷填充圆

[*]dc.SelectObject(pBrush);  [*]dc.Ellipse(xPos,yPos,xPos+10,yPos+10);  // 绘制椭圆(直径为10个像素)

最终效果如图:

4.小地图与场景的交互     现在我们已经将定位点绘制出来了,但是当我们在场景中走动时,定位点并没有在小地图移动。所以我们还要实现以下功能:   (1).在小地图上动态标注当前所在位置       当我们在场景中移动时,获取当前摄像机所在的位置,并且告诉对话框,让它在指定的位置绘制定位点,最后刷新对话框。步骤如下:        1).定义一个公有函数,以便其它类调用它绘制定位点,函数声明为void DrawPoint(int x, int y),函数实现:

[*]void DrawPoint(int x, int y)  [*]{  [*]    xPos = x;  [*]    yPos = y;  [*]}

2).场景的漫游通过键盘操作,所以我们应该在键盘响应处命令小地图对话框重新绘制定位点,即在视图类中的OnKeyDown函数中添加如下代码:

[*]// 在小地图中定位

[*]if (minMap != NULL)  [*]{  [*]    // 画点

[*]    minMap->DrawPoint(m_Camera.GetPosition().m_x*50+90,  [*]                      m_Camera.GetPosition().m_z*60+40);  [*] [*]    // 重绘

[*]    minMap->Invalidate(TRUE);  [*]}

注意:二维中的y坐标对应三维场景中的z坐标,而且因为小地图与场景有一定的比例,所以他俩的之间的坐标要转换,场景中的初始位置(x=0,z=2.5)对应小地图中的(x=90,y=190),在场景中左右移动一步相当于小地图中左右移动50步,上下移动一步相当于小地图中移动60步。 (2).点击小地图上的位置后瞬间移动到指定位置         当我们点击小地图时,获取鼠标单击的位置,然后设置场景中摄像机的位置。        实现步骤如下:        添加响应鼠标左键按下的函数,然后在OnLButtonDown函数中添加如下代码:

[*]// 在地图上标识

[*]DrawPoint(point.x,point.y);  [*] [*]// 重绘地图

[*]Invalidate(TRUE);  [*] [*]// 重新获取摄像机

[*]camera = ((CPipeLineView*)((CMainFrame *)AfxGetMainWnd())->GetActiveView())->m_Camera;  [*] [*]// 将场景中的视角转到指定位置

[*]((CPipeLineView*)((CMainFrame *)AfxGetMainWnd())->GetActiveView())->m_Camera.SetCamera(  [*]    (point.x-90)/50, camera.GetPosition().m_y, (point.y-40)/60,     // 视点

[*]    (point.x-90)/50, camera.GetPosition().m_y, (point.y-40)/60-0.5, // 参考点

[*]    0.0f,1.0f,0.0f);  [*] [*]// 重绘场景

[*]((CPipeLineView*)((CMainFrame *)AfxGetMainWnd())->GetActiveView())->Invalidate(TRUE);

注意:camera已在头文件中声明,为场景中的摄像机。        实现的效果如图: http://www.c3dn.net/data/attachment/forum/201102/14/2027085hkk8f18emmru17h.gif

源代码下载:http://www.c3dn.net/forum.php?mod=viewthread&tid=928&page=1&extra=#pid2430

声明:本文章来自C3DN论坛,由“江南孤鹜”原创,转载请声明!

转载于:https://www.cnblogs.com/lzhitian/archive/2012/12/10/2811159.html

【转】在OpenGL场景中实现小地图功能相关推荐

  1. (转载)在OpenGL场景中实现小地图功能

    转自:http://www.c3dn.net/forum.php?mod=viewthread&tid=48&page=1 想象一下,我们在原始森林里寻找宝藏,没有地图,没有GPS,那 ...

  2. OpenGL中的颜色混合功能(一)

    OpenGL中的颜色混合功能(一)              我们知道,材料属性和光照参数可以极大地增加图形的逼真度,但除此之外,我们在对现实世界进行建模时,有许多效果是通过混合颜色的方式实现的.透明 ...

  3. 通过IDoc来实现公司间STO场景中外向交货单过账后自动触发内向交货单的功能 – Part 2

    通过IDoc来实现公司间STO场景中外向交货单过账后自动触发内向交货单的功能 – Part B 6, 入站IDOC的设置 IDoc type – DELVRY01 Message Type – DES ...

  4. 通过IDoc来实现公司间STO场景中外向交货单过账后自动触发内向交货单的功能 - Part I

    通过IDoc来实现公司间STO场景中外向交货单过账后自动触发内向交货单的功能 - Part I 公司间采购(公司间库存转储)流程里,常见的解决方案是发货方完成发货过账后,自动触发收货方的内向交货单.除 ...

  5. Quick BI产品核心功能大图(五)移动端:让数据在更多业务场景中流通

    简介:将数据更好的融入日常工作中,一个重要的前提条件就是多端多渠道的数据触达和办公协同能力. Quick BI凭借移动端交互体验,帮助用户随时随地便捷查看报表,并通过在线协同方式,追踪策略的执行落地. ...

  6. Python+OpenGL实现虚拟场景中不同物体的拾取与选择

    开学第一课:一定不要这样问老师Python问题 中国大学MOOC"Python程序设计基础"第6次开课时间 董付国老师Python系列教材推荐与选用参考 ============= ...

  7. 在WebGL场景中管理多个卡牌对象的实验

    这篇文章讨论如何在基于Babylon.js的WebGL场景中,实现多个简单卡牌类对象的显示.选择.分组.排序,同时建立一套实用的3D场景代码框架.由于作者美工能力有限,所以示例场景视觉效果可能欠佳,本 ...

  8. 计算机图形学实验——三维迷宫的创建及走迷宫过程中的交互功能的实现

    计算机图形学实验2 三维迷宫的创建及走迷宫过程中的交互功能的实现 OpenGL三维迷宫创建及交互 三维"图元"的绘制 迷宫结构的储存 视角转换的实现 碰撞检测 纹理贴图 小结 Op ...

  9. 【我的OpenGL学习进阶之旅】OpenGL ES 3.0新功能

    目录 1.1 纹理 1.2 着色器 1.3 几何形状 1.4 缓冲区对象 1.5 帧缓冲区 OpenGL ES 2.0 开创了手持设备可编程着色器的时代,在驱动大量设备的游戏.应用程序和用户接口中获得 ...

最新文章

  1. 逃离 AI 赛道的投资人:做局失利、破局无力
  2. javaWeb学习总结(4)- HttpServletResponse
  3. juniper路由器主备路由引擎主机名配置
  4. 谭浩强c++程序设计知识点思维导图
  5. nodejs 中es5 模块的几种写法
  6. 你做不到对企业真正有价值,下一个裁员就是你
  7. 服务器系统如何清理,服务器清理内存怎么清理
  8. eos源码赏析(七):EOS智能合约入门之共识机制初探
  9. python中字符串的使用04字符串大小写转换、删除空白字符
  10. 薪资过万的高级web开发工程师掌握哪些技能
  11. 微信小程序开发: 开发前准备工作
  12. JS之数据结构与算法
  13. 不懂envoyfilter也敢说精通istio系列-ratelimit-istio ratelimit完全手册
  14. 06 现有原件模型的创建
  15. 百万英雄类答题游戏的程序员打开方式
  16. git与ssh配置方法及注意事项
  17. 【王喆-推荐系统】(task3)Embedding基础(特征工程篇)
  18. postgre创建存储过程_postgre 存储过程
  19. MybatisPlus_${ew.sqlSelect},${ew.sqlSet},${ew.sqlSegment},${ew.customSqlSegment}的使用
  20. 基于COCHONUT做和弦识别

热门文章

  1. Docker官方文档翻译4
  2. AI在农业领域的应用落地!
  3. 研究生论文“盲审”“查重”再加码!毕业或将变的更加困难
  4. 厉害!苏炳添即将在暨南大学成立短跑实验室
  5. 600页!分享珍藏很久的《推荐系统学习手册》(附下载链接及入门经验)
  6. PyTorch中文版官方教程来啦(附下载)
  7. Spring基础专题——第三章(反转控制与依赖注入)
  8. Linux系统中运行.sh文件的几种方法
  9. PS2019历史记录画笔工具、历史记录艺术画笔工具
  10. Django博客系统工程创建和配置