简体   繁体   中英

OpenGl glm rotate

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"

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM