SDL Blitting
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)
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.
rmask, gmask, bmask, amask)
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.
In the docs it says that you need to call
SDL_SetVideoMode() first so maybe you need to do something like this:
I think this should work?
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?
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
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???
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???
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:
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 :-)
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 :-)
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.
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| problems blitting a picture to the screen | petr6534 | 4 | 3,549 |
Oct 20, 2004 04:18 PM Last Post: petr6534 |
|
| Blitting modes in SDL? | Taxxodium | 2 | 2,627 |
Oct 27, 2003 09:43 AM Last Post: sealfin |
|
| Blitting all but one color in OpenGL | Griggs | 5 | 4,197 |
Sep 10, 2002 11:59 PM Last Post: Griggs |
|

