(二) 模型变换

模形变换就是指的在世界坐标系中(world space)做“移动”,“旋转", "缩放"三种操作。

首先要说明的,在Opengl中,是用4x4矩阵进行坐标变换,OpenGL的4x4矩阵是按列排列的,就像下面这样。

所谓的模型变换,就是对这个矩阵进行变换。

描述三维世界你就得先设计三维模形。 在设计三维模形的时候,它是们于模形坐标系中的,最终它会放置到世界坐标系统中,如果这个模形设计时处理的好的话,放到世界坐标系中时默认就是模形的中心定位于世界坐标系统的中心处。

这里有一个延伸的知识点:模形放置到世界坐标系时中心不位于世界坐标系中心处,是怎么回事?有什么后果?  这个以后我们会做一个扩展性的讨论。

上面说的是导入其它设计软件制作的模形,比如3dsMax制作的模形的情况。如果我们自己用代码画的模形,自然是默认就位于世界坐标系统的中心。

这个世界坐标系,就像下图一样:

X轴箭头方向为正,反过来为负

Y轴箭头方向为正,反过来为负

Z轴箭头方向正好指向我们的眼睛,因此图上只是个小点,看不见,它负方向向屏幕里面。

而下图中的三维体的中心就刚好们于这个世界坐标系的中心。

下面的演示代码在世界坐标系统中画出一个三角形,再对它做一些变换操作。

 using System;
using System.Windows.Forms;
using SharpGL; namespace blankTest
{
public partial class Form1 : Form
{
private int mtype = ;
public Form1()
{
InitializeComponent(); } private void Form1_Load(object sender, EventArgs e)
{ } private void openGLControl1_OpenGLInitialized(object sender, EventArgs e)
{ } private void openGLControl1_Resize(object sender, EventArgs e)
{ } private void openGLControl1_OpenGLDraw(object sender, PaintEventArgs e)
{
SharpGL.OpenGL gl = this.openGLControl1.OpenGL; gl.ClearColor(, , , );
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); switch (mtype)
{
case :
translateSample(gl);
break;
case :
rotateSample(gl);
break;
case :
scaleSample(gl);
break;
} gl.Finish();
gl.Flush();
} private void scaleSample(SharpGL.OpenGL gl)
{
gl.LoadIdentity();
gl.Scale(1f, 1f, 1f);
gl.Translate(, , -9f);
drawPT(gl); gl.LoadIdentity();
gl.Scale(5f, 1f, 1f);
gl.Translate(, , -9f);
drawPT(gl);
} private void rotateSample(SharpGL.OpenGL gl)
{
gl.LoadIdentity();
gl.Rotate(,, );
gl.Translate(, , -8f);
drawPT(gl); gl.Rotate(, , );
gl.Translate(-, ,0f);
drawPT(gl);
} private void translateSample(SharpGL.OpenGL gl)
{
gl.LoadIdentity();
gl.Translate(0f, 0f, -3f);
drawPT(gl); gl.LoadIdentity();
gl.Translate(0f, 1f, -3f);
drawPT(gl);
} private void drawPT(SharpGL.OpenGL gl)
{
gl.PointSize(5f);
gl.Begin(OpenGL.GL_TRIANGLES);
{
gl.Vertex(0.0f, 0f, 0.0f);
gl.Vertex(-1.0f, -1f, 0.0f);
gl.Vertex(1.0f, -1f, 0.0f);
}
gl.End();
} private void btnTranslate_Click(object sender, EventArgs e)
{
switch (((Button)sender).Name)
{
case "btnTranslate":
mtype = ;
break;
case "btnRotate":
mtype = ;
break;
case "btnScale":
mtype = ;
break;
}
} }
}

三个函数translateSample(),  rotateSample(),scaleSample() 分别演示”平移“,”旋转“,”缩放”。

我们来谈谈一些重点的地方:

在“平移”函数中,如果没有gl.LoadIdentity()函数复位坐标系统到原点位置,那么执行结果会不同,第二条gl.Translate(0f,1f,-3f)将会是相对于上一条gl.Translate的位置(0f,0f,-3f)移动。

而每次绘制三角形之前做一次gl.LoadIdentity(), 相当于每次绘图时的中心点坐标都从原点算起。

  private void translateSample(SharpGL.OpenGL gl)
{
gl.LoadIdentity();
gl.Translate(0f, 0f, -3f);
drawPT(gl); gl.LoadIdentity();
gl.Translate(0f, 1f, -3f);
drawPT(gl);
}

gl.Translate中的Z轴设置为0,则物体不可见,因为这时候画出来的三角形,贴着世界坐标系的Z轴。就像你的眼睛贴跟它零距离一般。

你可以想象成摄像机位于世界坐标系统(0,0,0), 走向Z轴的负方向。

为了说明白这点,博主画了个示意图如下:

图中的栅格面就代表了世界坐标系平面,两条相互垂直的粗黑线就是世界坐标系的XY轴, 你的眼睛会正对着这个世界坐标系平面看. 
现在三维box的底面(红色面)正好贴在世界坐标系的Z轴为0的深度上。相当于你的眼睛跟物体零距离. 因此你得把这个Box向Z轴的负方向走上-1个或者更多个,才可以看见这个Box.

这段程序的运行效果如下:

平移

旋转

缩放

本节源代码下载

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

SharpGL学习笔记(二) 模型变换(几何变换)的更多相关文章

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

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

  2. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  3. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  4. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  5. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  6. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  7. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  8. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  9. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

随机推荐

  1. QMusic

    https://github.com/dragondjf/QMusic        QMusic是基于python + PyQT5 + QML的一款本地音乐播放器,旨在提升Linux下更好的音乐播放 ...

  2. 同一个Tomcat部署两个project之间的通信问题

    同一个tomcat下的两个project是无法通信的. 同一个tomcat中的project能互相调用吗 启动一个tomcat部署多个项目,那么每个项目算是一个线程还是进程呢? Tomcat中的pro ...

  3. Java编程思想学习笔记——访问权限修饰词

    几种访问权限修饰词 public,protected,private,friendly(Java中并无该修饰词,即包访问权限,不提供任何访问修饰词) 使用时,放置在类中成员(域或方法)的定义之前的,仅 ...

  4. 基于bootstrap-multiselect.js的下拉框联动

    背景:当option特别多时,一般的下拉框选择起来就有点力不从心了,所以使用multiselect是个很好的选择,可以通过输入文字来选择选项很方便,但是有一个需要下拉框联动,网上找了半天才找到解决方法 ...

  5. Windows 下 绿化 Oracle

    既然Oracle在非windows平台上可以很“绿色”的执行,那么在windows平台上有无可能呢? 答案是“Yes-No” 基本上,除了监听器(lisentner)这个异类外,Oracle实例完全可 ...

  6. SQL2005数据库置疑处理

    2005中遇到置疑.丢失日志时按照网上常见的MSSQL2000修复方法来做, 结果发现行不通,甚至连一步都做不下去.其实,在MSSQL2005在处理置疑问题的思 路与MSSQL2000是一致的,但具体 ...

  7. Visual Studio 2012中使用GitHub

    前言 一直以来都想使用Git来管理自己平时积累的小代码,就是除了工作之外的代码了.有时候自己搞个小代码,在公司写了,就要通过U盘或者网盘等等 一系列工具进行Copy,然后回家才能继续在原来的基础上作业 ...

  8. Base64编码——学习笔记

    Base64是一种编码方式. 非加密 chcp->936 编码流程: 位数不够后面补0,例中补了2个0. 末尾加=表示结束符. GB2312,有些敏感词不能显示. GBK,是GB2312升级版. ...

  9. 通过MyEclipse部署web应用程序开发环境

    1.下载并安装MyEclipse10 2.配置java开发的jar包 3.配置tomcat服务器 4.部署tomcat服务器 点击Bronse可以查看部署后的文件夹目录 5.启动tomcat服务器 6 ...

  10. 如何通过Node.js启动cesium

    设置一个Web服务器通过Node.js是很容易的,只需要3个步骤: (1)从安装Node.js网站,你可以使用默认安装设置. (2)打开命令行,然后进入Cesium的根目录,通过npm install ...