OpenGl glm повернуть - PullRequest
0 голосов
/ 12 июля 2020

Я использую

glm::mat4 transform(1.0f);
transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));

, чтобы получить вращение вокруг оси с течением времени. Но почему поворот происходит равномерно и не увеличивается с таймером (сначала 1 с, потом 43, а значит 43 градуса?) Ведь таймер не сбрасывается, а растет, а поворот изображения идет как бы с той же "скоростью" "

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Но почему вращение происходит равномерно и не увеличивается с таймером

Потому что вы каждый раз запускаете преобразование с «нуля» (идентичность).

Если вы хотите вращаться быстрее и быстрее со временем, вам нужно накопить угол:

float angle = 0.0f;
while( shouldDraw() )
{
    ...
    angle += static_cast< float >( glfwGetTime() );
    glm::mat4 transform(1.0f);
    transform = glm::rotate(transform, angle, glm::vec3(0.0f, 0.0f, 1.0f));
    ...
}

Все вместе, сравнивая оба подхода:

// g++ main.cpp `pkg-config --cflags --libs glfw3 gl`
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

void DrawTriangle()
{
    glBegin( GL_TRIANGLES );
    glColor3ub( 255, 0, 0 );
    glVertex2f(  0,  1 );
    glColor3ub( 0, 255, 0 );
    glVertex2f( -1, -1 );
    glColor3ub( 0, 0, 255 );
    glVertex2f(  1, -1 );
    glEnd();
}

int main( int, char** )
{
    glfwInit();
    GLFWwindow* window = glfwCreateWindow( 600, 600, "GLFW", NULL, NULL );
    glfwMakeContextCurrent( window );

    float angle2 = 0.0f;
    while( !glfwWindowShouldClose( window ) )
    {
        glfwPollEvents();
        int w, h;
        glfwGetFramebufferSize( window, &w, &h );
        glViewport( 0, 0, w, h );

        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        glOrtho( -5, 5, -5, 5, -1, 1 );
        
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
        
        const float time = static_cast< float >( glfwGetTime() );
        
        float angle1 = time;
        angle2 += time;

        glPushMatrix();
        {
            glTranslatef( 2.5f, 2.5f, 0.0f );
            
            glm::mat4 transform(1.0f);
            transform = glm::rotate(transform, angle1, glm::vec3(0.0f, 0.0f, 1.0f));
            glMultMatrixf( glm::value_ptr( transform ) );
            DrawTriangle();
        }
        glPopMatrix();

        glPushMatrix();
        {
            glTranslatef( -2.5f, -2.5f, 0.0f );
            
            glm::mat4 transform(1.0f);
            transform = glm::rotate(transform, angle2, glm::vec3(0.0f, 0.0f, 1.0f));
            glMultMatrixf( glm::value_ptr( transform ) );
            DrawTriangle();
        }
        glPopMatrix();
        

        glfwSwapBuffers( window );
    }

    glfwTerminate();
}
0 голосов
/ 13 июля 2020

Добро пожаловать в Stack Overflow! :)

Я предполагаю, что вы применяете свою матрицу transformation точно так же, как применяли бы матрицу модели. В этом случае ваше вращение применяется к вашему объекту во время рендеринга только один раз . Это приводит к равномерному или линейному вращению, так как время увеличивается линейно.

Таким образом, результат равен rotations_per_second * static_cast<float>(glfwGetTime()).

Если вы хотите увеличить вращение вашего объекта на указанную величину, вы должны умножить обе матрицы вращения вместе.

Или вы можете уменьшить накладные расходы и определить angular ускорение angular_velocity_per_second и умножить его на ваше время дважды , чтобы получить угол поворота.

...