[英]OpenGL translation and rotation in the same time
在我的openGL项目中,我试图实现以下目标:让对象绕其原点旋转(在其自己的世界中为(0,0,0)点)并同时进行转换。 我提出以下结构:
/***
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的调用顺序引起的吗? 有人可以给我些帮助吗?
如@reprodukto所建议,我找到了解决问题的方法。
我使用另外两个标志进行平移和缩放,并在paintGL函数中一起处理这种情况。 通过这种方式,我可以应用“翻译*旋转*缩放”转换的教科书顺序。
谢谢大家花时间评论和回答我的问题,我非常感谢!
您将需要具有一个更新x,y&z值的函数。 您所需要做的就是创建一个保存x,y&z值的数组,然后将其备份到一个临时数组中。 删除旧阵列,然后用新阵列替换。 就是这样。 创建一个名为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;
}
如您所知,开发人员通常会在模型,视图和投影矩阵方面进行思考。 为了清楚起见,最好将它们考虑为:
model_to_world矩阵(将模型放置在游戏世界中)
world_to_camera矩阵(通过在摄像机周围移动整个游戏世界来在您的世界中定位摄像机)
world_to_projection矩阵(采用截头圆锥体的形状并将其压缩为一个立方体,这是opengl用于渲染的立方体,在x,y和z方向上从-1到+1的立方体)
请记住,矩阵可以同时进行平移,缩放和旋转操作,并且可以在将单个矩阵传递到着色器程序之前将模型,视图和投影矩阵相乘一次。
我不确定您在做什么,但我认为更好的解决方案是这样的:
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的东西,或者这不能帮助您解决问题,请发表评论,我将编辑答案以尝试提供帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.