(二) 模型变换

模形变换就是指的在世界坐标系中(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. php模拟post提交请求与调用接口

    /** * 模拟post进行url请求 * @param string $url * @param string $param */ function request_post($url = '', ...

  2. EJB里的问题解答

    1.什么是EJB? EJB即Enterprise JavaBean是JavaEE应用的业务层技术标准,以这项技术开发的组件叫做EJB组件. EJB架构师一个用于开发和部署基于组件的分布式业务应用的组件 ...

  3. GCT之数学公式(微积分)

  4. 避免使用jQuery的html方法来替换标签,而是使用replaceWith方法

    tblCostSplit.html内容: <nobr title="">只想显示里面内容,去掉nobr标签</nobr> <nobr title=&q ...

  5. vue二级联动select

    <div> <span>所在区域</span> <select name="" v-model="country"&g ...

  6. 在Unity中查找缺失的引用

    这篇博客是查找unity中缺失引用的一个简单简短的解决方案.你可以从GitHub上获取源码. 缺失引用 一个丢失引用与没有引用(在检视表显示“None”)是完全不同的概念.这些友各种原因造成,比如:把 ...

  7. Linux远程管理之SVN,VNC

    一.远程管理的基本概念 首先我们来初略的讲讲远程管理的一些基本概念.对于我们使用的计算机来说,如果是个人计算机,就没有远程管理这一概念了,想用的时候开机就能使用,而对于我们的服务器来说,就不同了,对于 ...

  8. spring+mybatise注解实现

    spring+mybatise注解实现 spring.jpa.database=MYSQL spring.datasource.type=com.alibaba.druid.pool.DruidDat ...

  9. java登录央行征信网站

    package com.entrym.crawler.test; import java.util.HashMap; import java.util.Map; import org.apache.c ...

  10. 8 -- 深入使用Spring -- 2...3 使用@Resource配置依赖

    8.2.3 使用@Resource配置依赖 @Resource 位于javax.annotation包下,是来自Java EE规范的一个Annotation,Spring直接借鉴了该Annotatio ...