首页 > 解决方案 > 无法使用 opengl 正确旋转 2D 对象

问题描述

我正在使用 opengl、glfw 和 glew。当用户分别按下左右箭头时,我想旋转飞船的尖端而不移动整个飞船。我试过使用 gltransform glrotate,它确实会旋转,但它也会移动我的宇宙飞船。空间运动的输出

objects objects::rotateSpaceship(GLFWwindow * window, objects & sp)
{
    GLfloat spaceship_angle = sp.getAngle();

    GLfloat newAngle = sp.getAngle() + 0.5;
    sp.setAngle(newAngle);

    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);

        GLfloat spaceShipRightLine[] =
        {
            x, y + 80, 0,
            x - 50, y - 50, 0
        };


        GLfloat spaceShipLeftLine[] = {
            x, y + 80, 0,
            x + 50, y - 50, 0
        };

        GLfloat spaceShipMiddleLine[] = {
            sp.x - 30 ,sp.y,0,
            sp.x + 35,sp.y,0
        };


        glPushMatrix();

        glTranslatef(0.0, 0.01, 0.0); // 3. Translate to the object's position.

        glRotatef(sp.getAngle(), 0.0, 0.0, 1.0); // 2. Rotate the object.

        glTranslatef(0.0, 0.01, 0.0); // 1. Translate to the origin. 

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, spaceShipRightLine);
        glDrawArrays(GL_LINES, 0, 2);
        glDisableClientState(GL_VERTEX_ARRAY);

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, spaceShipLeftLine);
        glDrawArrays(GL_LINES, 0, 2);
        glDisableClientState(GL_VERTEX_ARRAY);

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, spaceShipMiddleLine);
        glDrawArrays(GL_LINES, 0, 2);
        glDisableClientState(GL_VERTEX_ARRAY);

        glPopMatrix();

        // Swap front and back buffers
        glfwSwapBuffers(window);

        // Poll for and process events
        glfwPollEvents();
    }

    glfwTerminate();
    return sp;
}

标签: c++openglglfw

解决方案


请注意,由glBegin/glEnd序列绘制和固定函数矩阵堆栈自几十年以来已被弃用。阅读Fixed Function Pipeline并查看Vertex Specification and Shader了解最先进的渲染方式。


我想在不移动整个飞船的情况下旋转飞船的尖端 [...]

首先,您必须定义枢轴,即宇宙飞船的“尖端”:

float pivot_x = sp.x;
float pivot_y = sp.y + 80.0f;

要围绕枢轴旋转,您必须定义一个模型矩阵,该矩阵由反转的枢轴置换,然后旋转 ( glRotatef) 并最终转换回枢轴 ( glTranslate):

glTranslatef(pivot_x, pivot_y, 0);
glRotatef(angle, 0, 0, 1);
glTranslatef(-pivot_x, -pivot_y, 0);

最终代码可能如下所示:

float pivot_x = x;
float pivot_y = y + 80.0f;

glPushMatrix();

glTranslatef(pivot_x, pivot_y, 0 );      // 3. Translate to the object's position.
glRotatef(sp.getAngle(), 0.0, 0.0, 1.0); // 2. Rotate the object.
glTranslatef(-pivot_x, -pivot_y, 0.0);   // 1. Translate to the origin. 

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipRightLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipLeftLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipMiddleLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);

glPopMatrix();

推荐阅读