void render(){
SDL_Rect rect;
rect.x = 450;
rect.y = 450;
rect.w = 40;
rect.h = 40;
SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0,0xFF));
SDL_BlitSurface( framerate, NULL,screen, &rect );
SDL_Flip(screen);
}
(Yes it could be optimised, but I just want to get page flipping working propperly first). If I can't get page flipping working propperly I'll have to use another library as max CPU usage with only 90 ish FPS doing nothing is really bad.
Anyone have any suggestioins ?
Page Flipping in SDL
Hi people,
I have been playing around with SDL a little (I'm moving from java to SDL) and have come across a problem with SDL's page flipping abilities.
From my understanding, after creating an SDL_Surface* named screen(or anything else), and initialising it with the following line:
screen = SDL_SetVideoMode( 800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
it should be able to use page flipping and yet , when I call SDL_Flip(screen) it doesn't.
I know the capabilites are there, because when I was using java, a simple full-screen program could run at about 4k fps (when VSync was off). In SDL my program, which is a simple program to test framerate moderation, runs at only 80-95 FPS. When all frame rate moderation is turned off, that still remains the same. In a while(true){//render and stuff here} loop, it will go extremely slowly.
When I commented out the SDL_Flip() and instead wrote the un-restrained FPS into an output-file it showed that the fps was running into the thousands (possibly tens of thousands, I dont remember)
In the SDL documentation is says that if page flipping is unavailable it will use SDL_UpdateRect(blah blah blah), and when I replaced SDL_Flip() with SDL_UpdateRect() it ran at the same FPS, implying it's not page flipping propperly.
SDL wont allow page flipping in my program( and yet I know my GFX card supports it - 7600gt). My question is; Why wont SDL allow my pc to use page flipping when it clearly supports it ?
On the Windows machines I've tested, SDL only runs in hardware mode when you setup a full screen window, and runs in software windowed. If you want cross-platform hardware rendering in a window, you could consider using OpenGL with SDL.
I've found, however, that the software is more than fast enough for 2D games - 2D hardware acceleration has been pretty much phased out in favor of 3D stuff, and processor speeds and RAM quantities keep going up.
I've found, however, that the software is more than fast enough for 2D games - 2D hardware acceleration has been pretty much phased out in favor of 3D stuff, and processor speeds and RAM quantities keep going up.
I just tested it in fullscreen and the same thing happened, 90 FPS. This is so frustrating, it should work without any issues at all.
My pc shouldn't be struggling to get 100fps in software mode when its doing nothing. It still uses all my CPU as well.
Looks like I'll have to move onto something else which is annoying because I thought SDL would be good.
Thanks for the heads up on the Software in windowed mode thingy though, I didn't know about that.
My pc shouldn't be struggling to get 100fps in software mode when its doing nothing. It still uses all my CPU as well.
Looks like I'll have to move onto something else which is annoying because I thought SDL would be good.
Thanks for the heads up on the Software in windowed mode thingy though, I didn't know about that.
It is very strange that you only get 100 fps. Do you have an outdated computer? My last game uses SDL in software mode and gets over that on almost all of the machines I tested it on. Maybe there is something else going on - could you post the complete code?
My pc should run it fine, it's still fairly new. I'm kinda new so I don't know exactly how to put the code snippets in without just pasting them, so bare with me. Also this code is kinda messy, hadn't planned on cleaning it up for a bit, as it is still my first SDL app.
#include "SDL/SDL.h"#include <string>#include <SDL/SDL_image.h>#include <SDL/SDL_ttf.h>#include <SDL/SDL_rotozoom.h>#include <windows.h>#include <cstdlib>#import "HRTimer.cpp"#import "Entity.cpp"#import "map.cpp"#import <fstream.h>//very messy I know.void getAndProcessEvents();void render();void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination );void apply_surface( int x, int y,int width, int height, SDL_Surface* source, SDL_Surface* destination );void itoa(int x, char **pointer);void update();SDL_Surface *load_image( std::string filename ) ;SDL_Surface *backgrounds;SDL_Surface *screen;SDL_Surface *tile;SDL_Event event;int xOffset = 0;int yOffset = 0;bool quit = false;int fpsMain = 0;SDL_Color textColor = { 255, 255, 255 };TTF_Font* font = NULL;SDL_Surface *framerate = NULL;bool *keyArray;SDL_Surface *temp = NULL;char *fpschar;ofstream *log_file;int main( int argc, char* args[] ){ temp = new SDL_Surface(); log_file = new ofstream("log_file.txt"); int width = 256; int height = 256; char *pathArray[width]; *pathArray = new char[width]; for(int x = 0;x < height;x++) pathArray[x] = (char*)malloc(sizeof(char)*width); FILE *fp = fopen("out.txt","r"); char c; int x = 0; for(int x = 0;x < height;x++) for(int y = 0;(c = (char)fgetc(fp)) != EOF && y < width;y++) pathArray[x][y] = c; Map *map = new Map(pathArray,height, width); keyArray = new bool[65536]; // dont quit without reason :) if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { return 1; } if( TTF_Init() == -1 ) { return false; } screen = SDL_SetVideoMode( 800, 600, 32,SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF ); temp = SDL_CreateRGBSurface( SDL_HWSURFACE, 800, 600, 32, 0, 0, 0,0); HRTimer *hr = new HRTimer(); double fpsTime =hr->currentTimeMS(); double baseTime = fpsTime; int fps = 0; font = TTF_OpenFont( "lazy.ttf", 32); backgrounds = load_image("background.png"); tile = load_image("tile.jpg"); while( quit == false ) { if(hr->currentTimeMS() - fpsTime > 1000){ fpsMain = fps; fps = 0; fpsTime = hr->currentTimeMS(); itoa(fpsMain, &fpschar); framerate = TTF_RenderText_Solid( font, fpschar, textColor ); *log_file << fpsMain; } //While there's an event to handle //update(); render(); getAndProcessEvents(); // commented out all the sleep functions so it runs as fast as possible. //double sleepTime = (baseTime+2.09999) - hr->currentTimeMS(); //if(sleepTime > 0) // Sleep(sleepTime); baseTime+=2.09999; fps++; } log_file->close(); return 0;}void getAndProcessEvents(){ while( SDL_PollEvent( &event ) ) { if( event.type == SDL_QUIT ) { quit = true; } if(event.type == SDL_KEYDOWN){ int keyCode = event.key.keysym.sym; keyArray[keyCode] = true; } if(event.type == SDL_KEYUP){ int keyCode = event.key.keysym.sym; keyArray[keyCode] = false; } } if(keyArray[SDLK_LEFT]) xOffset--; if(keyArray[SDLK_RIGHT]) xOffset+=2; if(keyArray[SDLK_UP]) yOffset--; if(keyArray[SDLK_DOWN]) yOffset++; if(keyArray[SDLK_ESCAPE]) quit = true;}void render(){ SDL_Rect rect; rect.x = 450; rect.y = 450; //SDL_Rect offset; //offset.w = 50; //offset.h = 50; /*for(int x = -1;x < 17;x++) for(int y = -1;y < 13;y++){ offset.x = x*50 + (xOffset%50); offset.y = y*50 + (yOffset%50); SDL_BlitSurface( tile, NULL, temp, &offset ); }*/ //SDL_Rect rect; rect.x = 450; rect.y = 450; rect.w = 40; rect.h = 40; SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0,0xFF)); SDL_BlitSurface( framerate, NULL,screen, &rect ); SDL_Flip(screen);}SDL_Surface *load_image( std::string filename ) { SDL_Surface* loadedImage = NULL; SDL_Surface* optimizedImage = NULL; loadedImage = IMG_Load( filename.c_str() ); if( loadedImage != NULL ) { optimizedImage = SDL_DisplayFormat( loadedImage ); SDL_FreeSurface( loadedImage ); if(optimizedImage != NULL){ Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ); SDL_SetColorKey( optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey ); } } return optimizedImage;}void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination ){ SDL_Rect offset; offset.x = x; offset.y = y; SDL_BlitSurface( source, NULL, destination, &offset );}void itoa(int x, char **pointer){ if(x == 0){ *pointer = new char[2]; pointer[0][0] = '0'; pointer[0][1] = '\0'; return; } int tempy = x; int length = 0; while(tempy != 0){ tempy/=10; length++; } *pointer = new char[length+1]; for(int i = length-1;x != 0;i--){ pointer[0] = x%10 +48; x/=10; } // patch it up :) pointer[0][length] = '\0'; return;}// lol ignore this.void update(){ for(int x = 0;x < 1000;x++){ for(int y = 0;y < 1000;y++){ int temp = x*y; temp+=50000; } }}
Well you have a fair amount of memory leaks with this code. You don't need to use new for fstream objects or SDL_Surfaces (I've seen this before with Java guys [smile]).
Your biggest memory leak, however, is the surface framerate. Every second, you allocate and build a new surface with:
framerate = TTF_RenderText_Solid( font, fpschar, textColor );
But you never free the surface. You should try something like the following:
Also, the array of size 65536 seems unnecessary; I think 256 would work fine.
Memory leaks will cause performance to downgrade as the cache becomes overrun, so you definately want to take care of that before you decide if SDL is fast enough or not.
I would rewrite some of your code, but I'm off to class [smile].
Your biggest memory leak, however, is the surface framerate. Every second, you allocate and build a new surface with:
framerate = TTF_RenderText_Solid( font, fpschar, textColor );
But you never free the surface. You should try something like the following:
if(hr->currentTimeMS() - fpsTime > 1000){ fpsMain = fps; fps = 0; fpsTime = hr->currentTimeMS(); itoa(fpsMain, &fpschar); // Free the old surface if( framerate != NULL ) SDL_FreeSurface( framerate ); framerate = TTF_RenderText_Solid( font, fpschar, textColor ); *log_file << fpsMain;}
Also, the array of size 65536 seems unnecessary; I think 256 would work fine.
Memory leaks will cause performance to downgrade as the cache becomes overrun, so you definately want to take care of that before you decide if SDL is fast enough or not.
I would rewrite some of your code, but I'm off to class [smile].
The array has to be Unicode size for some reason, as pressing any of the arrow keys results in some value around 275. Fixed some memory leaks, but that's not where the performance degrading is happening. Even with all those problems, when I cover certain parts of the window (with other windows) the framerate jumps up to about 2k.
The performance should still be way above what it is now.
Thanks again for the heads up again, I didn't know that the TTF_Render_Text_solid() actually created a new copy of the surface, but come to think of it, makes alot of sense.
The performance should still be way above what it is now.
Thanks again for the heads up again, I didn't know that the TTF_Render_Text_solid() actually created a new copy of the surface, but come to think of it, makes alot of sense.
Ok I made quite a few changes to get it to compile. Some of the changes are in the comments, most of the other things was just commenting out code or deleting it. For example many of the variables are only used inside a single function and are better suited to being locals.
I had to remove a few things that I dont have access to, like your map class, but I hope you can build on this.
Its still a bit messy, possibly more messy [smile], but now it runs at ~300fps in windowed mode and 1300fps in fullscreen, on my system anyway.
I had to remove a few things that I dont have access to, like your map class, but I hope you can build on this.
Its still a bit messy, possibly more messy [smile], but now it runs at ~300fps in windowed mode and 1300fps in fullscreen, on my system anyway.
#include <string>#include <cstdlib>#include <fstream>#include <sstream>#include "SDL.h"#include "SDL_image.h"#include "SDL_ttf.h"//include <SDL/SDL_rotozoom.h>//include <windows.h>//import "HRTimer.cpp"//import "Entity.cpp"//import "map.cpp"//very messy I know.void getAndProcessEvents();void render();void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination );void apply_surface( int x, int y,int width, int height, SDL_Surface* source, SDL_Surface* destination );void update();SDL_Surface *load_image( std::string filename ) ;SDL_Surface *backgrounds = NULL;SDL_Surface *screen = NULL;SDL_Surface *tile = NULL;int xOffset = 0;int yOffset = 0;bool quit = false;TTF_Font* font = NULL;SDL_Surface *framerate = NULL;std::ofstream log_file("log_file.txt");int main( int argc, char* args[] ){ //log_file = new ofstream("log_file.txt"); int width = 256; int height = 256; char *pathArray[width]; for(int x = 0;x < height;x++) pathArray[x] = new char[width]; //FILE *fp = fopen("out.txt","r"); /* char c; //int x = 0; for(int x = 0;x < height;x++) for(int y = 0;(c = (char)fgetc(fp)) != EOF && y < width;y++) pathArray[x][y] = c; */ //Map *map = new Map(pathArray,height, width); // dont quit without reason :) if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { return 1; } if( TTF_Init() == -1 ) { return 1; } screen = SDL_SetVideoMode( 800, 600, 32,SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF ); //HRTimer *hr = new HRTimer(); //double fpsTime =hr->currentTimeMS(); Uint32 fpsTime = SDL_GetTicks(); int fps = 0; font = TTF_OpenFont( "freesans.ttf", 32); backgrounds = load_image("background.png"); tile = load_image("tile.jpg"); while( quit == false ) { if(SDL_GetTicks() - fpsTime > 1000){ int fpsMain = 0; SDL_Color textColor = { 255, 255, 255 }; fpsMain = fps; if( framerate ) { SDL_FreeSurface(framerate); } fps = 0; fpsTime = SDL_GetTicks();//hr->currentTimeMS(); // preferred way to convert things to strings in C++ std::stringstream stream; stream << fpsMain; // stream.str() returns a std::string, which // we can use .c_str() on to get a const char pointer framerate = TTF_RenderText_Solid( font, stream.str().c_str(), textColor ); log_file << fpsMain; } render(); getAndProcessEvents(); fps++; } // std::ofstreams automatically close themselves when destructed //log_file->close(); return 0;}void getAndProcessEvents(){ SDL_Event event; while( SDL_PollEvent( &event ) ) { if( event.type == SDL_QUIT ) { quit = true; } // SDL has a build in keyboard state, see below /* if(event.type == SDL_KEYDOWN){ int keyCode = event.key.keysym.sym; keyArray[keyCode] = true; } if(event.type == SDL_KEYUP){ int keyCode = event.key.keysym.sym; keyArray[keyCode] = false; } */ } // like so: Uint8 *keyArray = SDL_GetKeyState(NULL); if(keyArray[SDLK_LEFT]) xOffset--; if(keyArray[SDLK_RIGHT]) xOffset+=2; if(keyArray[SDLK_UP]) yOffset--; if(keyArray[SDLK_DOWN]) yOffset++; if(keyArray[SDLK_ESCAPE]) quit = true;}void render(){ SDL_Rect rect; rect.x = 450; rect.y = 450; rect.w = 40; rect.h = 40; // your rect isnt big enough to fit thousands of fps =) SDL_FillRect(screen, /*&rect*/NULL, SDL_MapRGB(screen->format, 0, 0,0xFF)); SDL_BlitSurface( framerate, NULL,screen, &rect ); SDL_Flip(screen);}SDL_Surface *load_image( std::string filename ){ SDL_Surface* loadedImage = NULL; SDL_Surface* optimizedImage = NULL; loadedImage = IMG_Load( filename.c_str() ); if( loadedImage != NULL ) { optimizedImage = SDL_DisplayFormat( loadedImage ); SDL_FreeSurface( loadedImage ); if(optimizedImage != NULL){ Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ); SDL_SetColorKey( optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey ); } } return optimizedImage;}void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination ){ SDL_Rect offset; offset.x = x; offset.y = y; SDL_BlitSurface( source, NULL, destination, &offset );}/*// lol ignore this.void update(){ for(int x = 0;x < 1000;x++){ for(int y = 0;y < 1000;y++){ int temp = x*y; temp+=50000; } }}*/
Quote:Original post by Mogthew
I just tested it in fullscreen and the same thing happened, 90 FPS. This is so frustrating, it should work without any issues at all.
Is VSync on? That is the normal behaviour for page flipping.
Quote:My pc shouldn't be struggling to get 100fps in software mode when its doing nothing. It still uses all my CPU as well.
Using all your CPU is not a sign of any sort of problem.
Vsync was off. If my app was doing nothing and using all cpu, thats pretty silly. Doesn't leave any room for actual calculations in the game.
As for vysnc, I have the refresh rate override, so it would be capped at 100, it never _usually_ goes above 95.
EDIT:
After compiling the New source code for the app, my computer runs it for about 2 seconds, then quits. Also, theres a segfault somewhere oO
Fixed the segfault, the App still runs at 100 fps in fullscreen mode (with vysnc off)
I have a 3800 dual core, this shouldn't be happening (it maxes out 1 core at 95FPS).
[Edited by - Mogthew on February 20, 2007 6:31:24 PM]
As for vysnc, I have the refresh rate override, so it would be capped at 100, it never _usually_ goes above 95.
EDIT:
After compiling the New source code for the app, my computer runs it for about 2 seconds, then quits. Also, theres a segfault somewhere oO
Fixed the segfault, the App still runs at 100 fps in fullscreen mode (with vysnc off)
I have a 3800 dual core, this shouldn't be happening (it maxes out 1 core at 95FPS).
[Edited by - Mogthew on February 20, 2007 6:31:24 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement