Jump to content
  • Advertisement
Sign in to follow this  
archaos90

Rendering & SDL

This topic is 3818 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey again, When you blit a SDL_Surface in SDL the content of the source SDL_Surface gets cleared. I tried to duplicate the SDL_Surface but it doesn't work (as shown in the code below). The purpose of this is that the program should only need to draw the room/level once, and not everytime it loops. The SDL wiki states that you shouldn't use memcpy (which I tried at first, but it segfaulted ofc) and recommended the method I used below as the proper way. Any suggestions?
Hero hero(200, 400);
SDL_Surface *levelm;
SDL_Surface *levels;
bool update_level;

void InitRender(SDL_Surface *screen)
{
      levels = SDL_SetVideoMode(screen->clip_rect.w, screen->clip_rect.w, 16, SDL_SWSURFACE | SDL_PREALLOC);                            
      levelm = SDL_SetVideoMode(screen->clip_rect.w, screen->clip_rect.w, 16, SDL_SWSURFACE | SDL_PREALLOC);
      update_level = true;
}

void RenderScene(SDL_Surface *screen, SDL_Surface *newscreen, SDL_Surface *emptyscreen, Room *rooms, int croom)
{                                 
        /* Prepare scene */
        SDL_SetColorKey(newscreen, SDL_SRCCOLORKEY, SDL_MapRGB(newscreen->format, 0x00, 0x00, 0x00)); 
        SDL_FillRect(SDL_GetVideoSurface(), NULL, SDL_MapRGB(SDL_GetVideoSurface()->format, 0,0,0));     
        
        /* Draw into scene */
        if (update_level == true)
        {
           rooms[croom].Draw(levelm);
        }
        else
        {
                  levelm = levels;
        }   
        levels = levelm;     
        levels->refcount++;       
        update_level = false;        
        SDL_BlitSurface(levelm, &levelm->clip_rect, newscreen, &newscreen->clip_rect);
        hero.Draw(newscreen);
        
        /* Render scene */        
        SDL_BlitSurface(newscreen, NULL, screen, NULL);
        SDL_Flip(screen);      
}

Share this post


Link to post
Share on other sites
Advertisement
The source doesn't get cleared. Can you link me to where you read that it does.

From the looks of your code you have a skewed understanding of how to render things in SDL. At one point you have a function that takes a "screen" pointer as an argument and then calls SDL_SetVideoMode repeatedly. Calling SDL_SetVideoMode more than once will deallocate the current video surface (screen, followed by levels will be bad pointers). If you post a more complete example, I may be able to re-write it slightly better.

To duplicate a surface - something you rarely have to do - look into SDL_CreateRGBSurface(). But there is a way around this.

Share this post


Link to post
Share on other sites
Quote:

The source doesn't get cleared. Can you link me to where you read that it does.


Try it yourself. Draw something into a surface, blit it, then blit again. Voila, voidness!

Quote:

From the looks of your code you have a skewed understanding of how to render things in SDL. At one point you have a function that takes a "screen" pointer as an argument and then calls SDL_SetVideoMode repeatedly. Calling SDL_SetVideoMode more than once will deallocate the current video surface (screen, followed by levels will be bad pointers). If you post a more complete example, I may be able to re-write it slightly better.


Please separate InitRender from RenderScene. InitRender executes only once before the game loop.

Quote:
To duplicate a surface - something you rarely have to do - look into SDL_CreateRGBSurface(). But there is a way around this.


So, I'm supposed to only use one surface, excluding those that gets generated through SDL_LoadBMP and such, or what do you mean?

Share this post


Link to post
Share on other sites
Quote:

Try it yourself. Draw something into a surface, blit it, then blit again. Voila, voidness!


I have used SDL for something like 4 years. I am very familiar with it, I've read some of the code. I know that blitting from a surface does not alter the pixel data of that surface.

If you post an small example of this, Ill run it and see what results I get. I'm always prepared to be proven wrong [smile].

Quote:

Please separate InitRender from RenderScene. InitRender executes only once before the game loop.


While I can see that, the fact that InitRender calls SDL_SetVideoMode() twice means that, at the very least, you have a single bad pointer (levels). You may have an additional bad pointer if the "screen" parameter points to something returned by SDL_SetVideoMode() too.

Quote:

So, I'm supposed to only use one surface, excluding those that gets generated through SDL_LoadBMP and such, or what do you mean?


Usually, yes. Of course there are exceptions.

Maybe you're trying to implement (software) double buffering? Parallax backgrounds? Sometimes you will need additional surfaces. If I had an idea of what all the different surfaces in your code were supposed to represent I might be able to explain a better way (If one exists [grin]).

I can see you modifying the refcount member of an SDL_Surface, which is possibly a bad idea.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!