The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Micro stuttering while moving SDL_Surfaces
jannik93


Joined: 16 Apr 2014
Posts: 4
Hey guys,

first of all I have to admit, I am very new to C++ and SDL. At work I only work with C# and .NET.

I am trying to figure out, why I experience micro lags when I am moving SDL_Surfaces on my screen. I hope someone can help me find whats going wrong there:

First of all, this is my main function with the draw/logic loop:

Code:
struct Credit {
   SDL_Surface *Text;
   SDL_Rect Src;
   SDL_Rect Dest;
};


void CCredits::Show()
{
   const SDL_Rect screenRect = CFrameworkInst->GetScreen()->clip_rect;
   SDL_Event event;

   CreateCredits();
   ResetPositions(&screenRect);
   
   bool creditsRunning = true;
   while (creditsRunning)
   {
      while (SDL_PollEvent(&event))
      {
         switch (event.type)
         {
         case SDL_KEYDOWN:
            if (event.key.keysym.sym == SDLK_ESCAPE)
            {
               creditsRunning = false;
            }
            break;
         case SDL_QUIT:
            creditsRunning = false;
            break;
         }
      }

      for (int i = 0; i < CREDITLEN; i++)
      {
         if (Credits[i].Dest.y > 0)
         {
            Credits[i].Dest.y -= SPEED;
         }
         else
         {
            Credits[i].Src.y += SPEED;
         }

         if (Credits[i].Dest.y < screenRect.h && Credits[i].Src.y < Credits[i].Src.h)
         {
            CFrameworkInst->Paint(Credits[i].Text, &Credits[i].Src, &Credits[i].Dest);
         }
      }
      if (Credits[CREDITLEN - 1].Src.y > Credits[CREDITLEN - 1].Src.h)
      {
         ResetPositions(&screenRect);
      }
      
      CFrameworkInst->Update();
      CFrameworkInst->Clear();
      CTimerInst->Delay();
   }

   for (int i = 0; i < CREDITLEN; i++)
   {
      SDL_FreeSurface(Credits[i].Text);
   }
}


As you can see, I am trying to do some sort of credit logic, which moves TTF_Render_Solid Surfaces from the buttom to the top of the page.

The paint, clear and update goes here:

Code:
void CFramework::Paint(SDL_Surface *surface, SDL_Rect *src, SDL_Rect *dest)
{
   SDL_BlitSurface(surface, src, windowSurface, dest);
}

void CFramework::Clear()
{
   SDL_FillRect(windowSurface, NULL, 0);
}

void CFramework::Update()
{
   SDL_UpdateWindowSurface(window);
}


Further more, my timer delay looks like this:
Code:
void CTimer::Init(int fps)
{
   m_FPS = 1000/fps;
   m_LastTime = SDL_GetTicks();
}

void CTimer::Delay()
{
   int timeLeftBehind = SDL_GetTicks() - m_LastTime;
   if (timeLeftBehind < m_FPS)
   {
      SDL_Delay(m_FPS-timeLeftBehind);   
   }
   m_LastTime = SDL_GetTicks();
}


As you can see, Framework and Timer are Singletons.

Anyone knows whats going wrong? Feel free to give me suggestions if I did something stupid, I am just getting started with SDL Smile

Thank you in advance!

Jannik
jannik93


Joined: 16 Apr 2014
Posts: 4
Oh, BTW: I am using SDL 2.0.3, just in case that it matters
Nathaniel J Fries


Joined: 30 Mar 2010
Posts: 444
1) Try not limiting FPS.
2) Use the new render API instead of surfaces. Much faster.
jannik93


Joined: 16 Apr 2014
Posts: 4
Hey,

thanks for the answer.

How to do that without a fps limitation? Without a fps limitation it would be sometimes faster, sometimes slower, wouldnt it?

Further more, I dont know the new API, are there tutorials? All I've seen on youtube was using the old SDL_Surface way etc. Some more infos would be great, for example what exactly I have to change etc?
Micro stuttering while moving SDL_Surfaces
Jonny D


Joined: 12 Sep 2009
Posts: 932
There is another consideration here, depending on what you're experiencing.  I would expect that the program is running fine with respect to FPS.


You are storing your sprite position in an SDL_Rect (Credits[i].Dest), which is a struct of integers.  When you apply your SPEED to the position, you will get aliasing to integer positions.  If you want smoother motion, store your positions in floating point (x,y) pairs and use a floating point SPEED.


Similarly, you may not be able to get perfectly smooth motion at all with the built-in SDL rendering functions because they don't directly support subpixel positioning.  I wrote SDL_gpu, which addresses that issue in case you run into it.


Jonny D
jannik93


Joined: 16 Apr 2014
Posts: 4
I figured out some things:

I rewrote my three methods now, I am using SDL_Textures now and SDL_Renderer and it appears to be working like a charm.

But I have another question in my mind: How do I get the clip_rect from the Texture?