2013年12月9日 星期一

[openGL] glPushMatrix() 和 glPopMatrix()

首先,先說明一下,網路上查關於 openGL 的內容,常常會提到 CM,CM 是 Current Matrix 的簡寫,也就是目前 matrix 內的內容。

要了解的話,可以先從最下面「 [三] 例子」,開始看。

[一] glPushMatrix()

    1. 功能: 將 CM push 到 stack 中,而依不同的機器 stack 可以存放 matrix 的數量有所不同

    2. 目的: 為了各種原因,保存目前的 CM,等待之後再進行使用 (下面有原因的例子)

[二] glPopMatrix()

    1. 功能: pop 出 stack 中的 matrix,並且把現在的 CM 取代掉

    2. 目的: 一樣也是為了各種原因,把之前儲存在 stack 中的 matrix,讀回來繼續使用

[三] 例子

    1.

    glTranslated(0, 10, 0);
    ... draw A ...
    glPushMatrix();
    glRotatef(90, 0, 1, 0);
    ... draw B ...
    glPopMatrix();
    ... draw C ...

    : A 、 B、C 三個都會平行 y 軸移動 10 單位,只是 B 還會繞 y 軸旋轉 90 度

    : 在畫完 A 之後,CM 中保存著往 y 方向移動 10 的內容,之後 glPushMatrix() 把這
      個 CM 存進 stack 中,而第四行再把目前的 CM 旋轉 90 度,在畫完 B 之後,
      glPopMatrix() 把 stack 中向 y 方向移動 10 的內容讀取出來把目前有移動又有旋轉的
      CM 取代掉,因此 C 就只有移動了

    2.

    glTranslated(0, 10, 0);
    ... draw A ...
    glPushMatrix();
    glLoadIdentity();
    glRotatef(90, 0, 1, 0);
    ... draw B ...
    glPopMatrix();
    ... draw C ...

    : A、C 三個都會平行 y 軸移動 10 單位,B 只會繞 y 軸旋轉 90 度

    : 跟上面例子不同之處,在於 glPushMatrix() 之後,有多做一個 glLoadIdentity() 的動作,
     因為目前的 CM 就變回最剛開始的單位矩陣,什麼動作都沒有做,因此,
     B 就只有對 y 軸旋轉 90 度,之後把之前的 matrix pop回來,則現在的 CM 就有了
     移動的內容,而他對 C 做運算之後,C也有了移動的

    [總結]

    有時候可能需要把目前移動、旋轉等等的資訊記錄起來,把其他運算做完之後,

    再把原本存起來的資訊讀回來繼續使用,這時候就可以使用 glPushMatrix()、glPopMatrix(),

    (例如最近在做的小小賽車遊戲,因為是讀取 .obj 檔來使用,所以每一個模型面向的方向、
     位置等等都要再重新做設定,但是除了每一個模型自己旋轉移動到正確的位置外,
     也要能夠跟著其他模型大家一起旋轉,就非常需要這種功能)

沒有留言:

張貼留言