看板 GameDesign 關於我們 聯絡資訊
在解釋之前,先有個概念: 「物體的旋轉、移動、放大縮小等全部可以用矩陣運算來表示」 也就是物體的座標在乘上某個矩陣後,就可以得到旋轉、移動、放大縮小的結果。 現在我們來看看這幾個操作... ※ 引述《prjryu (橘)》之銘言: : 可否詳述call update_mo時 : void update_mo( float angle, float x, float y, float z ) : { : glPushMatrix(); 把目前 OpenGL 正在使用的 matrix 推進一個 stack 中 OpenGL 內部會去管理這個 stack 所以你只要用 push 就會保留現在的座標轉換方式 可以在稍後用 pop 恢復 : glLoadIdentity(); 把目前的 matrix 設定為 ideneity matrix identity 對應到的座標轉換就是「不做任何轉換」 : glRotatef( angle, x,y,z ); 把目前的 matrix 乘上 rotation matrix 因為在上一行中,目前的 matrix 是 identity 所以這一行實際作用就是讓現在作用中的 matrix 設定為 rotation matrix rotation matrix 對應的座標轉換就是「以某個向量為軸旋轉」 : glMultMatrixf(mo); //這行是做什麼? 把目前的 matrix 乘上 mo 這個 matrix 假設前面的 rotation matrix 叫作 R 那麼目前的 matrix 就是 R*mo R*mo 是什麼意思呢?R 是指旋轉,而 mo 是什麼我們不知道, 但它也是個 matrix,可以進行座標轉換,所以合起來說就是 「先進行旋轉後,再進行 mo 這個座標轉換」 : glGetFloatv( GL_MODELVIEW_MATRIX, mo ); //這行是做什麼? 這行的意思是把目前用的 modelview matrix 存到 mo 裡面 若和上兩行結合起來就是如下的意思: R = RotationMatrix(angle, x, y, z); mo = R * mo; 所以整體的意義就是「mo 儲存了某個座標轉換,在經過這些運算後, mo 除了原本的效果(可能是旋轉平移放大縮小)外,還追加了旋轉的效果」 : glPopMatrix(); 上面的運算會影響到 OpenGL 內部使用的 matrix 為了消除這個副作用 就用 glPopMatrix 把它恢復原狀 : glutPostRedisplay(); : } : 在程式中的運作順序及結果? : 我看來是這樣: : push : ↘ : │glGetFloatv( GL_MODELVIEW_MATRIX, mo ); │ : │glMultMatrixf(mo); │ : │glRotatef( angle, x,y, ); │ : │glLoadIdentity(); │ : └────────────────────┘ : pop(所以執行順序變成) : glGetFloatv( GL_MODELVIEW_MATRIX, mo ); //把現在的矩陣存到mo : glMultMatrixf(mo); //把目前的矩陣乘上mo : glRotatef( angle, x,y, ); //轉角度 : glLoadIdentity(); //回到原來的狀態 : 此處MODELVIEW_MATRIX矩陣和目前的矩陣不一樣的嗎? : 可以一行一行解釋嗎? push 和 pop 並不會影響其後指令的執行順序喔 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 219.87.151.2
Splash5:loadidentity應該也帶有initialize a matrix的意思 05/19 14:03
prjryu:mo[16]={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}; 05/20 22:30
prjryu:非常感謝littleshan大鉅細靡遺的講解,受益良多m(_ _)m 05/20 22:37
prjryu:上面是mo的陣列初始,請問和mo相乘在此處的效果是? 05/21 04:51
littleshan:mo 初始就是 identity matrix,效果為「無效果」 05/21 14:30
Splash5:那個 原po可以手算這兩個矩陣相乘阿XD.. 你就知道為啥叫 05/22 00:37
Splash5:identity matrix (單位矩陣) 果然還是線性代數XD 05/22 00:38