SharpGL学习笔记(二) 模型变换(几何变换)

摘要:
表单8{9privateintmtype=0;1314}1516privatevoidForm1_Load(objectsender;EventArgse)17{1819}2021privatevoiveopenGLControl1_OpenGLInitialized(objectsend;

(二) 模型变换

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

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

SharpGL学习笔记(二) 模型变换(几何变换)第1张

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

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

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

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

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

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

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

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

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

SharpGL学习笔记(二) 模型变换(几何变换)第2张

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

  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.

SharpGL学习笔记(二) 模型变换(几何变换)第3张

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

SharpGL学习笔记(二) 模型变换(几何变换)第4张

平移

SharpGL学习笔记(二) 模型变换(几何变换)第5张

旋转

SharpGL学习笔记(二) 模型变换(几何变换)第6张

缩放

本节源代码下载

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

免责声明:文章转载自《SharpGL学习笔记(二) 模型变换(几何变换)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#——获取鼠标当前坐标1、背景介绍及移动云MAS平台 --短信平台下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

如何在Ubuntu 20.04 Linux操作系统上安装Git

在继续下面的过程来安装Git之前,请确保您的操作系统是Ubuntu 20.04,并且您已经以具有sudo特权的用户身份登录。使用APT软件包管理器安装Git建议的,最简单的将Git安装到Ubuntu系统的方法是使用Ubuntu操作系统默认存储库中的本机软件包管理器(APT)。此过程将使用Ubuntu存储库中可用的版本安装Git,但如果要安装其他任何版本或最...

Windows Embedded CE 6.0开发环境的搭建 .

   最近要做一个Windows CE系统上的串行通讯程序,因为在此之前并没有接触过有关Windows嵌入式方面的应用开发,所以搭建开发环境成了摆在面前的第一道难题。本文将记录并总结我搭建Windows Embedded CE 6.0开发环境的步骤和过程中碰到的问题,希望给同为Windows嵌入式开发初学者的朋友们提供一个参考。       我最终确定的开...

【Shell脚本学习1】Shell简介:什么是Shell,Shell命令的两种执行方式

Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。 它虽然不是Unix/Linux系...

国内外免费PHP开源建站程序

互联网上有很多开源建站程序供站长选择,做社区时你在Discuz和PHPWind之间做比较,做资讯网时你在DedeCMS、PHPCMS和Wordpress之间比较,虽然如此,你依然不知道选择什么程序好,折腾好几个来回。 但还好你有得选,最头痛的是想做一个网站但找不到合适的程序,这里将28套程序分为[论坛社区]、[CMS内容管理]、[企业建站]、[网上商店]...

MFC入门(一)

Windows消息机制 基本概念解释 1) SDK和API SDK:软件开发工具包(Software Development Kit),一般都是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。 API函数: Windows操作系统提供给应用程序编程的接口(Application Programming Int...

支付系统流程

想要精通一个行业需要多久? 我的回答是I don't know,断断续续做支付这一块的业务有几年了,但是感觉刚刚入门。 很久没有写博客了。。。不知道要怎么写了。 --------------------------------------------------------------- 以下支付的说明,均是基于跨境电商,支付渠道如无特殊说明,均是指Pay...