OpenGL的平移和旋转在同一时间
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调用顺序造成的吗?有人能帮帮我吗?
根据建议by@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的东西,或者如果这不能帮助你解决你的问题,请评论,我会编辑我的答案来尝试帮助。
- 按时间自动旋转形状,同时在 OpenGL 中使用C++移动它们
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 图问题:找出两个节点是否在每个节点的O(1)时间和O(2)存储中共享同一分支
- 同一程序的运行时间差异很大,有时达到1000+us
- 对于同一任务,线程的等待时间在 0 到 30000 微秒之间系统地切换
- 相机的旋转方向在一段时间后反转
- 我如何仅使用一个Arduino uno才能在同一时间和同一方向上旋转两个步进电动机
- 为什么同一次执行的时间不同
- 在同一列表的while循环中迭代for循环所需的Big-O时间
- C++ 如何保持炮塔与油箱在同一轴上旋转?(2D坦克指挥官游戏)
- 制作旋转器的功能,每天每分钟创建一个时间戳
- 在给定时间内插值欧拉角/旋转矩阵
- 同一类型的多个声明是否会影响编译时间
- 我可以读取两个值的选项在同一时间使用popt库
- OpenGL的平移和旋转在同一时间
- 如何在同一时间弹出2堆栈
- 不违反标准的近恒定时间旋转
- 基于时间的旋转
- c++游戏-循环和按键在同一时间
- 在不占用CPU时间的非阻塞应用程序中旋转