SDL_Flip()???

Started by
3 comments, last by RuneLancer 17 years, 11 months ago
I got a ball going up and down on the screen, no errors, but it leaves a trail everywhere it goes. SDL_Flip(background); if i understand correctly this refreshes the background overwriting the last frame. Ive placed "SDL_Flip(screen/ g_Bitmap)" all over the place, but i still get a trail from the ball. (some of the code is from Aaron Cox sdl tutorials) can someone help me please?(if you need more of the code let me know(although im sure the error is in here somewhere))

void Game()
{	
    
	// Here we compare the difference between the current time and the last time we //
	// handled a frame. If FRAME_RATE amount of time has, it's time for a new frame. //
	if ( (SDL_GetTicks() - g_Timer) >= FRAME_RATE )
	{
		HandleGameInput();

		// Make sure nothing from the last frame is still drawn. //
		ClearScreen();

		// Draw the background of our little 'game'. //
		DrawBackground();
		
		//SDL_BlitSurface(g_Bitmap, &g_Ball.bitmap_location,     g_Window, &g_Ball.screen_location);
       DrawDot(g_Ball.screen_location.x, g_Ball.screen_location.y, g_Dot, g_Bitmap);
        
		// Tell SDL to display our backbuffer. The four 0's will make //
		// SDL display the whole screen. //
		SDL_UpdateRect(g_Window, 0, 0, 0, 0);
		SDL_Flip(g_Bitmap);
		// We've processed a frame so we now need to record the time at which we did it. //
		// This way we can compare this time the next time our function gets called and  //
		// see if enough time has passed between iterations. //
		g_Timer = SDL_GetTicks();
	}	
}


void apply_surface(int x, int y, SDL_Surface *source, SDL_Surface *screen) {
    SDL_Rect offset;

    offset.x=x;
    offset.y=y;
    
    
    //SDL_UpdateRect(g_Window, 0, 0, 0, 0);
    SDL_BlitSurface(g_Bitmap, &g_Ball.bitmap_location, g_Window, &g_Ball.screen_location);
    SDL_BlitSurface(source, NULL, screen, &offset);
     
}

void DrawDot(int x, int y, SDL_Surface *source, SDL_Surface *screen){
     
     SDL_Flip(screen);
     apply_surface(x, y, source, screen);
    
     MoveBall();
     SDL_Flip(screen);
     
     }
void DrawBackground() 
{
	// These structures tell SDL_BlitSurface() the location of what //
	// we want to blit and the destination we want it blitted to.   //
	// Presently, we blit the entire surface to the entire screen.  //
	SDL_Rect source      = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };		
	SDL_Rect destination = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
	
	// This just 'block-image transfers' our bitmap to our window. //
	SDL_BlitSurface(g_Bitmap, &source, g_Window, &destination);
	
}

// This function simply clears the back buffer to black. //
void ClearScreen()
{
	// This function just fills a surface with a given color. The //
	// first 0 tells SDL to fill the whole surface. The second 0  //
	// is for black. //
//

	SDL_FillRect(g_Window, 0, 0);
	
}



Advertisement
I only skimmed your code, but it looks to me like you're drawing the ball directly on your background bitmap, so the 'trail' essentially becomes part of your background.
I changed your code a little,just commented out lines and added in ones. Hopefully it will work, but you had so many SDL_Flips, that (i dont think) you need.


void Game(){	        SDL_Rect Dest;	// Here we compare the difference between the current time and the last time we //	// handled a frame. If FRAME_RATE amount of time has, it's time for a new frame. //	if ( (SDL_GetTicks() - g_Timer) >= FRAME_RATE )	{		HandleGameInput();		// Make sure nothing from the last frame is still drawn. //		ClearScreen();		// Draw the background of our little 'game'. //		DrawBackground();				//SDL_BlitSurface(g_Bitmap, &g_Ball.bitmap_location,     g_Window, &g_Ball.screen_location);       DrawDot(g_Ball.screen_location.x, g_Ball.screen_location.y, g_Dot, g_Bitmap);        		// Tell SDL to display our backbuffer. The four 0's will make //		// SDL display the whole screen. //		//SDL_UpdateRect(g_Window, 0, 0, 0, 0);		//SDL_Flip(g_Bitmap);                                 Dest.x = 0;                Dest.y = 0;                Dest.w = screen->w;                Dest.h = screen->h;                SDL_BlitSurface(screen, SDL_Rect, g_Bitmap, &g_Ball.bitmap_location);                SDL_Flip(screen);		// We've processed a frame so we now need to record the time at which we did it. //		// This way we can compare this time the next time our function gets called and  //		// see if enough time has passed between iterations. //		g_Timer = SDL_GetTicks();	}	}void apply_surface(int x, int y, SDL_Surface *source, SDL_Surface *screen) {    SDL_Rect offset;    offset.x=x;    offset.y=y;            //SDL_UpdateRect(g_Window, 0, 0, 0, 0);    SDL_BlitSurface(g_Bitmap, &g_Ball.bitmap_location, g_Window, &g_Ball.screen_location);    //SDL_BlitSurface(source, NULL, screen, &offset);     }void DrawDot(int x, int y, SDL_Surface *source, SDL_Surface *screen){          //SDL_Flip(screen);     apply_surface(x, y, source, screen);         MoveBall();     //SDL_Flip(screen);          }void DrawBackground() {	// These structures tell SDL_BlitSurface() the location of what //	// we want to blit and the destination we want it blitted to.   //	// Presently, we blit the entire surface to the entire screen.  //	SDL_Rect source      = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };			SDL_Rect destination = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };		// This just 'block-image transfers' our bitmap to our window. //	SDL_BlitSurface(g_Bitmap, &source, g_Window, &destination);	}// This function simply clears the back buffer to black. //void ClearScreen(){	// This function just fills a surface with a given color. The //	// first 0 tells SDL to fill the whole surface. The second 0  //	// is for black. ////	SDL_FillRect(g_Window, 0, 0);	}
Im afraid I didnt understand your code completly, maybe I didnt spend enough time on it but I really dont get why you're doing flips on g_Bitmap? is it double buffered? if yes why?

if its not changing (and I dont mean position changing) dont do this. your drawing code per frame should look something like this:

<pseudocode>
SDL_FillRect(screen); //clear
SDL_BlitSurface(ball,x,y); //blit
SDL_Flip(screen); //flip
</pseudocode>

if its changing it should look like this:

<pseudocode>
SDL_FillRect(screen);
SDL_FillRect(ball); //only if you're filling it completly new
SDL_LockSurface(ball);
//apply modifications to the ball here
SDL_UnlockSurface(ball);
SDL_BlitSurface(ball,x,y);
SDL_Flip(screen);
</pseudocode>

you dont even need a double buffered surface for that.
SDL_Flip does not clear your background.

Your monitor updates its display every once in a while. This will not necessarily match up with when your game is done rendering stuff to the screen. So you might end up with half an image because the monitor updates before your program finishes its own image update.

To solve this, most APIs have a backbuffer. The backbuffer is a second "screen," only this one isn't displayed anywhere. So you can draw to it and not worry about what gets shown on the real screen. When you're done, you simply say "A'aight mate, swap the real screen and the fake one." Pop! Your entire frame is sent to the display in one shot. Meanwhile the old display becomes your backbuffer, and the process is repeated.

This does not mean your old display is now blank. It's still there. It's just not being drawn anymore - you said you wanted the "fake" one (now the real one) to be drawn instead.

Clear your backbuffer before rendering to it. That should take care of the trails. I'm guessing you had flicker issues too, because one frame would be rendered to the backbuffer, the second to the actual-display-but-backbuffer-now-since-you-swapped them, then the third to the backbuffer (the old one), etc..

This topic is closed to new replies.

Advertisement