Невозможно правильно вращать 2D объект с помощью opengl - PullRequest
0 голосов
/ 03 января 2019

Я использую 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;
}

1 Ответ

0 голосов
/ 03 января 2019

Обратите внимание, что рисование с помощью glBegin / glEnd последовательностей и набора матриц фиксированных функций устарело с десятилетий. Прочитайте о конвейере с фиксированными функциями и посмотрите Спецификация вершин и Шейдер , чтобы узнать о современном способе рендеринга.


Я хочу вращать кончик космического корабля, не двигая весь космический корабль [...]

Сначала вы должны определить точку поворота, которая является «вершиной» космического корабля:

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

Чтобы вращаться вокруг оси, вы должны определить матрицу модели, которая смещается на инвертированную точку, затем поворачивается (glRotatef) и окончательно преобразуется обратно в точку (* 1025). *):

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();
...