Jump to content
  • Advertisement
Sign in to follow this  
popcorn

Sprite Rotation

This topic is 2995 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

I am looking at how I could possibly rotate the following sprite by about 20 degrees. The width is 60 pixels and the height is 50 pixels.



I am using SDL.

The following apply.
1. I cannot use openGL.
2. I cannot use SDL_gfx.
3. I cannot use a paint package to rotate the image.

How would I do this?

[Edited by - popcorn on July 7, 2010 6:31:29 PM]

Share this post


Link to post
Share on other sites
Advertisement
tilt your monitor 20 degrees. Why are you restricted from using tools that were built to help you do such things?

Share this post


Link to post
Share on other sites
Denzin, I forgot:

4. You cannot tilt your monitor :)

The reason is I want to understand the theory behind this and how to program this. From searches here and on google what I've mentioned are always the most common answers.

Share this post


Link to post
Share on other sites
Well I managed to do this:


Can't say it was my own work though, this article is where all the code really came from so credit to the people involved. Rotating a bitmap with an angle of any value.

The code examples are written for windows but I managed to convert it to SDL.

Heres my code in case anyone is interested:


#include "SDL.h"
#include "SDL_ttf.h"
#include <iostream>
#include <cmath>

using namespace std;

#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
return *p;

case 2:
return *(Uint16 *)p;

case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;

case 4:
return *(Uint32 *)p;

default:
return 0; /* shouldn't happen, but avoids warnings */
}
}

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
*p = pixel;
break;

case 2:
*(Uint16 *)p = pixel;
break;

case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;

case 4:
*(Uint32 *)p = pixel;
break;
}
}

SDL_Surface *createSurface(int width, int height)
{
SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0);

return surface;
}

int main( int argc, char* args[] )
{
//Start SDL
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface *screen = NULL;
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
SDL_WM_SetCaption("SDL Rotation Test", NULL);

SDL_Event event;
bool quit = false;

SDL_Surface *surface = createSurface(60, 50);
SDL_Surface *temp = NULL;
temp = SDL_LoadBMP("disasteroids2_master.bmp");

SDL_Rect userClip;
userClip.x = 448;
userClip.y = 295;
userClip.w = 60;
userClip.h = 50;

SDL_BlitSurface(temp, &userClip, surface, NULL);
SDL_FillRect(screen, NULL, SDL_MapRGB(SDL_GetVideoSurface()->format, 75, 150, 255));

int angle = 45;
float radians=(2*3.1416*angle)/360;

float cosine=(float)cos(radians);
float sine=(float)sin(radians);

float Point1x=(-surface->h*sine);
float Point1y=(surface->h*cosine);
float Point2x=(surface->w*cosine-surface->h*sine);
float Point2y=(surface->h*cosine+surface->w*sine);
float Point3x=(surface->w*cosine);
float Point3y=(surface->w*sine);

float minx=min(0,min(Point1x,min(Point2x,Point3x)));
float miny=min(0,min(Point1y,min(Point2y,Point3y)));
float maxx=max(Point1x,max(Point2x,Point3x));
float maxy=max(Point1y,max(Point2y,Point3y));

int DestBitmapWidth=(int)ceil(fabs(maxx)-minx);
int DestBitmapHeight=(int)ceil(fabs(maxy)-miny);

SDL_Surface *rotate = createSurface(DestBitmapWidth, DestBitmapHeight);

cout << "Angle: " << angle << endl;
cout << "Surface width: " << rotate->w << endl;
cout << "Surface height: " << rotate->h << endl;

Uint32 pixel;

for(int x=0;x<DestBitmapWidth;x++)
{
for(int y=0;y<DestBitmapHeight;y++)
{
int SrcBitmapx=(int)((x+minx)*cosine+(y+miny)*sine);
int SrcBitmapy=(int)((y+miny)*cosine-(x+minx)*sine);
if(SrcBitmapx >= 0 && SrcBitmapx < surface->w && SrcBitmapy >= 0 && SrcBitmapy < surface->h)
{
pixel = getpixel(surface, SrcBitmapx, SrcBitmapy);
putpixel(rotate, x, y, pixel);
}
}
}

SDL_BlitSurface(rotate, NULL, screen, NULL);
SDL_Flip(screen);

while(!quit)
{
while(SDL_PollEvent(&event))
{

if(event.type == SDL_QUIT)
{
quit = true;
}
}
}
SDL_FreeSurface(temp);
SDL_FreeSurface(surface);
SDL_FreeSurface(rotate);
//Quit SDL
SDL_Quit();

return 0;
}





I can only guess that it is related to the rotation matrix stuff that Concentrate links to in his post. I will need to take some time to see if I can really understand whats going on here....

Does anyone know if it is related to the rotation matrix stuff pointed out by Concentrate?

[Edited by - popcorn on July 8, 2010 12:23:22 AM]

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!