2016-09-24 68 views
0

在我的openGL項目中,我試圖實現以下目標:讓對象圍繞其原點(在其自己的世界中的(0,0,0)點)旋轉,並同時將其翻譯。我拿出follwing結構:OpenGL在同一時間翻譯和旋轉

/*** 
Install shader and upload data to openGL, initialize and stuffs... 
***/ 
// transfomration matrix is a global variable 
// note the transformation matrix eventually will be right multiplied 
// by the vertex data in the vertex shader 
void keyboard(){ 
// Inside this function I capture the keyboard input. 
// if rotation key is captured, set the rotation flag 
// if translation or scaling key is captured, modify the matrix like this 
    transformation = glm::translate() * transformation; 
} 
void paintGL(){ 
// Inside this function I check if the rotation flag is up and modify the 
// model to wolrd transformation matrix. I choose to modify the transform 
// matrix here because I can take use of the main loop to let my object 
// continuously rotate unless the flag is off. 
    if(rotation flag is set) 
     transformation = transformation * glm::rotate() * inverse(transformation) 
} 
int main(){ 
    glutInit(); 
    glutDisplayFunc(paintGL); 
    glutKeyboardFunc(keyboard); 
    glutMainLoop(); 
} 

現在我的問題是,當我只旋轉或只能翻譯或規模,計劃按預期工作。但是,如果我翻譯對象然後按下旋轉,對象將返回到其初始位置,然後旋轉。或者它消失了!

我知道順序很重要,但在我看來,只要我應用逆矩陣,對象應該回到原來的世界,圍繞原點旋轉,然後我可以將其翻譯回來。我的問題是由鍵盤和paintGL的調用序列引起的嗎?有人能給我一些幫助嗎?

+0

在'paintGL'中,你不應該首先逆變換,然後旋轉,然後變換回來嗎? –

+0

@reproduktor是的,這就是我所做的,就像上面寫的那樣。 –

+0

對不起,我的錯誤,我認爲OpenGL以另一種順序應用矩陣。無論如何,如果您在'keyboard'函數中更改翻譯,則您將處理可能已經包含旋轉的變換。嘗試單獨維護轉換轉換,然後在'paintGL'中編寫轉換和旋轉。 –

回答

0

您需要有一個函數來更新x,y值爲& z值。所有你需要的是創建一個數組來保存你的x,y值,然後你需要將它備份到一個臨時數組中。刪除舊的陣列並用新的陣列替換它。就像這樣。創建一個名爲POINT的新變量,用於保存在翻譯對象時要使用的x,y,z值。

typedef struct 
{ 
     GLfloat xyz[3]; 

}POINT; 

void update(GLfloat x, GLfloat y, GLfloat z) 
{ 
     POINT *point; 
     POINT new_point; 
     new_point.xyz[0] = x; 
     new_point.xyz[1] = y; 
     new_point.xyz[2] = z; 
     long my_points; 
     if(my_points>0) 
     point = new POINT[my_points+1]; 
     else{ 
      POINT *temp = new POINT[my_points+1]; 
     for(long i=0;i<my_points;i++) 
         temp[i] = point[i]; 
       delete [] point; 
       point = NULL; 
      //Ok here you allocate new memory 
      point = new POINT[my_points+2]; 
       for(long i=0;i<my_points;i++) 
        point[i] = temp[i]; 
       delete [] temp; 
       temp = NULL; 
     } 
     point[my_points] = new_point; 

} 
+0

我實際上使用了新的openGL,其中頂點信息首先上傳到頂點着色器。而目前我不想通過改變物體來進行變形。 –

+0

確定這只是一個想法,其實我是新手 –

+0

謝謝反正哈哈 –

1

正如@ reprodukto所建議的,我找到了解決我的問題的方法。

我使用另外兩個標誌進行平移和縮放,並在paintGL函數內處理所有情況。這樣我就可以應用翻譯*旋轉*縮放轉換的教科書順序。

謝謝大家花時間評論和回答我的問題,我真的很感激!

0

正如我確信您已閱讀過,開發人員通常會根據模型,視圖和投影矩陣進行思考。只是爲了把事情說清楚,最好是將它們看作:

model_to_world矩陣(放置你的模型在遊戲世界)

world_to_camera矩陣(通過移動整個遊戲世界坐落在你的世界相機相機)

world_to_projection矩陣(這需要一個平截頭體的形狀,並將其擠壓成一個立方體,這是opengl用於渲染的立方體,在x,y和z方向上從-1到+1的立方體)

請記住,矩陣可以一次完成平移,縮放和旋轉,而您c在將單個矩陣傳遞到着色器程序之前,將模型,視圖和投影矩陣乘以一次。

我不知道你在做什麼,但我認爲一個更好的解決辦法是這樣的:

glm::mat4 originTransform; // this will initialize a matrix which represents no translation, scaling, or rotation, which will be useful later. 
glm::mat4 localMatrix; // your "model" matrix 

localMatrix = glm::translate(originTransform, glm::vec3(2.3f, 0.5f, -1.0f)); // I put in random values to translate by. 

// 2nd translation: 
localMatrix = glm::translate(localMatrix, glm::vec3(5.3f, 2.5f, -10.0f)); // Note that I'm inputting the localMatrix now and not the originTransform, otherwise everything that was done to this matrix before would be made irrelevant. 

localMatrix = glm::rotate(localMatrix, 90.0f, glm::vec3(1.0f, 0.0f, 0.0f)); // a 90 degree rotation on the x axis. Again, note that this is done on the localMatrix and not the originTransform. 

對於視圖和投影矩陣,請參閱教程在網上。

如果你想製作2D而不是3D,或者這不能幫助你解決問題,請發表評論,我會編輯我的答案以嘗試提供幫助。