如何在 OpenGL C++ 中旋转旋转轴?

Posted

技术标签:

【中文标题】如何在 OpenGL C++ 中旋转旋转轴?【英文标题】:How to rotate rotation axis in OpenGL C++? 【发布时间】:2016-11-29 02:16:25 【问题描述】:

glm::mat4 模型 = glm::mat4(1.0f);

float dir_x = 0.0f, dir_y = 1.0f, dir_z = 0.0f;

do 

    // Clear the screen

    glClear(GL_COLOR_BUFFER_BIT);

    // Use our shader

    glUseProgram(programID);

    GLuint MatrixID = glGetUniformLocation(programID, "MVP");

    glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);

    //glm::mat4 Projection = glm::ortho(-1.0f,1.0f,-1.0f,1.0f,0.0f,100.0f); // In world coordinates



    // Camera matrix

    glm::mat4 View = glm::lookAt(

        glm::vec3(0.5, 0.5, 3), // Camera is at (4,3,3), in World Space

        glm::vec3(0.5, 0.5, 0), // and looks at the origin

        glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)

    );

    float rot_angle = 0.0f;

    const float speed = 0.01f;





    glm::vec3 dir = glm::vec3(dir_x, dir_y,  dir-z);



    if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)

    

        rot_angle = -1.0f;

        Model = glm::translate(tri_center)* glm::rotate(glm::mat4(), glm::radians(rot_angle), glm::vec3(0, 0, -1))*glm::translate(-tri_center)*Model;

        //dir left

...

如果我旋转对象(汽车),我想将它移动到汽车的头部。现在,不管车头如何,车只向上移动。 代码如何让 dir 旋转?

【问题讨论】:

你能澄清一下你真正想要做什么吗?抱歉,我没有完全从身体上捕捉到它。您打算更改对象的旋转中心吗? 对不起,我英语不好。你的想法是对的。我打算改变对象的旋转中心 我的回答成功了吗?你让它旋转正确吗? 【参考方案1】:

改变旋转中心可以通过以下方式实现:

    记住,矩阵相乘从右到左,第一个变换在最右边,最后一个在左边

    首先,创建一个平移,将旋转中心带到场景的原点 (0, 0, 0),这基本上是反转每个 x、y 和 z。所以示例中心vec3(1.0, 2.3, -5.2)的翻译是glm::mat4 origin = glm::translate(origin, glm::vec3(-1.0, -2.3, 5.2);

    存储这个向量,我们将把它用于网格中的所有点 现在将所需的旋转应用到这个平移矩阵并将它们存储在一个新的 mat4 中,这样做: glm::mat4 final = glm::rotate(..) * origin 最后,通过创建与 vector3 相同的平移,将中心(和模型的其余部分)带回原始位置,如下所示: glm::mat4 relocate = glm::translate(relocate, center) 然后 glm::mat4 final = relocate * glm::rotate(..) * origin 本质上,我们在这里所做的是将模型的中心带到原点,将所有点相对于该原点平移,然后围绕中心(现在是原点)旋转它们,然后将它们带回原来的距离. 现在将此平移应用于所有模型点,显然是在顶点着色器中执行此操作。如果模型真的很小,您可以在代码中执行此操作,但这会占用大多数网格的内存。如果您不想添加另一个矩阵,可以将此 mat4 应用于模型矩阵。 model = model * final //note, first do transformations, then scale for the model

完整代码如下所示:(您也可以手动将矩阵相乘,但 GLM 允许您将矩阵传递给 translate() 函数的参数,然后它只是将转换应用到当前形式的矩阵)

glm::vec3 center = vec3(1.0, 2.3, -5.2); 
glm::mat4 finalTransform = glm::translate(finalTransform, glm::vec3(-1.0, -2.3, 5.2)); //first bring everything to origin, notice this is a mat4 
finalTransform = glm::rotate(finalTransform, ...); //rotate how you want
finalTransform = glm::translate(finalTransform, center); //return to center
model = model * finalTransform; //apply this transformation to be calculated by the vertex shader for the object
glUniformMatrix4fv(glGetUniformLocation(sp, "model"), 1, GL_FALSE, glm::value_ptr(model)); //pass model matrix into shader program 

此外,在您当前的代码中,您的想法似乎是正确的,但您使用的翻译功能不正确。应该这样称呼它:glm::translate(mat4, vec3)。至少,构造一个空的mat4 以使用glm::mat4() 构造函数进行转换。

【讨论】:

以上是关于如何在 OpenGL C++ 中旋转旋转轴?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中使用 sdl、opengl 移动相机时修复奇怪的相机旋转

如何在 OpenGL 中围绕 Z 轴中心旋转对象?

使用 C++ 在 OpenGL 中移动自动旋转的 3d 多边形

在使用 C++ 在 OpenGL 中移动形状时按时间自动旋转形状

如何在openGL中旋转图像?

如何在 OpenGL 中更改旋转中心