OpenGL 程式設計/現代 OpenGL 教程導航
外觀
- glutKeyboardFunc
- glutSpecialFunc
- glutSpecialUpFunc
- glutGetModifiers() == GLUT_ACTIVE_SHIFT 或 GLUT_ACTIVE_CTRL 或 GLUT_ACTIVE_ALT
注意:當按下鍵並保持按住時,GLUT 的 special() 回撥函式會反覆呼叫。
有幾種方法可以定位 (X,Y,Z) 軸三元組。

- Z 軸向上 : 在 Blender 中使用,這意味著 (X,Y) 是地面,而 Z 是海拔高度
- Y 軸向上 : 在 OpenGL 中使用,這意味著 (X,Y) 像一面牆,所以 Y 是海拔高度,而 Z 是距離該牆更近或更遠
- 右手系 / 左手系 : OpenGL 和 Blender 使用右手座標系,這意味著你可以用右手來表示它,拇指指向 X 軸,食指指向 Y 軸,中指指向 Z 軸。左手座標系(如 DirectX 使用)可以用左手類似地表示。
在 OpenGL 中使用 Blender 的 Z 軸向上座標系可能很誘人,但會導致問題
- .obj 檔案通常是 Y 軸向上,在載入它們時需要更改(或在從 Blender 匯出它們時)
- 相機是 Y 軸向上,因此如果你使用 Z 軸向上座標系,預設情況下相機位於 (0,0,0) 處,並且它面向下方。當旋轉相機時,這會非常令人困惑,因為例如,如果你的相機正在注視地平線朝向 Y 軸,並且你在 Z 軸上旋轉以向左或向右看,你實際上是在 Y 軸上旋轉檢視(橫滾)。當變換相機時,你必須想象你是從腳上拍攝影片。
- 其他引擎,如 Irrlicht 和 Ogre,也使用 Y 軸向上
因此,我們將在本書中堅持使用 Y 軸向上。
OpenGL 中沒有內建的相機概念。我們必須略作欺騙才能實現它。
我們的技術如下:與其思考如何在固定世界中移動相機,不如思考如何在相機周圍移動整個世界。
例如,在 X 軸上移動相機 3 個單位與在 X 軸上移動整個世界 -3 個單位相同。對所有其他軸和旋轉也是如此。
在使用相機時請牢記這一點。最終結果會感覺非常直觀,但如果你在使用相機時忘記了我們最初的欺騙行為,你將得到錯誤的變換。
我們將從一個直觀的實現開始
- 左右旋轉相機 Y 軸
- 上下移動前後
- Page Up/Page Down 旋轉相機 X 軸
/* code here */
為了向前/向後移動,我們使用 glm::translate。有兩種形式
glm::translate(transformation_matrix, glm::vec3(dx, dy, dz)): 應用transformation_matrix,然後在新座標系中移動 (dx,dy,dz)glm::translate(glm::mat4(1), glm::vec3(dx, dy, dz)) * transformation_matrix: 應用transformation_matrix,然後在舊座標系中移動 (dx,dy,dz)(即移動之前的座標系)- 在相機平移的情況下,不要忘記我們正在欺騙並移動整個世界,而不是相機;因此,上述含義對於 world2camera 矩陣是相反的。
例如,如果你的現有 transformation_matrix 將你的相機向右旋轉 90°,然後沿 Z 軸平移
- 使用第一種形式,你將平移相機的新左側(沿世界 Z 軸),
- 而使用第二種形式,你將平移相機向前(沿世界 X 軸)。
這種實現存在可用性問題:當相機彎曲時左右旋轉相機時,我們不習慣在這個彎曲的軸上旋轉我們的整個身體。相反,我們習慣於在世界直線 Y 軸上旋轉頭部。因此,我們需要將世界 Y 軸平移到相機的區域性座標
glm::vec3 y_axis_world = glm::mat3(transforms[MODE_CAMERA]) * glm::vec3(0.0, 1.0, 0.0);
transforms[MODE_CAMERA] = glm::rotate(glm::mat4(1.0), -delta_rotY, y_axis_world) * transforms[MODE_CAMERA];
最後,讓我們實現側移
/* code here */
瀏覽和下載 完整程式碼 