Sign in to follow this  
vanzukeus

[SDL] drawing a rectangle in a surface

Recommended Posts

Hi all, I'm using SDL and SDL_gfx for primitives like fillRectangle etc. I have a problem, I want to draw a rectangle in a SDL_surface and after display the content of this surface in the screen (the main SDL_surface). I'm doing this:
SDL_Surface* test;
test = new SDL_Surface();
//test->h=300;
//test->w=300;
boxRGBA(test,22,33,44,100,144,2,3,122);
CSurface::OnDraw(Surf_Display,test,1,1);

with:
 
bool CSurface::OnDraw(SDL_Surface* Surf_Dest, SDL_Surface* Surf_Src, int X, int Y) {
	if(Surf_Dest == NULL || Surf_Src == NULL) {
		return false;
	}

	SDL_Rect DestR;

	DestR.x = X;
	DestR.y = Y;

	SDL_BlitSurface(Surf_Src, NULL, Surf_Dest, &DestR);

	return true;
}
I get that test has all the fields undefined and I have not got it why.. Thanks in advance!

Share this post


Link to post
Share on other sites
First you should create a surface with SDL_CreateRGBSurface() instead of new SDL_Surface(). Then, if you set a DestR rect, be sure to at least put a size (.w and .h) or else it will be 0 and won't do anything. Finally, for a simple rectangle you don't have to usr SDL_gfx, you can simply use SDL_FillRect().

Share this post


Link to post
Share on other sites
You've allocated memory for an SDL_Surface struct, that's all. None of that data is filled in. You want SDL to create a new surface that you can use, then draw your rect on that and finally blit that surface onto the screen:
test = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, primary->format->BitsPerPixel, 
primary->format->Rmask, primary->format->Gmask, primary->format->Bmask, primary->format->Amask);

// check for success
if (!test)
throw std::exception(); // failed to create surface!

Remember to use SDL_FreeSurface() to free surfaces, don't delete them.

Share this post


Link to post
Share on other sites
thanks :)
Now I'm going to try it. Anyway, I need a filled rectangle. SDL_gfx provides circle and other stuff also and it is portable in almost all the OS that support SDL if I rimember well. What do you think about this library?

Share this post


Link to post
Share on other sites
I found the signature of that method:
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);

but.. if I want to use SDL_gfx methods this SDL_CreateRGBSurface seems useless

Share this post


Link to post
Share on other sites
What? If you're using an appropriate video format, just enable alpha blending

// SRCALPHA = enable alpha blending on this surface
// *note that this is a 32bit surface, so if your primary surface isn't also 32 bits
// then your frame rate will suffer
test = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, w, h, 32,
primary->format->Rmask, primary->format->Gmask, primary->format->Bmask, 0);

if (!test)
throw std::exception(); // error creating surface

// apparently strangeness can occur when Amask != 0 while setting alpha channel, so
// this is SDL's workaround
// set this surface's alpha value to 255 (fully opaque). per-pixel alpha values
// take precedence over per-surface alpha
if (SDL_SetAlpha(test, SDL_SRCALPHA, SDL_ALPHA_OPAQUE) == -1)
throw std::exception(); // error setting surface alpha value

I'll also point out that you don't need alpha channels for boxRGBA, it programmatically alphablends with the destination and doesn't use an alpha channel.

Share this post


Link to post
Share on other sites
Guys thanks for the infos,

I tried both of your advices:


int w=50;
int h=50;

test = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, w, h, 32,155,55,55, 55);

if (!test)
throw std::exception(); // error creating surface

// apparently strangeness can occur when Amask != 0 while setting alpha channel, so
// this is SDL's workaround
// set this surface's alpha value to 255 (fully opaque). per-pixel alpha values
// take precedence over per-surface alpha
if (SDL_SetAlpha(test, SDL_SRCALPHA, SDL_ALPHA_OPAQUE) == -1)
throw std::exception(); // error setting surface alpha value

CSurface::OnDraw(Surf_Display,test,22,22);


and

SDL_Surface* test;
SDL_Rect *rect = new SDL_Rect();
rect->x=100;
rect->y=100;
rect->w=100;
rect->h=100;
test = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 200, 200, 32,155,55,55, 55);
Uint32 rectcolor = SDL_MapRGB( test->format, 33, 144, 55 );
//boxRGBA(test,22,33,44,100,144,2,3,122);
SDL_FillRect( test, rect, rectcolor );
CSurface::OnDraw(Surf_Display,test,1,1);


Both don't work :(
they compile, no error at run-time but no visible rectangle in the screen too :D

Share this post


Link to post
Share on other sites
Quote:
Original post by vanzukeus
test = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 200, 200, 32,155,55,55, 55);
[/code]


The last 4 parameters to SDL_CreateRGBSurface are not colour values. They are there to tell the surface how to pack the colour data you store into it. Try sending through the data out of the main surface as Amrazek suggested.

Share this post


Link to post
Share on other sites
Yes now it works.
Anyway, this is the solution:


Uint32 rmask, gmask, bmask, amask;

/* SDL interprets each pixel as a 32-bit number, so our masks must depend
on the endianness (byte order) of the machine */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

SDL_Surface* test;
SDL_Rect *rect = new SDL_Rect();
rect->x=100;
rect->y=100;
rect->w=100;
rect->h=100;
test = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 200, 200, 32,rmask, gmask, bmask, amask);
Uint32 rectcolor = SDL_MapRGB( test->format, 155, 0, 55 );
//boxRGBA(test,22,33,44,100,144,2,3,122);
SDL_FillRect( test, rect, rectcolor );
CSurface::OnDraw(Surf_Display,test,1,1);


Thanks for the help!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this