opengl里面的平移,旋转,缩放都是基于矩阵的运算,我们可以很方便地通过设定参数的方式调用一些接口函数来实现,同时我们也可以通过自定义的矩阵来实现上述的基本变换。

首先来看一个渲染程序。

GLfloat rtri;                         GLfloat posX; GLfloat posY; GLfloat scale=0.5f; 
void renderGL() {     // Clear the color and depth buffers.      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );     // We don't want to modify the projection matrix. */     glMatrixMode( GL_MODELVIEW );     glLoadIdentity( );     glTranslatef(posX,0.0f,-6.0f);       glRotatef(rtri,0.0f,1.0f,0.0f);                    glScalef(scale,scale,scale);     glBegin(GL_TRIANGLES);                           glColor3f(1.0f,0.0f,0.0f);                     glVertex3f( 0.0f, 1.0f, 0.0f);                   glColor3f(0.0f,1.0f,0.0f);                     glVertex3f(-1.0f,-1.0f, 0.0f);                   glColor3f(0.0f,0.0f,1.0f);                     glVertex3f( 1.0f,-1.0f, 0.0f);               glEnd();                             if(posX<3.0f) posX+=0.001f;     else posX=-3.0f;     if(scale<2.0f) scale+=0.0005f;     else scale=0.5f;     rtri+=0.2f;                                                                                                                        SDL_GL_SwapBuffers( ); }

程序很简单,运行的结果就是一个不断旋转+缩放+平移的三角形。




所谓的变换就是于矩阵相乘,下面来看看不同的变换所对应的是什么样的矩阵。

平移变换:

P=[

1,0,0,0,

0,1,0,0,

0,0,1,0,

posX,posY,posZ,1

]

旋转变换(以Y轴为例,a为旋转角度)

Y=[

cos(a),0,-sin(a),0,

0,1,0,0,

sin(a),0,cos(a),0,

0,0,0,1

]

比例变换

S=[

qx,0,0,0,

0,qy,0,0,

0,0,qz,0,

0,0,0,1

]

对于矩阵运算不了解的可以参考《计算机图形》或者DirectX的龙书。

在OpenGL中关于使用自定义矩阵的函数有两个glLoadMatrixf(m)和glMultMatrixf(m).

前者是加载一个矩阵,后者则是将m与当前矩阵相乘。

下面是使用自定义矩阵的程序。

void renderGL() {     GLfloat moveMatrix[]=     {1.0f, 0.0f, 0.0f,0.0f,                0.0f,1.0f, 0.0f, 0.0f,               0.0f, 0.0f, 1.0f, 0.0f,              posX, 0.0f, -6.0f, 1.0f};      GLfloat scaleMatrix[]=     {     scale, 0.0f, 0.0f,0.0f,                0.0f,scale, 0.0f, 0.0f,               0.0f, 0.0f, scale, 0.0f,              0.0, 0.0f, 0.0f, 1.0f      };      GLfloat rotateYMatrix[]=     {     cos(rtri),0.0f,-sin(rtri),0.0f,     0.0f,1.0f,0.0f,0.0f,     sin(rtri),0.0f,cos(rtri),0.0f,     0.0f,0.0f,0.0f,1.0f     };      // Clear the color and depth buffers.      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );     // We don't want to modify the projection matrix. */     glMatrixMode( GL_MODELVIEW );     glLoadIdentity();     glMultMatrixf(moveMatrix);      glMultMatrixf(scaleMatrix);      glMultMatrixf(rotateYMatrix);      glBegin(GL_TRIANGLES);                           glColor3f(1.0f,0.0f,0.0f);                     glVertex3f( 0.0f, 1.0f, 0.0f);                   glColor3f(0.0f,1.0f,0.0f);                     glVertex3f(-1.0f,-1.0f, 0.0f);                   glColor3f(0.0f,0.0f,1.0f);                     glVertex3f( 1.0f,-1.0f, 0.0f);               glEnd();                             if(posX<3.0f) posX+=0.001f;     else posX=-3.0f;     if(scale<2.0f) scale+=0.0005f;     else scale=0.5f;     rtri+=0.002f;                                                                                                    SDL_GL_SwapBuffers( ); }

得到的效果和前面的程序完全相同。