OpenGL中glRotatef()函数究竟对矩阵做了什么

我们知道OpenGL中维持着两套矩阵,一个是模型视图矩阵(model view matrix),另一个是投影矩阵(projection matrix)。而Direct3D维持着三个矩阵,其实它们的本质是一样的,因为Model(World)矩阵×View矩阵 = ModelView矩阵,也就是OpenGL的模型视图矩阵。通过对OpenGL这两套矩阵的变换,我们可以得到各种投影效果。这回我就来研究OpenGL中一个常见的函数glRotatef(d)。

    

    看参数,glRotatef( angle, x, y, z )函数的作用是将当前坐标系以a( x, y, z )向量为旋转轴旋转angle角度。这种方法可以以简单明白的方式将世界坐标系进行旋转。但是在内部,OpenGL究竟是用什么公式对其进行旋转呢?


    原创文章,反对未声明的引用。原博客地址:http://blog.csdn.net/gamesdev/article/details/9929211

为了弄清楚真相,我们开始研究矩阵的相关知识。首先,我们考虑单位矩阵I在绕着坐标轴旋转后所得的旋转矩阵。这里我直接列出了三种情况:

知道了绕着三轴后的旋转矩阵,那么下面就是绕任意向量所得的矩阵了。设M为单位矩阵经向量a旋转后的矩阵,且a = (xa, ya, za),旋转角度为α,则M=

我其实也不明白该如何证明的,不过我们可以编写一个小程序来验证一下:

#include <assert.h>
#include <stdio.h>
#include <math.h>
#include "GLWidget.h" void PrintMatrix( float matrix[16] )
{
assert( matrix != 0 );
printf( "%8.2f%8.2f%8.2f%8.2f\n"
"%8.2f%8.2f%8.2f%8.2f\n"
"%8.2f%8.2f%8.2f%8.2f\n"
"%8.2f%8.2f%8.2f%8.2f\n",
matrix[0], matrix[1], matrix[2], matrix[3],
matrix[4], matrix[5], matrix[6], matrix[7],
matrix[8], matrix[9], matrix[10], matrix[11],
matrix[12], matrix[13], matrix[14], matrix[15] );
} void MyRotatef( float matrix[16],
float angleInDegree,
float x,
float y,
float z )
{
assert( matrix != 0 ); // 向量的单位化
float length = sqrt( x * x + y * y + z * z );
assert( !qFuzzyCompare( length, 0.0f ) );// 希望length不为0 x /= length;
y /= length;
z /= length; float alpha = angleInDegree / 180 * 3.1415926;// 已转换弧度制
float s = sin( alpha );
float c = cos( alpha );
float t = 1.0f - c; #define MATRIX( row, col ) matrix[row * 4 + col]
MATRIX( 0, 0 ) = t * x * x + c;
MATRIX( 0, 1 ) = t * x * y + s * z;
MATRIX( 0, 2 ) = t * x * z - s * y;
MATRIX( 0, 3 ) = 0.0f;
MATRIX( 1, 0 ) = t * x * y - s * z;
MATRIX( 1, 1 ) = t * y * y + c;
MATRIX( 1, 2 ) = t * y * z + s * x;
MATRIX( 1, 3 ) = 0.0f;
MATRIX( 2, 0 ) = t * x * z + s * y;
MATRIX( 2, 1 ) = t * y * z - s * x;
MATRIX( 2, 2 ) = t * z * z + c;
MATRIX( 2, 3 ) = 0.0f;
MATRIX( 3, 0 ) = 0.0f;
MATRIX( 3, 1 ) = 0.0f;
MATRIX( 3, 2 ) = 0.0f;
MATRIX( 3, 3 ) = 1.0f;
#undef MATRIX
} GLWidget::GLWidget( QWidget* pParent ):
QGLWidget( pParent )
{
setWindowTitle( "Test OpenGL Matrix" );
} void GLWidget::initializeGL( void )
{
float angle = 30.0f;
float x = 12.0f;
float y = 8.0f;
float z = 3.0f; float matrix1[16], matrix2[16];
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
glGetFloatv( GL_MODELVIEW_MATRIX, matrix1 );
glGetFloatv( GL_MODELVIEW_MATRIX, matrix2 ); printf( "The initial identity matrix is:\n" );
PrintMatrix( matrix2 );
printf( "Now perform OpenGL glRotate function.\n" );
glRotatef( angle, x, y, z );
glGetFloatv( GL_MODELVIEW_MATRIX, matrix1 );
PrintMatrix( matrix1 ); printf( "Now perform MyRotate function.\n" );
MyRotatef( matrix2, angle, x, y, z );
PrintMatrix( matrix2 );
} void GLWidget::paintGL( void )
{ }

程序的运行结果如下:


这说明上面的这条公式是正确的。如此一来我们就知道了glRotatef()的原理啦。其实D3DXMatrixRotationAxis()函数也是这样操作的,只不过D3D是左手坐标系,它的矩阵构建方法又会有所不同。

OpenGL中glRotatef()函数究竟对矩阵做了什么的更多相关文章

  1. OpenGL中两种计算投影矩阵的函数

    OpenGL无意间同时看到两种创建投影矩阵的写法,可以说它们完成的是同样的功能,但写法完全不同,可以观摩一下什么叫做异曲同工之妙... 第一种: gltMakeShadowMatrix函数是重点 // ...

  2. js中在一个函数中引用另一个函数中的函数,可以这么做

    在另一个函数中,将需要使用的函数绑定在window下 // UEditor $(function () { window.ue = UE.getEditor('editor', { // ue即可成为 ...

  3. 计算机图形学OpenGL中的glLoadIdentity、glTranslatef、glRotatef原理,用法 .(转)

    单位矩阵 对角线上都是1,其余元素皆为0的矩阵. 在矩阵的乘法中,有一种矩阵起着特殊的作用,如同数的乘法中的1,我们称这种矩阵为单位矩阵. 它是个方阵,除左上角到右下角的对角线(称为主对角线)上的元素 ...

  4. OpenGL中平移、旋转、缩放矩阵堆栈操作

    在OpenGL中,图元的几何变换均为线性变换,通过矩阵变换实现.OpenGL中的坐标用齐次坐标表示,即(x,y,z)表示成(x',y',z',h),其中x=x'/h; y=y'/h; z=z'/h. ...

  5. (转)思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...

    转自:http://www.cnblogs.com/soroman/archive/2008/03/21/1115571.html 思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用1. ...

  6. OpenGL中glPushMatrix和glPopMatrix的原理

    glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPush ...

  7. OpenGL中坐标系的理解(一)

    在OpenGL中,存在着至少存在着三种矩阵,对应着函数glMatrixMode()的三个参数:GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE. 以下主要描述GL_MODEL ...

  8. OpenGL中常用的函数

    OPengl的官方文档如下:https://www.opengl.org/sdk/docs/man4/ void glGetIntegerv(   GLenum pname,      GLint * ...

  9. 关于opengl中的矩阵平移,矩阵旋转,推导过程理解 OpenGL计算机图形学的一些必要矩阵运算知识

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12166896.html 为什么引入齐次坐标的变换矩阵可以表示平移呢? - Yu Mao的回答 ...

随机推荐

  1. 1011. A+B和C

    /* * Main.c * 1011. A+B和C * Created on: 2014年8月30日 * Author: Boomkeeper *********测试通过******* */ #inc ...

  2. 05-3. 求a的连续和(15)

    输入两个整数a和n,a的范围是[0,9],n的范围是[1,8],求数列之和S = a+aa+aaa+...+aaa...a(n个a). 如a为2.n为8时输出的是2+22+222+...+222222 ...

  3. axis2 webservices 411错误解决办法

    错误:org.apache.axis2.AxisFault: Transport error: 411 Error: Length Required 可能会导致这个问题的原因: 1.访问地址经过端口映 ...

  4. python魔术方法

    在类中有一些特殊的方法具有特殊的意义,比如__init__和__del__方法,它们的重要性我们已经学习过了. 一般说来,特殊的方法都被用来模仿某个行为.例如,如果你想要为你的类使用x[key]这样的 ...

  5. mysql_healthly

    cat mysql_healthly.php <?php if (!defined('IN_PDK')){ define('IN_PDK', true); } $db_name = $_GET[ ...

  6. 将Linux下编译的warning警告信息输出到文件中[整理笔记]

    Linux中,脚本语言环境中,即你用make xxx即其他一些普通linux命令,比如ls,find等,不同的数字,代表不同的含义: 数字 含义 标准叫法0 标准输入  stdin = standar ...

  7. 13-7-1 做了一个360优化大师的主页(就是一个主页UI)

    模仿360优化大师做了一个下它的首页.   代码如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/re ...

  8. JSP 文件上传下载系列之二[Commons fileUpload]

    前言 关于JSP 文件上传的基础和原理在系列一中有介绍到. 这里介绍一个很流行的组件commons fileupload,用来加速文件上传的开发. 官方的介绍是:  让添加强壮,高性能的文件到你的se ...

  9. Sublime-text 自己定义快捷键攻略

    好吧.我承认今天非常悲剧,本来上午就写好了这篇博文,公布之后,在自己的博文里怎么也找不到. 所以如今又又一次写了一份.希望大家能顶一下吧...Nothing is better than your s ...

  10. 温故而知新之数据库的分离和附加…高手请跳过….

    sql server2005分离数据库后,把路径下的两个文件拷到自己想要存放的目录下,然后再附加