Micro stuttering while moving SDL_Surfaces

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 :slight_smile:

Thank you in advance!

Jannik

  1. Try not limiting FPS.
  2. Use the new render API instead of surfaces. Much faster.------------------------
    Nate Fries

Oh, BTW: I am using SDL 2.0.3, just in case that it matters

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?

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

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?