这一部分我们首先实现视图控制(包括了平移/旋转/缩放),前面我们已经讲过,通过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. python 爬取世纪佳缘,经过js渲染过的网页的爬取

    #!/usr/bin/python #-*- coding:utf-8 -*- #爬取世纪佳缘 #这个网站是真的烦,刚开始的时候用scrapy框架写,但是因为刚接触框架,碰到js渲染的页面之后就没办法 ...

  2. PHP视频教程 字符串处理函数(三)

    字符串替换函数: str_replace() 替换字符串或数组元素,区分大小,第四个参数可选用于统计替换次数. str_ireplace() 不区分大小写替换 字符串函数比较 strcmp()比较字符 ...

  3. 【BZOJ 4070】【APIO 2015】雅加达的摩天楼

    http://www.lydsy.com/JudgeOnline/problem.php?id=4070 分块建图. 对每个\(P_i\)分类讨论,\(P_i>\sqrt N\)则直接连边,边数 ...

  4. [NOI2009]诗人小G --- DP + 决策单调性

    [NOI2009]诗人小G 题目描述: 小G是一个出色的诗人,经常作诗自娱自乐. 但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并 ...

  5. [BZOJ5093]图的价值(NTT+第二类Stirling数)

    5093: [Lydsy1711月赛]图的价值 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 250  Solved: 130[Submit][Sta ...

  6. 谈HTTPS中间人攻击与证书校验(一)

    一.前言 随着安全的普及,https通信应用越发广泛,但是由于对https不熟悉导致开发人员频繁错误的使用https,例如最常见的是未校验https证书从而导致“中间人攻击”,并且由于修复方案也一直是 ...

  7. php -- php读取sqlserver中的datetime出现的格式问题

    php连接sqlserver2005时,读取出来的数据是01 15 2014 12:00AM, 也就是说日期的格式是MM DD YY hh:mmAM 那如何把它转变成24小时制,且显示的格式为YY-M ...

  8. linux系统相关、硬件、资源 - 相关命令

    分类命令:   1.1.系统 # uname -a                    # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue   # 查看操作系统版本 #  ...

  9. Jenkins使用jenkins-cli.jar进行远程调用时出现“ERROR: No such job 'test'”或者权限不够等问题解决(Windows)

    网上最提倡的解决办法是用SSH的key进行登录,但是我发觉Linux上非常容易实现,但是Windows压根不知道在哪里设置. 原文:https://issues.jenkins-ci.org/brow ...

  10. objective C中的字符串NSStirng常用操作

    objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的 ...