这一部分我们首先实现视图控制(包括了平移/旋转/缩放),前面我们已经讲过,通过lookat一个函数,或者通过translate+rotate两个函数,都能实现视图的控制(两个函数的方式比较简单,但是通用性不够,因为这个更像是画布就像去参观卖房子的模型,你可以把模型随便上下左右移动翻转看外面,但是如果要像第一人称视角到房子里面爬窗户,上房顶,钻地道,这种视角肯定是不够的。可以想象CS游戏中,整个地图场景必然是唯一的,每个游戏玩家都可以控制一组视角,视角的lookat九个参数不同导致了可以仰望,俯瞰,左右扫等等,有兴趣的读者可以去仔细研究实现方法)

 

然而能用按钮控制还是不够方便,很多时候我们需要像Solidworks软件这样能够用鼠标键盘控制,我自己设定的一些简单规则:

鼠标可以控制视图前后左右翻转

按住Shift+鼠标可以控制视图前后左右平移

鼠标滚轮可以控制视图缩放

按住Ctrl,鼠标滚轮可以控制视图绕Z旋转

 

根据这些规则,我们需要在控件初始化的时候添加一组事件绑定(注意要用C#自动补全的方式做,不然后面的参数你不知道怎么写的,比如绑定到KeyDown事件,响应的是KeyEventArgs e,我们可以采集到键盘的按键,如果你自己写就不知道是什么参数类型了)

 

这些事件的绑定你也可以在主窗口中选中指定的控件,查看他所有的事件,双击进去(但是不符合面向对象的写法,假如我们完善了这个类以后要写一个新的项目,难道你每次拖完了这个OPENGL的控件,然后切换到这里,一个一个把事件双击进去生成,然后再复制粘贴代码?肯定效率很低,比较好的做法是自己定义一个类,然后每次初始化只要把这个OPENGLControl类型传递过去,所有的事件响应就一次完成了)

 

在这么多的事件响应中,我们先来看比较简单的几组,鼠标移入和鼠标移出是判断鼠标是否在控件上的(为了防止在鼠标在窗口的其他地方点击按钮,操作也会影响视图,我们定义只要鼠标离开了控件,则全局变量设置为false,就不再修改视图了)。鼠标按下和鼠标抬起来是为了定义是否采集鼠标当前位置的(也是为了防止误判,假定如果鼠标在控件内部移动,只有左键按下之后的移动操作才会产生影响,不按按钮移动鼠标也不修改视图,当然每次MouseDown的时候都要刷新一下当前的位置=记录之前的位置)

 

鼠标移动的事件是真正产生效果的事件,我们每次鼠标往某个方向运动,如果期望视图跟着发生改变,则实际上只要捕捉鼠标前后位置的差异,然后叠加到Translate或者Rotate的三个参数上即可(注意其实是两个参数,因为我们是在二维的电脑屏幕上模拟三维的效果,鼠标只会有X,Y的数值,所以也只能映射到XY的平移或者绕XY的旋转,所以后面会增加一些额外的规则定义Z的平移-缩放,Z的旋转-旋转视图)

 

讲到缩放视图,最方便的是用鼠标滚轮实现,鼠标滚轮上滚和下滚,e.Delta数值是正的和负的,为了防止太大的时候缩放的太快,所以如果已经ViewChangeTranslate很小,就缩放的再慢一点(也可以做成一个函数,越远越小则缩放越快,这样更符合用户体验)绕Z轴旋转还是比较重要的,为了防止规则太多,我还是用鼠标滚轮实现(需要先按下Ctrl键),到这里基本的视图控制就完成了。

 

然后深入理解一下PushMatrix和PopMatrix方法,假定我们要绘制一个小型的机器人,仅仅用三个六面体来表示机器人的头部和两个手臂(注意尽量绘制一个小模块的时候用一组push和pop包起来),我们后面详细介绍具体绘制过程

 

在绘制基本物体的时候,注意不管你的物体尺寸多少,你的画笔是保持不变的(仅仅Translate和Rotate可以修改画笔的位置和姿态),所以我可以人为地调节红色立方体块的大小

 

接下来绘制手臂,如果期望手臂正好贴在红色立方体块的两个,那么就必须要把画笔平移到下一个要绘制的立方体的底面中心位置(我们暂时还不考虑姿态,后面会讲姿态的文字,如果不使用Rotate,则姿态将始终保持垂直于画布),注意仔细体会画笔挪动到新的位置之后的效果

 

在绘制B手臂的时候,如果直接从绘制A手臂的地方挪过去也可以(再平移整个红色立方体的宽度就行了),但是只是对于简单的几何物体可以这样做,如果绘制非常复杂的多边形,很多时候我们自己也不知道画笔在哪了,所以有必要从上一步画笔还没开始动的地方接着画(因为B手臂跟A手臂是对称的, 所以只要把某些Translate的正负号改一改就行了)下图中从X-X1和X-X2过程基本类似,对称(这也是编程中比较重要的化归思想,不要产生新的问题,X1直接到X2就是新的问题,哪怕比X-X2更简单,因为我们已经有了X-X1的经验可以套用,就可以直接X-X2)

 

让整个动画元素动起来,其实只要把一些变量添加到整个绘制过程就可以了(我在这里只是做了简单的演示,比如两个手臂的摆动,实际上你也可以为机器人添加腿,眼睛,腰部等等)

 

最后套用一点运动控制的思想,让两个旋转的臂从A点走到B点,要求同时走到位(还是要考虑比较多的因素的,比如AB两点没有差距,或者只有一个旋转臂有差距),大体思路可以概括成:

1 采集起点和终点的差值(数组)

2 获取差值数组中的最大值(最远距离)

3 根据给定的速度求总的时间(最远距离/给定速度)

4 根据总的时间重新求每个轴的速度(每个轴的前后距离/总时间)

5 在线程中执行运动(用计时器,每隔一定时间生成一个新的时间,并用S=S0 + V*t的公式计算每次新的位置)

 

总结:到此为止OPENGL的简单介绍就结束了,网上有大量的代码介绍OPENGL的仿真(C++的比较多,因为C#相对于C++的性能还是差很多,所以大型的游戏,3D处理软件都会用C++作为最终的编程执行工具,可能C#是嵌套的上层交互用的),但是并不妨碍我们通过C#加深对OPENGL的理解(核心思想没有变,而且C#的开发,验证效率更高)。读者需要掌握:

1 理解OPENGL的基本绘图过程,平移,旋转,缩放的

2 理解OPENGL绘制基本物体,组合物体的原理,比如小型的摆臂机器人实现原理

3 查看网上的高手的代码,针对某一些具体的功能做深入的研究,OPENGL除了能绘制二维三维的物体,还能做动力学仿真,模型的渲染等,学好这部分内容还是很有意义的

 

 

更多教学视频和资料下载,欢迎关注以下信息:

我的优酷空间:

http://i.youku.com/acetaohai123

 

我的在线论坛:

http://csrobot.gz01.bdysite.com/

 

问题交流:

QQ:910358960

邮箱:acetaohai123@163.com

 

 

C#应用视频教程2.4 OPENGL虚拟仿真介绍的更多相关文章

  1. C#应用视频教程2.1 OPENGL虚拟仿真介绍

    OPENGL的虚拟仿真对于工控自动化的意义很大,虽然市面上有很多的第三方软件比如Solidworks,Mathlab,ProE等等软件可以做仿真,而且能够实现的功能包括了流体分析,力学分析,摩擦力分析 ...

  2. C#应用视频教程2.3 OPENGL虚拟仿真介绍

    本节最重要的一个内容,就是让视野可以平移+旋转+缩放(就像打CS游戏一样以第一人称视角去观察物体,如果可能的话W,S,A,D四个按键控制人物移动,还有鼠标控制视角),本节最重要的一个概念就是设置观察视 ...

  3. C#应用视频教程2.2 OPENGL虚拟仿真介绍

    三维在理解了如何绘制2D元素之后,我们尝试绘制3D元素. 其实多个三角形也能够成四面体,多个长方形也能够成六面体,所以绘制3D元素的时候,只要顶点数量匹配就行了   这里我们尤其注意,我把绘制之前的三 ...

  4. 基于unity3d IFC的虚拟仿真系统

  5. 国家虚拟仿真实验教学项目共享平台(实验空间)PHP SDK

    使用XJWT标准,此标准基于JSON Web Token (JWT)开发.XJWT包含三个参数:header, payload, signature,因此生成token就要先获得这三个参数. clas ...

  6. 2017.04.20 Adams仿真介绍

    Adams 仿真 | 验证"隐性机器人模型"概念,提高视觉伺服精度 产品:Adams行业:科研优势: 1.Adams 仿真可精确预测机器人的位置和方位 2.仿真在理论工作验证中起着 ...

  7. 【转】OpenGL相关函数库介绍

    原文:http://blog.chinaunix.net/uid-20638550-id-1909182.html OpenGL 函数库相关的API有核心库(gl).实用库(glu).辅助库(aux) ...

  8. OpenGL教程(0)——介绍

    OpenGL介绍 OpenGL,全称Open Graphics Library,是一个用C语言写的图形API.通俗地说,OpenGL用来绘制2D/3D图形.目前OpenGL的运用十分广泛,有许多用Op ...

  9. 解析vue2.0的diff算法 虚拟DOM介绍

    react虚拟dom:依据diff算法台 前端:更新状态.更新视图:所以前端页面的性能问题主要是由Dom操作引起的,解放Dom操作复杂性 刻不容缓 因为:Dom渲染慢,而JS解析编译相对非常非常非常快 ...

随机推荐

  1. 图形管线之旅 Part3

    原文:<A trip through the Graphics Pipeline 2011> 翻译:往昔之剑   转载请注明出处   此时,我们一路上通过多个驱动层和命令处理器将draw ...

  2. javascript入门教程笔记

    BOM BOM 是“ Browser Object Model ”的缩写,简称“ 浏览器对象模型 ”. BOM 定义了 JavaScript 操作浏览器的接口,提供了访问某些功能(如浏览器窗口大小.版 ...

  3. BNU校赛总决赛J 小白兔小灰兔 相交计算几何模板

    J 小白兔小灰兔 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K Special Judge, 64bit IO Format: %lld 题目描述 ...

  4. 【洛谷】2990:[USACO10OPEN]牛跳房子Cow Hopscotch【单调队列优化DP】

    P2990 [USACO10OPEN]牛跳房子Cow Hopscotch 题目描述 The cows have reverted to their childhood and are playing ...

  5. 74.Interesting Sequence(有趣的数列)(拓扑排序)

    Interesting Sequence(有趣的数列)[Special judge] 题目概述:是否存在一个长度为n的整数数列,其任意连续p项之和为正数而任意连续q项之和为负数? 方法:连续项a[i] ...

  6. BZOJ 4443: [Scoi2015]小凸玩矩阵 最大流

    4443: [Scoi2015]小凸玩矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4443 Description 小凸和小方是好 ...

  7. Codeforces Round #299 (Div. 2) A. Tavas and Nafas 水题

    A. Tavas and Nafas Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/535/pr ...

  8. java 高并发 订单编号递增(解决方案)

    业务描述: 首先从数据中查找最近的一条订单数据,然后将之前的订单号码+1作为新的订单号码,插入到数据库当中.(需求不能改变) 当出现并发操作时,A从数据库中获取最近一条订单的订单号为N,这是A还没有完 ...

  9. img 边距的问题

    一.*{margin:0;padding:0} 不能消除img的边距 二.布局中可以使用以下方法: 1.img:{flot:left} 2.img:{vertical-align: top;}  im ...

  10. Java常量定义需要注意事项及static作用(复习)

    在任何开发语言中,都需要定义常量.在Java开发语言平台中也不例外.不过在Java常量定义的时候,跟其他语言有所不同.其有自己的特色.在这篇文章中,主要针对Java语言中定义常量的注意事项进行解析,帮 ...