从本节开始,我们使用SharpGL带的VS2010扩展,来直接生成SharpGL工程。

如果你新建项目时,没有看到下面的SharpGL项目,那么请事先在SharpGL源代码中找到一个叫 ”SharpGL 2.0 Visual Studio Extension“目录 ,安装名为 SharpGL.vsix的vs2010扩展, 然后重启你的vs2010.

利用上面的SharpGL项目,直接生成一个完整的SharpGL工程,它带有Opengl窗体控件,基本代码已经都完成了, 你只需要修改3D绘图部分的代码就可以了。

生成的工程是还可以直接跑起来看到效果, 如下图所示。

我们会看到了有个三棱体已经画好了,并且还正在旋转,下面还动态显示了渲染的帧数。

我们在前二篇写的代码生成的三角形像是2D的,现在如上图这样的效果,就感觉很有立体感觉了。其实,两者不一样的只是因为这个工程默认已经进行了投影变换和视点变换。

当三维体放在世界坐标系中后,由于显示器只能用二维图像显示三维休,因此必须要依赖投影来把三维体降低维数。

投影变换的目的就是定义了一个视景体,使得视景体外多余的部分不会显示。

投影包括透视投影(perspective projection)和正视投影(orthographic projection)两种。

上图就是透视投影的效果,它符合人的观察经验,即离视点近的物体大,离视点远的物体小,远到极点就消失,成为灭点。就像笔直马路的尽头看上去就成为一个点。

我们看一下代码中有关投影部分的代码, 解释一下相关功能函数的参数意义。

  1. private void openGLControl_Resized(object sender, EventArgs e)
  2. {
  3. // TODO: Set the projection matrix here.
  4. OpenGL gl = openGLControl.OpenGL;
  5. gl.MatrixMode(OpenGL.GL_PROJECTION);
  6. gl.LoadIdentity();
  7.  
  8. gl.Perspective(20.0f, (double)Width / (double)Height, 0.01, 100.0);
  9. gl.LookAt(-, , -, , , , , , );
  10.  
  11. gl.MatrixMode(OpenGL.GL_MODELVIEW);
  12. }

创建透视效果的函数名和原型为:

Perspective(double fovy, double aspect, double zNerar, double zFar);

aspect是窗口的纵横比

zNerar,zFar分别是近处和远处的裁面位置。

fovy是控制视野在XY平面的角度,范围是0--180度。你可以把它想象成是3dsmax中的相机镜头对应的视野参数。

下面的Perspective函数的示意图中, 视角指的是参数fovy, aspect=w/h, zNerar为近平面距离, zFar为远平面距离.

对于比较难以理解的参数fovy, 如果你仍然不是太明白,下面换个方式说明一下.

我们拿3dsmax的摄像机参数来做比喻(意义是类似的),上图是我们使用15mm镜头(视野为100.389度)看到的效果。小镜头看到的视野更大。摄影里面叫这种小镜头叫广角镜头。

现在使用85mm的镜头(视野为23.913度),只可以看到物体的局部了。它的可视范围变窄了。

那么 Perspective()函数的fovy参数的意义就等同于镜头所代表的视野度数。

设置好投影变换后, 接下来还要设置视点变换.

设置视点变换的函数LookAt的原形为:

LookAt(double eyex, double eyey, double eyez, double centerx, double centery, double centerz, double upx, double upy, double upz);

这个函数是做视点变换用的,你可以认为它是设置摄像机的函数。

在opengl中,默认时视点定位于坐标系的原点,初使方向指向Z轴负方向,前面说过,默认的三维模形也是贴着世界坐标系的Z轴0的深度上放置的, 因此,如果不进行视点变换,则相当于摄像机正好贴着物体,什么也看不见,这就是为什么上节的代码里面要有一句代码gl.Translate()用于把把物体往Z轴负方向移动一定距离的原因。

我们还是以3dsmax中的摄像机来类比。下面的示意图中,我们使用的是一种被称为”目标摄像机“的相机,之所以这么称谓,是因为为这个摄像机带一个目标点可以调节。

前三个参数 eyex, eyey, eyez 表示摄像机本身位于世界坐标系中的位置。

在3dsmax中,摄像机的位置可以任意平移的.

上图我们放置的位置是XY轴刚好对着世界坐标系的原点。Z轴朝正方向走了老远。因为摄像机离物体远了,因此可以正常看到物体。

上图中,摄像机的XYZ都远离了物体做了变换,相当于在围绕三维体进行观察。

当中三个参数 centerx, centery,  centerz 相当于调整了3dsmax目标摄像机的目标点位置。

如上图所示, 改变目标点的位置也有类似围绕观察对象的效果。并且,这个目标点在Z轴上相对于物体的距离是没有什么意义的,主要意义是在XY上的变化上。这一点读者可以自己去试验。

最后三个参数 upx, upy, upz相当于在旋转3dsmax目标摄像机。

不过这个参数的值并不是角度值,而是向量,数值的大小没意义,正负值才有意义。

在3dsmax中,摄像机是可以任意角度旋转的。

但是在Lookat()函数中这最后三个参数, upx,upy 只能在上下,左右,45度这几个角度中变换,而且upz取值似乎没什么意义。

解释完这两个函数,我们用程序绘制一个三角形来测试一下上述视点变换和投影变换的效果。

上图是视野为20的效果,可以看到三角形看上去大些了。

视野改为60,三角形看上去小些了。

以上结果和上面分析Perspective()函数的fovy参数时结论是一致的。

现在我们改动LookAt的前三个参数,三角形正对着我们显示了。

现在我们改变LookAt的最后三个参数,Y向量改为-1,相当于摄像机旋转向下180度,结果三角形朝下了。

为了节约下载空间,以后的源代码中,笔者都把SharpGL的三个dDLL文件都删除了。

请你自己把这三个dll文件拷贝到: ”Dependencies“,  "bin\debug\" 这两个目录中去。再打开工程。

以后不在赘述。

本文源代码下载

原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/

SharpGL学习笔记(三) 投影变换和视点变换的更多相关文章

  1. SharpGL学习笔记(八) 矩阵堆栈和变换的综合例子: 机器人

    我们先引入关于"矩阵堆栈"的官方说法: OpenGL的矩阵堆栈指的就是内存中专门用来存放矩阵数据的某块特殊区域.实际上,在创建.装入.相乘模型变换和投影变换矩阵时,都已用到堆栈操作 ...

  2. SharpGL学习笔记(七) OpenGL的变换总结

    笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对& ...

  3. 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记

    回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...

  4. SharpGL学习笔记(十一) 光源创建的综合例子:光源参数可调节的测试场景

    灯光的测试例子:光源参数可以调节的测试场景 先看一下测试场景和效果. 场景中可以切换视图, 以方便观察三维体和灯光的位置.环境光,漫射光,镜面反射光都可以在四种颜色间切换. 灯光位置和摄像机位置(Lo ...

  5. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  6. [Firefly引擎][学习笔记三][已完结]所需模块封装

    原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读:        笔记三主要就是各个模块的封装了,这里贴 ...

  7. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  8. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  9. VSTO学习笔记(三) 开发Office 2010 64位COM加载项

    原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...

随机推荐

  1. 监听输入框值变化的最佳方案 oninput 和 onpropertychange (实时监控文本框改变的最佳方案)

    公司有个文本框,当输入文字/粘贴/复制 或者是键盘猛按的时候,都希望这个文本框能统计出 输入了多少字   这种用 onchange   onkeyup  onkepress  都不怎么好使   最后在 ...

  2. motiMaker 软件安装测试

    背景: mitoMaker是一款线粒体/叶绿体组装的pipeline软件,可以从原始的下机数据开始,自动化的组装基因组,注释基因结构,最终生成genebank, fasta 等文件. 整个pipeli ...

  3. 超炫酷的jQuery/HTML5应用效果及源码

    jQuery非常强大,我们之前也用jQuery分享过很多实用的插件.HTML5可以让网页变得更加绚丽多彩,将HTML5和jQuery结合使用那将发挥更棒的效果. 今天向大家收集了一些关于HTML5和j ...

  4. Java SE 8 并发增强

    1.原子值 java5开始,提供了一些原子操作的类,如AtomicInteger.AtomicLong等 这些类提供了诸如incrementAndGet这样的原子操作方法. 单数如果想进行复杂操作,则 ...

  5. python的sciter库Pysciter安装教程(win32 + win64)

    Pysciter是一个结合HTML与Python编写桌面软件个三方库 注:无论是32位还是64位电脑,建议安装32位的sciter,这样写出来的软件可以在win32和win64电脑上都可以运行(前提p ...

  6. GetDlgItem的用法小结

    GetDlgItem用于获得指定控件ID的窗体指针,函数原型如下: HWND GetDlgItem( HWND hDlg, int nIDDlgItem ); CWnd* GetDlgItem(int ...

  7. Linq 查询某个字段为null的数据

    如tb_flag 数据结构如下:flag int null 不能使用:flag==null 生成的SQL语句为 where flag=null   建议使用:可空类型 用Nullable<T&g ...

  8. highcharts系列之xAxis

    xAxis定义的是x坐标轴的配置选项.默认情况下,x轴指的是水平轴,特殊指定的时候也可以作为垂直的轴使用,在多坐标系中,xAxis是有多个配置好了的轴object的数组. 下面来看一下,xAxis常用 ...

  9. UnitOfWork 更新实体出错解决办法

    用UnitOfWork进行实体更新的时候,再查询实体一次,再去更新的时候会报如下错误: Attaching an entity of type 'TinyFrame.Data.DomainModel. ...

  10. 用plsql 导入导出oracle表结构数据

    一.导出 (1)导出数据 进入pl/sql,"工具"---->"Export Tables...",然后在弹出的对话框中选择要导出的表,最后点击" ...