Zu hohe Prozessorlast bei SDL-Programm

daddz

Mitglied
Hiho!

Also...ich hab mal damit angefangen ein kleines Programm zu schreiben mithilfe von SDL. Bis jetzt funktioniert alles super! Es wird ein Bild geladen, das man hin- und herbewegen kann! Doch wenn das Programm läuft frisst es die ganzen System-Ressourcen...der Prozessor ist zu 100% ausgelastet (3000+) ...was kann ich dagegen machen? Es kann doch nicht sein das so ein simples Programm derartig viel Prozessorlast erzeugt!? :eek:
Ich hoffe ihr könnt mir weiterhelfen! ;-]

greetz
daddz
 
Ich hab sowas mit OpenGl geschafft das ich sogar min 4000 K hab und nun öffnet der Mist nichtmal mehr! Nichtmal wenn ichs auf den ehemaligen Code zurücksetze^^
 
Die Auslastung ist ständig...ab Start des Programms! Es ist bestimmt in der while-Schleife die permanent läuft und Tastatur-Eingaben abfängt! Ich zeig euch mal meinen Quellcode:
Code:
#include <stdlib.h>
#include <SDL/SDL.h>

int main(int argc, char *argv[])
{
    SDL_Surface *screen, *image;
	SDL_Rect dst, dstblue;
    SDL_Event event;
	Uint8 *keys;
	int tuxX = 50, tuxY = 50;
    bool done = false;
    if(SDL_Init(SDL_INIT_VIDEO) == -1)
    {
        printf("Can't init SDL:  %s\n", SDL_GetError());
        exit(1);
    }
    atexit(SDL_Quit); 
    screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 255));
    if(screen == NULL)
    {
        printf("Can't set video mode: %s\n", SDL_GetError());
        exit(1);
    }
    image = SDL_LoadBMP("tux.bmp");
    if(image == NULL)
    {
        printf("Can't load image of tux: %s\n", SDL_GetError());
        exit(1);
    }	
	dst.w = image->w;
	dst.h = image->h;
	dstblue.w = image->w + 1;
	dstblue.h = image->h + 1;
    SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 255, 0, 255));    
    while(!done)
    {
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT:
                done = true;
                break;
            }
        }
		keys = SDL_GetKeyState(NULL);
		if(keys[SDLK_UP])
		{
			if(tuxY > 10)
				tuxY--;
		}
		if(keys[SDLK_DOWN])
		{
			if(tuxY < 470 - image->h)
				tuxY++;
		}
		if(keys[SDLK_RIGHT])
		{
			if(tuxX < 630 - image->w)
				tuxX++;
		}
		if(keys[SDLK_LEFT])
		{
			if(tuxX > 10)
				tuxX--;
		}
		dst.x = tuxX;
		dst.y = tuxY;
		dstblue.x = tuxX - 1;
		dstblue.y = tuxY - 1;
		SDL_FillRect(screen, &dstblue, SDL_MapRGB(screen->format, 0, 0, 255));
		SDL_BlitSurface(image, NULL, screen, &dst);
		SDL_Flip(screen);
    }
    SDL_FreeSurface(image);
    return 0;
}
Das ist jetz der Code von einem Tutorial aber im Prinzip der gleiche den ich hab! (bin grad nich an meinem PC)
Wie gesagt liegt es bestimmt an der While-Schleife aber wie soll ich es sonst machen?

greetz
daddz
 
Also der Code sieht soweit ganz gut aus.
Ich habe mal eine ältere SDL-Anwendung rausgesucht und gestartet (3D-Terrain-Engine mit Skybox und Multitexturing - OpenGL) Das ganze läuft bei mir auch mit voller CPU-Last.
Das liegt am Event-Polling.
Meine Anwendung läuft mit 60-100 FPS d.h. es sind 60-100 Schleifendurchläufe pro Sekunde und jedesmal wird nach einem Event (Maus, Joystick, Tastatur) gefragt. Das zwingt den Prozessor in die Knie.

Also entweder du nimmst das hin (wenn dein Programm sich sowieso die ganze CPU-Last genemigen darf. Oder du baust eine Framebremse ein. D.h. du begrenzt deine Hauptschleifendurchläufe auf 30-50 mal pro Sekunde und wenn diese Zeit unterschritten wird (Schnelle CPU, wenig Berechnung, keine Events) dann machst du einfach einen SLEEP bis, die angegebenen 30-50 FPS vorbei sind.
Um die Zeit zu messen, musst du am Anfang der Schleife die Zeit nehmen (in Millisekunden) und dann am Ende der Schleife, dann berechnest du die Differenz.
50 FPS sind dabei 20 Millisekunden (1 Sekunde = 1000 Millisekunden / 50 = 20 Millisekunden).
Wenn dann deine Schleife nur 9 ms benötigt dann "schläftst" du eben 11 ms.
Das entlastet die CPU und dein Programm wird nie schneller als 50 FPS.

Daniel
 
Wie sieht das ganze den Code-Technisch aus? Ich bin nich so der C++-Crack! :-(
Wär nett wenn du mir ein kleines Beispiel zeigen könntest! ;-]

Danke schonmal!

greetz
daddz
 
Also hier mal etwas Pseudocode
Code:
// Hauptschleife
while(!done)
{
    // am Anfang Zeit nehmen
    unsigned int startTime;
    startTime = SDL_GetTicks();
     
    ...
    // Eventhandling

    ...
    // Berechnungen
    
    ...
    // Zeichnen usw...
   

    // am Ende Zeit nehmen
    unsigned int endTime;
    endTime = SDL_GetTicks();

     // Differenz berechnen (tatsächliche Dauer der Schleife
    unsigned int diffTime = endTime-startTime;
    
     // 50 FPS abwarten (20 Millisekunden)
     SDL_Delay(20-diffTime);
}

So oder so ähnlich könnte das aussehen.

Daniel
 
Oh...vielen Dank! :-( Werde das gleich mal probieren!
Mir fällt bei deinem Code noch was auf...wäre es nicht besser wenn die Variable startTime nicht vor der Schleife deklariert wird? Sonst wird sie doch bei jedem Durchlauf neu deklariert und das ist doch unnötig?

greetz
daddz
 
Zurück