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