渲染问题,单缓冲效果

时间:2013-08-25 23:47:04

标签: c++ sdl sdl-image

情况:我目前正在尝试使用C ++中的SDL_image和SDL渲染一些内容(图像和一些文本)。然而,我遇到了一些看起来像缓冲问题的问题,但是我试图解决这个问题,我已经被困了好几个小时而无济于事。

问题:渲染时,屏幕会产生类似单缓冲的效果,其中先前位置的图像仍然在屏幕上显示,就像在最后一个缓冲区中一样。我怀疑问题出在我的绘制函数(主循环函数)

problem 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;
}

1 个答案:

答案 0 :(得分: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_Surface*的{​​{1}},SDL不会中断或警告您,我还建议您向load_image添加错误消息:

NULL