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