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( );
}
得到的效果和前面的程序完全相同。