0
votes

I use

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

to get rotation around the axis over time. But why does the rotation happen evenly and not increase with the timer (first 1 s, then 43, and therefore 43 degrees?) After all, the timer does not reset, but grows, but image rotation goes as if at the same "speed"

2
The angle argument for glm::rotate has to be set in radians. - Rabbid76
@Rabbid76 if you add glm :: radians () then the same thing happens, the speed is just slower, but it does not increase with time. I do not want to say that this is a mistake, I just wonder why this happens - Alpharius
The behavior is not reproducible. There is a bug in your application. Possibly your frame rate is to low. - Rabbid76
@Rabbid76 maybe I didn’t explain it well, but it always turns out like this ravesli.com/wp-content/uploads/2020/04/39.gif I just think, why if, for example, 70 seconds have passed, then the rotation, too, and not 70 degrees - Alpharius

2 Answers

1
votes

But why does the rotation happen evenly and not increase with the timer

Because you're starting the the transform from "zero" (identity) each time through.

If you want to rotate faster & faster with time you need to accumulate the angle:

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

All together, comparing both approaches:

// 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
votes

Welcome to Stack Overflow! :)

I assume that you apply your transformation matrix just like one would apply a model matrix. In that case, your rotation is applied to your object during rendering only once. This results in an even or linear rotation, since time increases linearly.

So the result is just rotations_per_second * static_cast<float>(glfwGetTime()).

If you want to increase the rotation of your object by said amount, you have to multiply both rotation matrices together.

Or you could reduce overhead and define an angular acceleration angular_velocity_per_second and multiply it by your time twice to get the angle of rotation.