SDL Blitting

KidTsunami
Unregistered
 
Post: #1
I'm trying to blit sections of an SDL surface to a blank SDL surface so that I can split up textures when i load them into OpenGL. I haven't been able to successfully blit from the original surface to the blank surface. I've tried the function (destSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 128, 128, 32,
rmask, gmask, bmask, amask)Wink And I've tried just rocking a NULL surface. And they all have not worked correctly. What is an easy way to make a blank surface that I blit a section of another surface to make a bunch of textures from a larger surface. Any help would be appreciate thanks.
Quote this message in a reply
Member
Posts: 156
Joined: 2002.10
Post: #2
In the docs it says that you need to call

SDL_SetVideoMode() first so maybe you need to do something like this:

Code:
SDL_Surface* screen = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE);

SDL_Surface* mysurf = SDL_CreateRGBSurface(SDL_SWSURFACE, 128, 128, screen->format->BitsPerPixel, rmask, gmask, bmask, amask);

I think this should work?
Quote this message in a reply
Moderator
Posts: 697
Joined: 2002.04
Post: #3
A little source which merely blits an image - sorry for the lack of comments in the code... by the way, this uses the SDL_Image libraries.
Code:
int main( int argc,
          char *argv[] )
{
  const Uint32 theInitialisationFlags = (SDL_INIT_VIDEO),
               theVideoFlags = ( SDL_HWSURFACE | SDL_HWPALETTE );
  const Uint16 theWidth = 128,
               theHeight = 128;
  const Uint8 theDepth = 32;
  SDL_Surface *theSurface,
              *theImageSurface = NULL;
  SDL_Rect theSurfaceRect;
  SDL_Event theEvent;
  const char theImagePath[] = "Test image.png";



  if ( SDL_Init( theInitialisationFlags ) != 0 )
    goto label_quit;
  if(( theSurface = SDL_SetVideoMode( theWidth, theHeight, theDepth, theVideoFlags )) == NULL )
    goto label_quit;
  if(( theImageSurface = IMG_Load( theImagePath )) == NULL )
    goto label_quit;
    //    The st¸ff below is very, very important.
  SDL_UnlockSurface( theSurface );
  SDL_UnlockSurface( theImageSurface );
  theSurfaceRect.x = 0;
  theSurfaceRect.y = 0;
  if( SDL_BlitSurface( theImageSurface, NULL, theSurface, &theSurfaceRect ) != 0 )
    goto label_quit;
  SDL_UpdateRect( theSurface, 0, 0, 0, 0 );
  label_loop:
  while( SDL_PollEvent( &theEvent ))
    if( theEvent.type == SDL_QUIT )
      goto label_quit;
  goto label_loop;
  label_quit:
  if( theImageSurface != NULL )
    SDL_FreeSurface( theImageSurface );
  SDL_Quit();
  return 0;
}

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
KidTsunami
Unregistered
 
Post: #4
Ok, see the problem I have is not blitting to the screen, that works. My only problem is creating a blank surface and blitting to that. Here is my code:

Uint32 rmask, gmask, bmask, amask;
SDL_Surface * destSurface = NULL;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

destSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 128, 128, 32,
rmask, gmask, bmask, amask);
// destSurface = IMG_Load (fileName.c_str());
SDL_Rect * sourceRect = new SDL_Rect ();
sourceRect -> x = i * tileWidth;
sourceRect -> y = j * tileHeight;
sourceRect -> w = tileWidth;
sourceRect -> h = tileHeight;

SDL_Rect * destRect = new SDL_Rect ();

destRect -> x = 0;
destRect -> y = 0;
destRect -> w = tileWidth;
destRect -> h = tileHeight;
SDL_UnlockSurface (tempSurface);
SDL_UnlockSurface (destSurface);
cout << SDL_BlitSurface(tempSurface, sourceRect, destSurface, NULL);
SDL_Surface *screen;
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
SDL_BlitSurface (destSurface, destRect, screen, NULL);
SDL_UpdateRect(screen, 0, 0, 640, 480);
SDL_Delay (1000);

I know thats not pretty but pretty much I'm just trying to get this to work somehow. As you can see, towards the top I have two different ways of making the destSurface surface. Currently the load image one is commented out. With that one, the blit works, but the result is a composite of the blit and the image that was already there. So I want a blank surface to blit to, but the blit just doesn't work when I rock the create RGB surface. Thanks for the help though. Any other thoughts???Wacko
Quote this message in a reply
alienjon
Unregistered
 
Post: #5
I just had the same issue. Turns out that the problem is that the format of the newly created surface doesn't match that of the screen. Converting it via: SDL_DisplayFormat(mySurface) will fix the problem like so:

Code:
SDL_Surface* Get_Sub_Surface(SDL_Surface* metaSurface, int x, int y, int width, int height)
{
    // Create an SDL_Rect with the area of the surface you want to create.
    SDL_Rect area;
    area.x = x;
    area.y = y;
    area.w = width;
    area.h = height;

    // Set the RGBA mask values.
    Uint32 r, g, b, a;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    r = 0xff000000;
    g = 0x00ff0000;
    b = 0x0000ff00;
    a = 0x000000ff;
#else
    r = 0x000000ff;
    g = 0x0000ff00;
    b = 0x00ff0000;
    a = 0xff000000;
#endif

    // Here's the actual magic.
    //Create a new surface via SDL_CreateRGBSurface() by providing:
    //    The flags you want (I only tested with SDL_SWSURFACE).
    //    The dimension of the new surface.
    //    The bitrate you want to use.
    //    The mask values you just created.
    //Then convert it to match the display's format. (this was the crucial part that fixed it for me)
    SDL_Surface* subSurface = SDL_DisplayFormat(SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, r, g, b, a));

    // Lastly, apply the area from the meta surface onto the whole of the sub surface.
    SDL_BlitSurface(metaSurface, &area, subSurface, 0);

    // Return the newly created surface!
    return subSurface;
}

I know that this post originated 5 years ago, but I just had the problem myself and couldn't find a suitable answer anywhere online so I figured I'd let you guys know too :-)
Quote this message in a reply
Member
Posts: 90
Joined: 2006.11
Post: #6
Code:
SDL_Surface* subSurface = SDL_DisplayFormat(SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, r, g, b, a))
//Great example of a memory leak. I shot myself in the foot reading this code.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  problems blitting a picture to the screen petr6534 4 3,807 Oct 20, 2004 04:18 PM
Last Post: petr6534
  Blitting modes in SDL? Taxxodium 2 2,851 Oct 27, 2003 09:43 AM
Last Post: sealfin
  Blitting all but one color in OpenGL Griggs 5 4,433 Sep 10, 2002 11:59 PM
Last Post: Griggs