2016-09-24 43 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,或者这不能帮助你解决问题,请发表评论,我会编辑我的答案以尝试提供帮助。