RotoZoom is great, but

RotoZoom is great, but…

Hi, I want to use BMP rotation and BMP scaling in my next SDL game and
RotoZoom seems to be the best option with SDL.

My problem with RotoZoom is that the newly scaled and/or rotated BMP is NOT
centered

Can someone suggest some options to fix this issues.

Thanks in advance.

Also, my thankyou to the SDL programmers, nice game engine!

JeZ+Lee
SLNTHERO at AOL.com (mailto:SLNTHERO at AOL.com)
www.SilentHeroProductions.com (http://www.silentheroproductions.com/)

What point does RotoZoom rotate around? Do you have the graphic
centered on that point before you rotate it? I don’t know how you can
expect it to be centered after a scale. The center point changes while
the origin in the upper left corner almost certainly stays the same.–
Lilith

On 9/1/2006 at 8:02 PM, in message <4a3.8711480.322a3218 at aol.com>, wrote:

RotoZoom is great, but…

Hi, I want to use BMP rotation and BMP scaling in my next SDL game
and
RotoZoom seems to be the best option with SDL.

My problem with RotoZoom is that the newly scaled and/or rotated BMP
is NOT

centered

Can someone suggest some options to fix this issues.

Thanks in advance.

Also, my thankyou to the SDL programmers, nice game engine!

JeZ+Lee
SLNTHERO at AOL.com (mailto:SLNTHERO at AOL.com)
www.SilentHeroProductions.com
(http://www.silentheroproductions.com/)

Hello !

What point does RotoZoom rotate around? Do you have the graphic
centered on that point before you rotate it? I don’t know how you can
expect it to be centered after a scale. The center point changes while
the origin in the upper left corner almost certainly stays the same.

But the center point should be the center point
before scaling and rotating and afterwards.
Instead of using the upper left corner
before blitting save the coords of the center point.

I use something like this. When you call this routine
with center = true it not uses the upper left corner as x and
y, but it centers the surface so that x and y are the center points.

void Screen::Blit (Bitmap *bitmap, Sint16 x, Sint16 y,
bool x_flip, bool y_flip, bool center)
{
if ( use_video == false ) return;

if (center == false)
{
rect.x = x;
rect.y = y;
}
else
{
rect.x = x - ( (bitmap -> w) / 2 );
rect.y = y - ( (bitmap -> h) / 2 );
}

rect.w = bitmap -> w;
rect.h = bitmap -> h;

if (    (x_flip == false) &&
    (y_flip == false)	    )
{
SDL_BlitSurface (bitmap, NULL, screen, & rect);
}
else

if (    (x_flip && y_flip) == false	)
{
SDL_Rect from_rect, to_rect;

/* --- flip horizontally if requested --- */

if (x_flip == true) {
    from_rect.h = to_rect.h = bitmap->h;
    from_rect.w = to_rect.w = 1;
    from_rect.y = 0;
    to_rect.y = rect.y;
    from_rect.x = 0;
    to_rect.x = rect.x + bitmap->w - 1;

    do {
	SDL_BlitSurface(bitmap, &from_rect, screen, &to_rect);
	from_rect.x++;
	to_rect.x--;
    } while (to_rect.x >= 0);
}
else

/* --- flip vertically if requested --- */

if (y_flip == true) {
    from_rect.h = to_rect.h = 1;
    from_rect.w = to_rect.w = bitmap->w;
    from_rect.x = 0;
    to_rect.x = rect.x;
    from_rect.y = 0;
    to_rect.y = rect.y + bitmap->h - 1;

    do {
	SDL_BlitSurface(bitmap, &from_rect, screen, &to_rect);
	from_rect.y++;
	to_rect.y--;
    } while (to_rect.y >= 0);
}
}
else

{
SDL_Rect from_rect, to_rect;
Sint16 index_x = 0, index_y = 0;

for (index_y = 0; index_y < bitmap -> h; index_y ++)
{
    for (index_x = 0; index_x < bitmap -> w; index_x ++)
    {
	from_rect.w = 1;
	from_rect.h = 1;
	from_rect.x = index_x;
	from_rect.y = index_y;

	to_rect.w = 1;
	to_rect.h = 1;
	to_rect.x = x + bitmap -> w - index_x - 1;
	to_rect.y = y + bitmap -> h - index_y - 1;

	SDL_BlitSurface (bitmap, & from_rect, screen, & to_rect);
    }
}
}

}

CU

Hello !

RotoZoom is great, but…

Hi, I want to use BMP rotation and BMP scaling in my next SDL game and
RotoZoom seems to be the best option with SDL.

My problem with RotoZoom is that the newly scaled and/or rotated BMP is
NOT
centered

You asked that question already before.

When i look at the rotozoom text code and
it rotates a bitmap this is totally centered for
me, when i look at the result i mean.

You can not just use the upper left corner coords
before and after the rotation that is clear.

CU

void Visuals::DisplayBMPonScreenBufferRotoZoom(Sint8 spriteNumber, Sint16
xScreenPos, Sint16 yScreenPos, double angle, double zoom)
{
SDL_Rect destinationRectangle;

destinationRectangle.x = xScreenPos;
destinationRectangle.y = yScreenPos;

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 1);

destinationRectangle.x -= (temp2->w / 2);
destinationRectangle.y -= (temp2->h / 2);

SDL_BlitSurface(temp2, NULL, Screen, &destinationRectangle);
}

Hi the above Class function centers properly the new scaled and/or rotated
BMP 100%.

Problem now is that is crashes after a set period of time
(Access Violation error)

Any ideas about this crash, perhaps I am doing something wrong in above code
???

Thanks in advance!

Jesse
SLNTHERO at AOL.com (mailto:SLNTHERO at AOL.com)
www.SilentHeroProductions.com (http://www.SilentHeroProductions.com)

Hello !

void Visuals::DisplayBMPonScreenBufferRotoZoom(Sint8 spriteNumber, Sint16
xScreenPos, Sint16 yScreenPos, double angle, double zoom) {
SDL_Rect destinationRectangle;

destinationRectangle.x = xScreenPos; destinationRectangle.y = yScreenPos;

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 1);

destinationRectangle.x -= (temp2->w / 2); destinationRectangle.y -=
(temp2->h / 2);

SDL_BlitSurface(temp2, NULL, Screen, &destinationRectangle);
}

Hi the above Class function centers properly the new scaled and/or
rotated BMP 100%.

Problem now is that is crashes after a set period of time
(Access Violation error)

Rotozoom is normally not optimized for only the fly
blitting. It works okay will small surfaces, but when
you have the memory it is better to rotate all the surfaces
before you need them in the init routine.

Another + for this is you can use SDL_DisplayFormat
to get the fastest possible blitting and you can use the RLE Flag.

I would do it that way :

For example SDL_Surface *mainShipSprite [360];
Load it with all rotated surfaces with degrees from 0-360.
If you need less, you can just use the angles you need.
Then when blitting do SDL_Blit … mainShipSprite [angle % 360] …

That way you can directly blit with the wanted angle.

The problem in your case maybe that rotozoom always creates
new Surfaces and you never free them.

CU

Hi,

I need on-the-fly BMP rotation and scaling, the memory requirements to store
pre-processed rotations/scaling is TOO LARGE.

wizard at syntheticsw.com writes:
The problem in your case maybe that rotozoom always creates
new Surfaces and you never free them.

  • How do I FREE an SDL surface? (probably stupid question, but I do not know
    the answer)

Jesse
SLNTHERO at AOL.com (mailto:SLNTHERO at AOL.com)
www.SilentHeroProductions.com (http://www.SilentHeroProductions.com)

In a message dated 9/2/2006 10:41:32 A.M. Eastern Standard Time,
wizard at syntheticsw.com writes:

Hello !

void Visuals::DisplayBMPonScreenBufferRotoZoom(Sint8 spriteNumber, Sint16
xScreenPos, Sint16 yScreenPos, double angle, double zoom) {
SDL_Rect destinationRectangle;

destinationRectangle.x = xScreenPos; destinationRectangle.y = yScreenPos;

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 1);

destinationRectangle.x -= (temp2->w / 2); destinationRectangle.y -=
(temp2->h / 2);

SDL_BlitSurface(temp2, NULL, Screen, &destinationRectangle);
}

Hi the above Class function centers properly the new scaled and/or
rotated BMP 100%.

Problem now is that is crashes after a set period of time
(Access Violation error)

Rotozoom is normally not optimized for only the fly
blitting. It works okay will small surfaces, but when
you have the memory it is better to rotate all the surfaces
before you need them in the init routine.

Another + for this is you can use SDL_DisplayFormat
to get the fastest possible blitting and you can use the RLE Flag.

I would do it that way :

For example SDL_Surface *mainShipSprite [360];
Load it with all rotated surfaces with degrees from 0-360.
If you need less, you can just use the angles you need.
Then when blitting do SDL_Blit … mainShipSprite [angle % 360] …

That way you can directly blit with the wanted angle.

The problem in your case maybe that rotozoom always creates
new Surfaces and you never free them.

CU_______________________________________________
SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Hello !

I need on-the-fly BMP rotation and scaling, the memory requirements to
store pre-processed rotations/scaling is TOO LARGE.

@Torsten_Giebl writes: The problem in your case maybe that
rotozoom always creates new Surfaces and you never free them.

  • How do I FREE an SDL surface? (probably stupid question, but I do not
    know the answer)

Look at :

http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fFreeSurface

CU

void Visuals::DisplayBMPonScreenBufferRotoZoom(Sint8 spriteNumber, Sint16
xScreenPos, Sint16 yScreenPos, double angle, double zoom)
{
SDL_Rect destinationRectangle;

destinationRectangle.x = xScreenPos;
destinationRectangle.y = yScreenPos;

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 0);

temp->clip_rect.x = 0;
temp->clip_rect.y = 0;
temp->clip_rect.w = 640;
temp->clip_rect.h = 480;

temp2->clip_rect.x = 0;
temp2->clip_rect.y = 0;
temp2->clip_rect.w = 640;
temp2->clip_rect.h = 480;

destinationRectangle.w = temp2->w;
destinationRectangle.h = temp2->h;

destinationRectangle.x -= (temp2->w / 2);
destinationRectangle.y -= (temp2->h / 2);

SDL_BlitSurface(temp2, NULL, Screen, &destinationRectangle);

SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
}

Above compiles and runs, but crashes on 2nd call - any ideas ?

Jesse
SLNTHERO at AOL.com (mailto:SLNTHERO at AOL.com)
www.SilentHeroProductions.com (http://www.SilentHeroProductions.com)

In a message dated 9/2/2006 11:21:59 A.M. Eastern Standard Time,
wizard at syntheticsw.com writes:

Hello !

I need on-the-fly BMP rotation and scaling, the memory requirements to
store pre-processed rotations/scaling is TOO LARGE.

wizard at syntheticsw.com writes: The problem in your case maybe that
rotozoom always creates new Surfaces and you never free them.

  • How do I FREE an SDL surface? (probably stupid question, but I do not
    know the answer)

Look at :

http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fFreeSurface

CU_______________________________________________
SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 0);
[…]
SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
}

Maybe you’re freeing the source frames from SpriteBMP a bit early?

Don’t free it if you don’t own it.On Sat, 02 Sep 2006 17:26:42 +0200, wrote:

Hello !

void Visuals::DisplayBMPonScreenBufferRotoZoom(Sint8 spriteNumber, Sint16
xScreenPos, Sint16 yScreenPos, double angle, double zoom) {
SDL_Rect destinationRectangle;

destinationRectangle.x = xScreenPos; destinationRectangle.y = yScreenPos;

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 0);

temp->clip_rect.x = 0; temp->clip_rect.y = 0; temp->clip_rect.w = 640;
temp->clip_rect.h = 480;

temp2->clip_rect.x = 0; temp2->clip_rect.y = 0; temp2->clip_rect.w = 640;
temp2->clip_rect.h = 480;

destinationRectangle.w = temp2->w; destinationRectangle.h = temp2->h;

destinationRectangle.x -= (temp2->w / 2); destinationRectangle.y -=
(temp2->h / 2);

SDL_BlitSurface(temp2, NULL, Screen, &destinationRectangle);

SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
}

Above compiles and runs, but crashes on 2nd call - any ideas ?

Yup, SDL_FreeSurface (temp) does delete
your original surface, as

SDL_Surface *temp = SpriteBMP[spriteNumber];

does not copy the original surface from SpriteBMP [spriteNumber]
into temp, it just sets temp with the reference to SpriteBMP …

Then the first time you free the original surface and
the 2nd time try to rotate a NULL surface.

CU

In a message dated 9/2/2006 12:22:30 P.M. Eastern Standard Time,
wizard at syntheticsw.com writes:

SDL_Surface *temp = SpriteBMP[spriteNumber];

does not copy the original surface from SpriteBMP [spriteNumber]
into temp, it just sets temp with the reference to SpriteBMP …

Then the first time you free the original surface and
the 2nd time try to rotate a NULL surface.

Hi, how i fix above problem ? thanks I am alttle stupid and really need
help with this!

Jesse
SLNTHERO at AOL.com (mailto:SLNTHERO at AOL.com)
www.SilentHeroProductions.com (http://www.SilentHeroProductions.com)

Hello !

In a message dated 9/2/2006 12:22:30 P.M. Eastern Standard Time,
@Torsten_Giebl writes:

SDL_Surface *temp = SpriteBMP[spriteNumber];

does not copy the original surface from SpriteBMP [spriteNumber] into
temp, it just sets temp with the reference to SpriteBMP …

Then the first time you free the original surface and
the 2nd time try to rotate a NULL surface.

Hi, how i fix above problem ? thanks I am alttle stupid and really need
help with this!

Just delete the line with SDL_FreeSurface (temp) in your function.
I do not know how big your coding background is,
if SDL is just a new API to learn for you or if this
is your first programm in C/C++ or your first programm ever.

So maybe if you have problems to understand this pointer stuff
try to get a good book about C programming.

CU

MORE INFORMATION FROM TESTING:

game crashes ONLY when the new RotoZoomed BMP is NOT completely on screen
(ie: entire BMP does not fit completely in SDL screen w,h)

any thoughts ?

void Visuals::DisplayBMPonScreenBufferRotoZoom(Sint8 spriteNumber, Sint16
xScreenPos, Sint16 yScreenPos, double angle, double zoom)
{
SDL_Rect destinationRectangle;

destinationRectangle.x = xScreenPos;
destinationRectangle.y = yScreenPos;

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 0);

temp->clip_rect.x = 0;
temp->clip_rect.y = 0;
temp->clip_rect.w = 640;
temp->clip_rect.h = 480;

temp2->clip_rect.x = 0;
temp2->clip_rect.y = 0;
temp2->clip_rect.w = 640;
temp2->clip_rect.h = 480;

destinationRectangle.w = temp2->w;
destinationRectangle.h = temp2->h;

destinationRectangle.x -= (temp2->w / 2);
destinationRectangle.y -= (temp2->h / 2);

SDL_BlitSurface(temp2, NULL, Screen, &destinationRectangle);

// SDL_FreeSurface(temp);
// SDL_FreeSurface(temp2);

JeZ+Lee
SLNTHERO at AOL.com (mailto:SLNTHERO at AOL.com)
www.SilentHeroProductions.com (http://www.SilentHeroProductions.com)

[…]

void Visuals::DisplayBMPonScreenBufferRotoZoom(Sint8 spriteNumber,
Sint16 xScreenPos, Sint16 yScreenPos,
double angle, double zoom)
{
SDL_Rect destinationRectangle;

destinationRectangle.x = xScreenPos;
destinationRectangle.y = yScreenPos;

SDL_Surface *temp = SpriteBMP[spriteNumber];
SDL_Surface *temp2 = rotozoomSurface(temp, angle, zoom, 0);

I don’t think you’re supposed to mess directly with the clip rects…
(Use SDL_SetClipRect().) Also, the clip rect is automatically set to
the full size of a surface when it’s created, so unless you want to
restrict rendering to a smaller rectangle, you don’t need to touch
this at all.

Either way, clip_rect is for blits to a surface. That is, if you
want to clip when rendering to the display, you should use
SDL_SetClipRect() on the display surface.

temp->clip_rect.x = 0;
temp->clip_rect.y = 0;
temp->clip_rect.w = 640;
temp->clip_rect.h = 480;

temp2->clip_rect.x = 0;
temp2->clip_rect.y = 0;
temp2->clip_rect.w = 640;
temp2->clip_rect.h = 480;

No need for these two as SDL_BlitSurface() ignores the size of the
destination rectangle anyway.

Only x and y are used. Also note that SDL_BlitSurface() will overwrite
destinationRectangle with the resulting rect after clipping! This is
important to keep in mind if you’re doing multiple blits in sequence,
reusing variables and stuff.

destinationRectangle.w = temp2->w;
destinationRectangle.h = temp2->h;

destinationRectangle.x -= (temp2->w / 2);
destinationRectangle.y -= (temp2->h / 2);

SDL_BlitSurface(temp2, NULL, Screen, &destinationRectangle);

// SDL_FreeSurface(temp);
// SDL_FreeSurface(temp2);

You should still free temp2, I think! (rotozoomSurface() creates a new
surface, right?)

Didn’t spot any obvious reason for crashing, though. What does the
debugger say? Where exactly does the crash happen?

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Saturday 02 September 2006 18:39, SlntHero at aol.com wrote: