`
jgsj
  • 浏览: 960713 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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(Angle,Xvector,Yvector,Zvector) 用于绕轴旋转物体, 这是一条十分有用的函数。 Angle 是一个用于指定旋转角度的数字(通常存储于变量中)。 Xvector, Yvector 和 Zvector 这三个参数用于描述一条向量, 以...

    OpenGl实验报告.doc

    体会 通过本次试验的实践,使我更加了解和初步掌握了OpenGL的用法,对使用OpenGl 绘制球体等图形有了充分认识,并对平移矩阵堆栈和旋转矩阵堆栈的使用有了初步的 掌握。虽然以前没有接触过OpenGl,但是通过学习...

    用opengl绘制一个旋转正方体.cpp

    //这个函数其实就是对接下来要做什么进行一下声明 GL_MODELVIEW 模型视图 glLoadIdentity(); glPushMatrix();// 提供了相应的接口 { glRotatef(AngleX, 1.0f, 0.0f, 0.0f); glRotatef(AngleY, 0.0f, 1.0f, ...

    OpenGL实现3D模型旋转

    OpenGL实现ArcBall的三维模型旋转,VC工程,直接运行成功

    opengl/c++贪吃蛇.rar

    VS工程奉上,运行逻辑应该无问题,用六面体代表贪吃蛇的身体,绘制用一个数组保存所有的顶点,用一个数组保存顶点的序号。...但是没有调gluLookAt和glRotatef,运行起来是二维的。c++和opengl都是初学,请大家指正。

    OpenGL读取3DS文件示例

    调用CLoad3DS的Import3DS函数,从文件中读取g_3DModel 调用CreateTexture,装入纹理 【MainLoop】 循环调用RenderScence渲染场景,直到窗口关闭时退出 删除场景中对象 效用DeInit恢复初始化之前的状态 ...

    opengl的太阳系模型

    //对齐像素字节函数 glGenTextures(1,texName); //第一个参数指定表明获取多少个连续的纹理标识符 glBindTexture(GL_TEXTURE_2D , *texName); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); ...

    opengl 3d文字

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(.0f, .0f, -10.0f); ... glPrint("Active opengl outline f 是ont text with NeHe - %7.2f", rot / 50);

    opengl橡皮筋

    glRotatef(roangles3, 0.0, 1.0, 0.0); #ifdef GL_VERSION_1_1 glBindTexture(GL_TEXTURE_1D, texName); #endif //glutSolidTeapot(2.0); glTranslated(-1, -3, -0); glRotatef(90, 1.0f, 0.0f, 0.0f); ...

    sunearthmoon模拟系统

    vc6.0 结合OPENGL库实现的太阳、月亮、地球运转模拟系统 ...opengl vc6.0 sunearthmoon glutwiresphere glrotatef sunearthmoon模拟系统 opengl vc6.0 sunearthmoon glutwiresphere glrotatef sunearthmoon模拟系统

    使用Tao和C#进行OpenGL 3D导航

    通过Tao和C#使用glRotatef,glTranslatef和gluLookAt进行OpenGL 3D导航。

    绘制旋转的正方形(来自opengl编程指南)

    该代码是用来绘制一个旋转的正方形,里面涉及gltranslatef,glrotatef等。

    openGL程序

    glRotatef(yRot,0.0f,1.0f,0.0f); xRot+=0.5f; yRot+=0.5f; glBegin(GL_TRIANGLES); glColor3f(1.0f,0.0f,0.0f); glNormal3f(0.0f,-1.0f,0.0f); glTexCoord2f(0.0f,1.0f); glVertex3fv(vertices[1]...

    计算机图形学制作时钟源代码

    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI, PFD_TYPE_RGBA, 24, 0,0,0,0,0,0, 0, 0, 0, 0,0,0,0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0,0,0 }; this-&gt;m_GLPixelIndex ...

    HumanMotionTrack 全

    我们定义一个OpenGL的类来做模型控制类,负责载入模型, CLoad3DS* m_3ds; int OpenGL::Load3DS(int ID, char *filename) { if(m_3ds!=NULL) m_3ds-&gt;Init(filename,ID); return 0; } 然后在显示时候调用 int ...

    图形学立方体旋转程序

    glRotatef(theta[2], 0.0, 0.0, 1.0); colorcube(); glFlush(); glutSwapBuffers(); } void spinCube() { /* Idle callback, spin cube 2 degrees about selected axis */ theta[axis] += 2.0; if( theta...

    Android自制3D View显示组件源代码(3D Widget)

    部分源代码:   gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW);... gl.glRotatef(mAngle, 0, 1, 0); gl.glRotatef(mAngle*0.25f, 1, 0, 0); gl.

Global site tag (gtag.js) - Google Analytics