博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SharpGL学习笔记(二) 模型变换(几何变换)
阅读量:6689 次
发布时间:2019-06-25

本文共 4556 字,大约阅读时间需要 15 分钟。

(二) 模型变换

 

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

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

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

 

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

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

 

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

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

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

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

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

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

 

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

1 using System;  2 using System.Windows.Forms;  3 using SharpGL;  4   5 namespace blankTest  6 {  7     public partial class Form1 : Form  8     {  9         private int mtype = 0; 10         public Form1() 11         { 12             InitializeComponent(); 13  14         } 15  16         private void Form1_Load(object sender, EventArgs e) 17         { 18  19         } 20  21         private void openGLControl1_OpenGLInitialized(object sender, EventArgs e) 22         { 23  24         } 25  26         private void openGLControl1_Resize(object sender, EventArgs e) 27         { 28          29         } 30  31         private void openGLControl1_OpenGLDraw(object sender, PaintEventArgs e) 32         { 33             SharpGL.OpenGL gl = this.openGLControl1.OpenGL; 34  35             gl.ClearColor(0, 0, 0, 1); 36             gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); 37  38             switch (mtype) 39             { 40                 case 0: 41                     translateSample(gl); 42                     break; 43                 case 1: 44                     rotateSample(gl); 45                     break; 46                 case 2: 47                     scaleSample(gl); 48                     break; 49             } 50              51             gl.Finish(); 52             gl.Flush(); 53         } 54  55         private void scaleSample(SharpGL.OpenGL gl) 56         { 57             gl.LoadIdentity(); 58             gl.Scale(1f, 1f, 1f); 59             gl.Translate(0, 0, -9f); 60             drawPT(gl); 61  62             gl.LoadIdentity(); 63             gl.Scale(5f, 1f, 1f); 64             gl.Translate(0, 1, -9f); 65             drawPT(gl); 66         } 67  68         private void rotateSample(SharpGL.OpenGL gl) 69         { 70             gl.LoadIdentity(); 71             gl.Rotate(0,0, 45); 72             gl.Translate(0, 0, -8f); 73             drawPT(gl); 74  75             gl.Rotate(0, 0, 45); 76             gl.Translate(-1, 1,0f); 77             drawPT(gl); 78         } 79  80         private void translateSample(SharpGL.OpenGL gl) 81         { 82             gl.LoadIdentity(); 83             gl.Translate(0f, 0f, -3f); 84             drawPT(gl); 85  86             gl.LoadIdentity(); 87             gl.Translate(0f, 1f, -3f); 88             drawPT(gl); 89         } 90  91         private void drawPT(SharpGL.OpenGL gl) 92         { 93             gl.PointSize(5f); 94             gl.Begin(OpenGL.GL_TRIANGLES); 95             { 96                 gl.Vertex(0.0f, 0f, 0.0f); 97                 gl.Vertex(-1.0f, -1f, 0.0f); 98                 gl.Vertex(1.0f, -1f, 0.0f); 99             }100             gl.End();101         }102 103         private void btnTranslate_Click(object sender, EventArgs e)104         {105             switch (((Button)sender).Name)106             {107                 case "btnTranslate":108                     mtype = 0;109                     break;110                 case "btnRotate":111                     mtype = 1;112                     break;113                 case "btnScale":114                     mtype = 2;115                     break;116             }117         }118 119     }120 }

 三个函数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://hokoo.baihongyu.com/

你可能感兴趣的文章
Bound Service
查看>>
解决twisted 的socket长连接问题
查看>>
JS错误类型的学习
查看>>
JOIN关联表中ON,WHERE后面跟条件的区别
查看>>
Could not find result map java.lang.String
查看>>
Spring读取Properties配置文件
查看>>
android 获得根视图 和获得根actionbar
查看>>
jquery实现hover图片半透明效果
查看>>
(在线文库系统)centos+nginx+mysql+php+openoffice+pdf2swf+pdf2image
查看>>
linux挂载/卸载U盘
查看>>
MAP-Diameter IWF Introduction
查看>>
MOS9.0源搭建安装
查看>>
j2ee-url-pattern
查看>>
集群之Mysql主从与环形详细配置步骤(4)(已重新整理)
查看>>
PHP提取身份证号码中的生日并验证是否成年的函数
查看>>
Apache mina 通信第二步发送消息 在线发送消息和离线接受消息
查看>>
Genesis-3D新手入门——8.天空盒
查看>>
char ch[3]中的ch在哪
查看>>
2014年度总结暨2015大致计划
查看>>
我的友情链接
查看>>