Ситуация: В настоящее время я пытаюсь сделать несколько вещей (изображения и текст), используя SDL_image и SDL в C ++. Однако я сталкиваюсь с некоторыми проблемами, которые выглядят как проблемы с буферизацией, однако, с моими попытками исправить это, я застрял в течение нескольких часов безрезультатно.
Проблема: При рендеринге экран дает эффект одиночной буферизации, когда изображение в его предыдущей позиции все еще отображается на экране, как в последнем буфере. Я подозреваю, что проблема лежит где-то в моей функции рисования (функция основного цикла)
проблема http://oi41.tinypic.com/28v6gc0.jpg
Вот мой main.cpp:
#include "SDL.h"#include "SDL_image.h"#include "Player.h"#include "Values.h"#include <string>
#include <sstream>
#include "SDL_ttf.h"#include "Timer.h"
//The surfaces that will be used
SDL_Surface *message = NULL;
SDL_Surface *background = NULL;
SDL_Surface *text = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *startStop = NULL;
SDL_Surface *pauseMessage = NULL;
SDL_Surface *seconds = NULL;
//The font thats going to be used
TTF_Font *font = NULL;
//The colour of the font
SDL_Color textColor = {255,255,255};
Player ** player;
Timer myTimer;
bool quit = false;
Uint32 start = 0;
bool running = true;
int fame = 0;
bool cap = true;
//Timer fps;
SDL_Event event;
void clean_up()
{
//Free the surfaces
//SDL_FreeSurface( message );
player[0]->clean();
SDL_FreeSurface( background );
SDL_FreeSurface( seconds );
SDL_FreeSurface(startStop);
SDL_FreeSurface(pauseMessage);
TTF_CloseFont(font);
TTF_Quit();
//Quit SDL
SDL_Quit();
}
SDL_Surface *load_image( std::string filename )
{
//Temporary storage for the image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = SDL_LoadBMP( filename.c_str() );
//If nothing went wrong in loading the image
if( loadedImage != NULL )
{
//Create an optimized image
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old image
SDL_FreeSurface( loadedImage );
}
//Return the optimized image
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
//Make a temporary rectangle to hold the offsets
SDL_Rect offset;
//Give the offsets to the rectangle
offset.x = x;
offset.y = y;
//Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
bool loadFiles()
{
player[0]->load_files();
background = load_image( "Floor1.bmp" );
//Open the font
font = TTF_OpenFont("lazy.ttf",28);
//If there was a problem in loadin the font
if(font == NULL)
{
return false;
}
return true;
}
bool init()
{
//Initialize all SDL subsystems
SDL_Init( SDL_INIT_EVERYTHING );
//Set up the screen
//screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 0,
SDL_HWSURFACE | SDL_DOUBLEBUF );
//Initialize SDL_tff
if(TTF_Init() == -1)
{
return false;
}
//Set the window caption
SDL_WM_SetCaption( "10 seconds", NULL );
player = new Player*[1];
player[0] = new Player(screen);
loadFiles();return true;
};
void mainloop()
{
startStop = TTF_RenderText_Solid(font, "Press S to start or stop the timer", textColor);
pauseMessage = TTF_RenderText_Solid(font, "Press P to pause or unpause the timer", textColor);
myTimer.start();
while (quit == false)
{
//While there's events to handle
while( SDL_PollEvent( &event ) )
{
//Handle events for the dot
player[0]->handleInput(event);
if (event.type == SDL_KEYDOWN)
{
//if s was pressed
if(event.key.keysym.sym == SDLK_s)
{
//if the timer is running
if(myTimer.isStarted() == true)
{
//Stop the timer
myTimer.stop();
}
else
{
//Start the timer
myTimer.start();
}
}
if (event.key.keysym.sym == SDLK_p)
{
//If the timer is paused
if (myTimer.isPaused() == true)
{
//Unpause the timer
myTimer.unpause();
}
else
{
//Pause the timer
myTimer.pause();
}
}
}
//If the user has Xed out the window
else if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
//Apply all images to screen
apply_surface( 0, 0, background, screen );
apply_surface( ( SCREEN_WIDTH - startStop->w ) / 2, 200, startStop, screen );
apply_surface( ( SCREEN_WIDTH - pauseMessage->w ) / 2, 250, pauseMessage, screen );
//The timers time as a string
std::stringstream time;
//convert the timers time to a string
time << "Timer: " << myTimer.getTicks() / 1000.f;
seconds = TTF_RenderText_Solid( font, time.str().c_str(), textColor );
//Render the time surface
apply_surface( ( SCREEN_WIDTH - seconds->w ) / 2, 0, seconds, screen );
/Free the time surface
//PlayerHandling
player[0]->move();
player[0]->setCamera();
player[0]->draw();
SDL_FreeSurface( seconds );
SDL_Flip(screen);
}
}int main( int argc, char* args[] )
{
init();
mainloop();
clean_up();
return 0;
}
Кажется, судя по графическому эффекту и тому факту, что ваш фон весь черный, ваш код не может загрузить фон. Вы можете проверить это, просто заполнив background
с цветом.
background = SDL_CreateRGBSurface( 0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 );
SDL_FillRect( background, NULL, SDL_MapRGBA( background->format, 125, 125, 0, 255) );
Поскольку SDL не ломается и не предупреждает вас, если вы пытаетесь использовать SDL_Surface*
это указывает на NULL
Я также предлагаю добавить сообщение об ошибке в ваш load_image:
SDL_Surface *load_image( std::string filename )
{
//Temporary storage for the image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = SDL_LoadBMP( filename.c_str() );
//If nothing went wrong in loading the image
if( loadedImage != NULL )
{
//Create an optimized image
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old image
SDL_FreeSurface( loadedImage );
} else
{
std::cout << "ERROR : Failed to load image : " << filename << std::endl;
}
//Return the optimized image
return optimizedImage;
}
Других решений пока нет …