zeitschwankungen -> unflüssige bewegung



  • äh ja....

    ob ich nun die zeit warte oder mit dem zeitfaktor multipliziere, wenn die Zeitwerte so unregelmäßig sind, habe ich trotzdem keine flüssige Bewegung.



  • doch! du multiplizierst ja mit einem Δt - damit hast eine gleichmäßige bewegung bei ungleichmäßigen zeitabständen - muss ich ein tutorial darüber schreiben? 😉



  • Hallo,

    wenn ich mit dem Zeitfaktor multipliziere, bekomme ich genau denselben Effekt.

    Ich poste mal den ganzen Code und fände es nett, wenn der ein oder andere ihn mal ausprobieren könnte (benötigt SDL und OpenGL) und mir sagt, wie es bei ihm aussieht.

    Ich habe festgestellt, wenn ich in die Hauptschleife ein SDL_Delay(1) einbaue, sieht die Bewegung wesentlich geschmeidiger aus (in dem Fall, bekomme ich in meinem ersten Beispiel auch einen konstanten Intervall von genau 40ms).

    Nun habe ich aber gerade mal das Problem im IRC geschildert und die Resonanz war, dass es für die anderen keinen Unterschied macht, ob da ein SDL_Delay drin ist, oder nicht.

    #include <SDL.h>
    #include <stdbool.h>
    #include <stdlib.h>
    
    #include <GL/gl.h>
    #include <GL/glu.h>
    
    /* window */
    
    static SDL_Surface* screen = 0;
    
    static
    void setup_opengl(int width, int height)
    {
       /* Enable smooth shading */
       glShadeModel(GL_SMOOTH);
       /* Set the background black */
       glClearColor(0, 0, 0, 0);
       /* Depth buffer setup */
       glClearDepth(1);
       /* Enables Depth Testing */
       glEnable(GL_DEPTH_TEST);
       /* The Type Of Depth Test To Do */
       glDepthFunc(GL_LEQUAL);
       /* Really Nice Perspective Calculations */
       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    
       /* Setup our viewport. */
       glViewport(0, 0, width, height);
       /* change to the projection matrix and set our viewing volume. */
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       /* Set our perspective */
       gluPerspective(45.0, (float)width/(float)height, 0.1, 100.0);
       /* Make sure we're chaning the model view and not the projection */
       glMatrixMode(GL_MODELVIEW);
       /* Reset The View */
       glLoadIdentity();
    }
    
    bool open_window(int xres, int yres,
                     int depth, bool fullscreen, char* title)
    {
        if(SDL_Init(SDL_INIT_VIDEO) == -1)
            return false;
    
        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    
        Uint32 flags = SDL_OPENGL;
        if(fullscreen)
            flags |= SDL_FULLSCREEN;
        if(!(screen = SDL_SetVideoMode(xres, yres, depth, flags)))
            return false;
    
        setup_opengl(xres, yres);
    
        if(title)
            SDL_WM_SetCaption(title, title);
        return true;
    }
    
    void close_window(void)
    {
        SDL_Quit();
    }
    
    bool process_events(void)
    {
        SDL_Event e;
        SDL_PumpEvents();
        return SDL_PeepEvents(&e, 1, SDL_GETEVENT,
                              SDL_EVENTMASK(SDL_QUIT)) == 0;
    }
    
    /* keyboard */
    
    static Uint8* keys;
    
    void update_keystate(void)
    {
        keys = SDL_GetKeyState(0);
    }
    
    bool keydown(int key)
    {
        return keys[key];
    }
    
    /* --------------------------- */
    
    void draw_screen(void)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        glTranslatef(0, 0, -6.0);
    
        glColor3f(0, 0, 1);
    
        static float angle = 0;
    
        static int last = 0;
        int now = SDL_GetTicks();
        float dt = (now - last) * 0.001;
        last = now;
        angle += 100 * dt;
    
        glRotatef(angle, 0, 0, 1);
    
        glBegin(GL_QUADS);
        glVertex2f(-1.0,  1.0);
        glVertex2f( 1.0,  1.0);
        glVertex2f( 1.0, -1.0);
        glVertex2f(-1.0, -1.0);
        glEnd();
    
        SDL_GL_SwapBuffers();
    }
    
    int main()
    {
        open_window(640, 480, 0, 0, 0);
    
        while(process_events()) {
            update_keystate();
            if(keydown(SDLK_ESCAPE)) break;
    
            draw_screen();
        }
    
        close_window();
    }
    

    Wichtig ist eigentlich nur die draw_screen()-Funktion und evtl. die OpenGl-Initialisierung.



  • hab mir deinen code nicht angesehen - so mach ich es - vielleicht hilfts (ich glaube es liegt an irgendetwas sdl spezifischen)

    // Geschwindigkeit = Weg/Zeit
    // -> Weg = Geschwindigkeit*Zeit
    
    float delta_Zeit = Time.get_time();
    Time.reset();
    float delta_weg = 0;
    
    if(delta_Zeit == 0)
    	delta_weg = 0;
    else
    	delta_weg = 2.0f/400.0f*delta_Zeit;
    
    i=i+delta_weg;
    
    Torus.SetRotationX(i);
    Torus.SetRotationY(i);
    Torus.SetRotationZ(i);
    
    if(i >= 360)
    {
    	i=i-360;
    }
    


  • Vertexwahn schrieb:

    hab mir deinen code nicht angesehen

    hättest du mal machen sollen, oder wenigstens was ich dazu geschrieben habe 😉

    btw. x * 0 = 0. Dein if ist überflüssig.



  • DrGreenthumb schrieb:

    Wie kommt das zustande und wie bekomme ich hier einen konstanten Intervall?

    Evtl. Fehler in der Zeitmessung und du hast schon einen konstanten Intervall. Ansonsten VSync an.

    Bye, TGGC (Keine Macht den Dummen)



  • Mit VSync an, geht die Performance total in den Keller.

    Ich glaube, ich lasse das SDL_Delay(1) drin. Ist auch ganz schön wenn der Prozess nicht auf 100% geht.

    Meine Framerate geht da von 3000 auf 1000 runter, kann das auf langsameren Rechnern schlimmere Auswirkungen haben?



  • DrGreenthumb schrieb:

    Mit VSync an, geht die Performance total in den Keller.

    Unsinn.

    Bye, TGGC (Keine Macht den Dummen)



  • TGGC schrieb:

    DrGreenthumb schrieb:

    Mit VSync an, geht die Performance total in den Keller.

    Unsinn.

    aha, dann war das wohl nicht VSync was ich da aktiviert habe. Das Häkchen hieß »Sync to VBlank« und war das einzige was ich in dem Zusammenhang gefunden habe.



  • nur der vollständigkeithalber: Es war ein Treiberproblem.


Anmelden zum Antworten