SharpGL学习笔记(二) 模型变换(几何变换)
(二) 模型变换
模形变换就是指的在世界坐标系中(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学习笔记(二) 模型变换(几何变换)的更多相关文章
- SharpGL学习笔记(七) OpenGL的变换总结
笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对& ...
- WPF的Binding学习笔记(二)
原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...
- AJax 学习笔记二(onreadystatechange的作用)
AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...
- [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计
源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...
- JMX学习笔记(二)-Notification
Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- Java IO学习笔记二
Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...
- 《SQL必知必会》学习笔记二)
<SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...
- NumPy学习笔记 二
NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...
随机推荐
- C# 时间比较方法DateTime.Compare
public static int Compare(DateTime t1,DateTime t2) 返回值 类型:System..::.Int32 有符号数字,指示 t1 和 t2 的相对值. 值类 ...
- Web打印控件Lodop实现证件套打
第一次接触Lodop大概是在两年前了,那时候研究Lodop主要是为了验证它能不能实现打印时在不修改内容的前提下调整样式,结果是ok的,如今又一次接触它,是因为工作中需要使用它了,于是再一次碰面 Lod ...
- vimdiff的常用命令
★ 跳转到下一个diff点: 请使用 ]c 命令★ 跳转到前一个diff点: 请使用 [c命令如果在命令前加上数字的话,可以跳过一个或数个差异点,从而实现跳的更远.比如如果在位于第一个差异点的行输入& ...
- 数据源HikariCP(多数据库的配置项)
oracle.jdbc.type=oracle oracle.jdbc.driver=oracle.jdbc.OracleDriver oracle.jdbc.url=jdbc:oracle:thin ...
- 简单理解IoC与DI
为了理解Spring的IoC与DI从网上查了很多资料,作为初学者,下面的描述应该是最详细,最易理解的方式了. 首先想说说IoC(Inversion of Control,控制倒转).这是spring的 ...
- cordova ios and ios8
ios8发布后,一些用cordova编写的app会碰到问题,总的来说,cordova官方称是完全支持ios8的,而且由于ios8推出的WKWebView存在问题并没能很好的解决(看原文),仍旧用了UI ...
- nvm安装node和npm,个人踩坑记录
我采用nvm-setup安装windows版本的nvm nvm安装node出现的问题: 1.node成功了,npm没成功 解决:在nvm 安装了node之后,输入npm找不到该命令,当时安装报错如下: ...
- phoenix连接hbase数据库,创建二级索引报错:Error: org.apache.phoenix.exception.PhoenixIOException: Failed after attempts=36, exceptions: Tue Mar 06 10:32:02 CST 2018, null, java.net.SocketTimeoutException: callTimeou
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- python 字符串格式化,使用f前缀
格式化一般用%,但后来推荐用format format有进步,可以用索引或者名字,但仍然没有很方便和快捷 # logger.debug('{} {} {} {} {} {}'.format(metho ...
- 禁止requests请求https的提示InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more
提示这个 InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from ...