Frames per Second



  • cooky451 schrieb:

    Mauszeiger würde ich entweder das System zeichnen lassen, oder in einem separaten Thread behandeln.

    Und was soll dieser Thread machen?





  • Ein guter Beitrag. (der davor)

    Ich habe versucht das jetzt umzusetzen. Angefangen habe ich beim Problem mit der Maus. Ich habe einen eigenen Mauszeiger erstellt und möchte den, je nach Bewegung, rendern. Mein Bildschirm ist im übrigen auf 60 Hertz eingestellt.

    Wenn ich meinen programmierten Mauszeiger auf 60 Hertz einstelle, dann sieht man wie der Bildschirm nicht hinterherkommt, da die Maus nie ganz gezeichnet wird. Bei 10 FPS kommt der Bildschirm hingegen noch mit und die Grafik wird immer ganz gezeichnet. Der SDL_Renderer wurde mit SDL_RENDERER_PRESENTVSYNC erstellt.

    C++ / SDL2

    main.cpp

    int main(int argc, char* args[])
    {
      SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER | SDL_INIT_AUDIO);
    
      CBuild * pBuild = new CBuild;
      STimeWindow * pTimeWindow = new STimeWindow;
      pTimeWindow->TimeStampA = 0;
      pTimeWindow->TimeStampB = SDL_GetTicks();
      double time_dif = 0.0;
    
      pBuild->init();
    
      if(pBuild->getWindowX() < 1024 || pBuild->getWindowY() < 768)
      {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Niedrige Aufloesung", "Leider ist die Aufloesung zu niedrig.\nDie Aufloesung muss mindestens 1024 x 768\nbetragen.", NULL);
      }
      else
      {
        while(pBuild->getExecuteFlag())
        {
          pBuild->draw();
          pBuild->update(time_dif, pTimeWindow->TimeStampB);
    
          time_dif = (pTimeWindow->TimeStampB - pTimeWindow->TimeStampA);
          time_dif *= 0.001;
          pTimeWindow->TimeStampA = pTimeWindow->TimeStampB;
          pTimeWindow->TimeStampB = SDL_GetTicks();
        }
      }
    
      SDL_Quit();
    
      delete pTimeWindow;
      return 0;
    }
    

    cbuild.cpp

    ///////////////////////////////////////
    ///////////////////////////////////////
    // constructor / destructor
    ///////////////////////////////////////
    ///////////////////////////////////////
    
    CBuild::CBuild():
    execute(1),
    fps(60)
    {
      pWindow = NULL;
      pRenderer = NULL;
      pWndSurf = NULL;
      pCursor = new CCursor();
    }
    
    CBuild::~CBuild()
    {}
    
    ///////////////////////////////////////
    ///////////////////////////////////////
    // private methods
    ///////////////////////////////////////
    ///////////////////////////////////////
    
    void CBuild::init_window()
    {
      SDL_GetCurrentDisplayMode(0, &displaymode);
      pWindow = SDL_CreateWindow
      (
        "Test",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        displaymode.w,
        displaymode.h,
        SDL_WINDOW_SHOWN
      );
      pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_PRESENTVSYNC);
      pWndSurf = SDL_GetWindowSurface(pWindow);
    }
    
    void CBuild::handleEvents()
    {
      while(SDL_PollEvent(&event))
      {
        switch(event.type)
        {
          case SDL_KEYDOWN:
          {
    	this->event_keydown();
          } break;
        };
      }
    }
    
    void CBuild::event_keydown()
    {
      switch(event.key.keysym.sym)
      {
        case SDLK_ESCAPE:
        {
          execute = 0;
        } break;
      };
    }
    
    ///////////////////////////////////////
    ///////////////////////////////////////
    // public methods
    ///////////////////////////////////////
    ///////////////////////////////////////
    
    bool CBuild::getExecuteFlag()
    {
      return execute;
    }
    
    int CBuild::getWindowX()
    {
      return displaymode.w;
    }
    
    int CBuild::getWindowY()
    {
      return displaymode.h;
    }
    
    ///////////////////////////////////////
    ///////////////////////////////////////
    // main methods
    ///////////////////////////////////////
    ///////////////////////////////////////
    
    void CBuild::init()
    {
      this->init_window();
      pCursor->initCursor("graphics/cursor.png", fps, pRenderer);
    }
    
    void CBuild::draw()
    {
      SDL_SetRenderDrawColor(pRenderer, 0x00, 0x00, 0x00, 0xff);
    
      SDL_RenderClear(pRenderer);
      pCursor->drawCursor(pRenderer);
    
      SDL_RenderPresent(pRenderer);
    }
    
    void CBuild::update(double timestep, int timestamp)
    {
      this->handleEvents();	
      pCursor->moveCursor(timestamp);
    }
    

    ccursor.cpp

    ///////////////////////////////////////
    ///////////////////////////////////////
    // constructor / destructor
    ///////////////////////////////////////
    ///////////////////////////////////////
    
    CCursor::CCursor():
    time_move(0),
    time_step(0)
    {
      pPosition = new SDL_Rect;
      pTexture = NULL;
    }
    
    CCursor::~CCursor()
    {}
    
    ///////////////////////////////////////
    ///////////////////////////////////////
    // methods
    ///////////////////////////////////////
    ///////////////////////////////////////
    
    void CCursor::initCursor(char * pFile, int nFPS, SDL_Renderer * pRenderer)
    {
      SDL_Surface * pSurfImage = NULL;
      time_step = 1000 / nFPS;
      SDL_ShowCursor(0);
    
      pSurfImage = IMG_Load(pFile);
      pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurfImage);
      pPosition->w = pSurfImage->w;
      pPosition->h = pSurfImage->h;
      SDL_FreeSurface(pSurfImage);
      SDL_SetTextureBlendMode(pTexture, SDL_BLENDMODE_BLEND);
      SDL_SetTextureAlphaMod(pTexture, 0xff);
    }
    
    void CCursor::moveCursor(int timer)
    {
      if(timer >= time_move)
      {
        SDL_GetMouseState(&pPosition->x, &pPosition->y);
        time_move += time_step;
      }
    }
    
    void CCursor::drawCursor(SDL_Renderer * pRenderer)
    {
      SDL_RenderCopy(pRenderer, pTexture, NULL, pPosition);
    }
    

    Fakt ist, dass er eigentlich 30 FPS in der CCursor Klasse schon nicht mehr hinbekommt. Der Cursor, den ich verwende, kann hier heruntergeladen werden:

    http://www.wp1105995.server-he.de/cursor.png

    Das heißt, ich muss irgendwas grundlegend mit SDL2 falsch machen.



  • Nutze am besten erst mal den Default-Cursor des Systems und mach das später, bis dein Programm ordentlich läuft.



  • Das ist ja aber 1 von 2 Hauptproblemen. Die Maus mit eigenem Cursor.

    Das 2. Hauptproblem ist, dass der Bildschirm bei Animationen ebenfalls nicht hinterherkommt. Das will ich jetzt aber durch die neue Zeitlogik mal testen. Indem ich stoppe wie lange das Programm zum Zeichnen eines Frames braucht. Das war ja vorher nicht so.


  • Mod

    spar dir viel arbeit und installiere dir einen profiler, z.b. AMDs codeanalyst und schau wo die performance verloren geht.

    bei sowas einfachem solltest du auf jeden fall 60fps hinbekommen, selbst auf einem 10jahre alten rechner.



  • Hey,

    Visual Studio 2013 liefert den sogar mit. Ich habe einen CPU Leistungstest gemacht. Der Graf kratz halt kurz über der 0% Hürde. Ich kann daraus auch keine Auffälligkeiten entnehmen.

    Das gleiche Problem habe ich aber auch auf einem anderen Gerät. Ich meine das mit dem nicht hinterherkommen beim Zeichnen, was mich nach wie vor glauben lässt, dass ich irgendwas im Code bezüglich SDL falsch mache.

    Die Anwendung:
    http://www.wp1105995.server-he.de/Beispiel.zip

    Der Leistungsbericht:
    http://www.wp1105995.server-he.de/CPU.zip



  • Lad mal das VS Projekt mit Sourcecode hoch.



  • Ich habe einfach mal den ganzen Projekt Ordner gezippt und hochgeladen. Bin gespannt, wie das bei euch läuft.

    Danke schonmal vorweg.

    http://www.wp1105995.server-he.de/project.zip



  • Ändere mal

    pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_PRESENTVSYNC);
    

    auf

    pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_ACCELERATED);
    

    Macht das einen Unterschied?

    edit:
    Und warum benutzt du nicht http://wiki.libsdl.org/SDL_CreateCursor ?



  • Hey,

    Nein, das macht leider keinen Unterschied. Schon probiert.
    Und SDL_CreateCursor ist nur für schwarz / weiß, wenn ich das richtig verstanden habe. Hatte ich oben auch schon erwähnt.

    "If you want to have color cursor, then this function is not for you; instead, you must hide the normal system cursor (SDL_ShowCursor) and in your main loop, when you draw graphics, also draw a SDL_Surface at the location of the mouse cursor." - SDL Seite

    Mir geht es auch weniger um die Maus, als um die Tatsache, dass der ja auch beim Animieren des Models nicht hinterherkommt. Auf die Maus könnte ich im Ernstfall wirklich verzichten.



  • Ich habe jetzt eine FPS Funktion eingebaut. (Mit F1 an und ausschaltbar) Egal, ob ich meinen Bildschirm auf 60 Hz, oder 75 Hz stelle. Mein Programm passt sich an und ist meist 1 - 2 Frames darunter, sprich entweder 58 Hz, oder 73 Hz. Das Programm achtet also wunderbar darauf wie lange es braucht zum Zeichnen. Dennoch wirkt alles verschwommen.

    Hier nochmal das aktualisierte Projekt zum ausprobieren:

    http://www.wp1105995.server-he.de/project.zip

    1. Hat Jemand noch ne Idee?
    2. Nutzt SDL swap chain?



  • Habs jetzt gelöst.

    SDL kommt mit 0x00 , 0x00, 0x00 als komplette Hintergrundfarbe nicht klar, wenn es um Animationen geht und die Grafiken selbst beispielsweise zu dunkel sind (dunkles grau, und dunkles blau). Habe den Hintergrund ein wenig heller gemacht um 16 schritte circa.

    Zusätzlich noch die Framerate der Maus von 60 auf 50 runtergesetzt und es funktioniert so flüssig.



  • PadMad schrieb:

    SDL kommt mit 0x00 , 0x00, 0x00 als komplette Hintergrundfarbe nicht klar, wenn es um Animationen geht und die Grafiken selbst beispielsweise zu dunkel sind (dunkles grau, und dunkles blau).

    Das glaubst du doch selbst nicht.

    Habe den Hintergrund ein wenig heller gemacht um 16 schritte circa.

    Zusätzlich noch die Framerate der Maus von 60 auf 50 runtergesetzt und es funktioniert so flüssig.

    lol



  • Man glaubt prinzipiell das was man sieht und ausprobiert hat 🙄
    Kannst es ja vielleicht erst mal selbst ausprobieren...

    Manche Farbkombinationen werden von Bildschirmen einfach nicht schnell genug oder unsauber gezeichnet. Zumindest in SDL.

    Aber du hast ne andere Lösung?



  • PadMad schrieb:

    Man glaubt prinzipiell das was man sieht und ausprobiert hat 🙄

    Ach wirklich, du hast gesehen dass es an der SDL liegt? Echt jetzt?

    Kannst es ja vielleicht erst mal selbst ausprobieren...

    Brauch ich nicht, da ich im Gegensatz zu dir weiss was der Grund ist.

    Manche Farbkombinationen werden von Bildschirmen einfach nicht schnell genug oder unsauber gezeichnet. Zumindest in SDL.

    Ja, vom Bildschrim. Was bitte hat das mit der SDL zu tun?

    Aber du hast ne andere Lösung?

    Ja, häng nen anderen Bildschirm an.



  • lol



  • Lach sovieo du willst, ändert trotzdem nix daran dass es am Bildschirm legt.


Anmelden zum Antworten