Any idea on how to rotate sprites?
-
- Enthusiast
- Posts: 767
- Joined: Sat Jan 24, 2004 6:56 pm
Any idea on how to rotate sprites?
Hi Group,
I'd like to know whether it is possible to rotate sprites - fast....
For a small project of mine, I'd like to create an instrument dial face, that has multiple objects that need to be animated (rotated, moved, etc). Can this be done with sprites?
I know this forum has multiple entries about rotating a sprite, but non of these seem to be geared towards fast real-time rotation...
I wouldn't like to use the larger 3D lib for something that is essentially 2D, that's why I thought about using sprites for this.
I'd like to know whether it is possible to rotate sprites - fast....
For a small project of mine, I'd like to create an instrument dial face, that has multiple objects that need to be animated (rotated, moved, etc). Can this be done with sprites?
I know this forum has multiple entries about rotating a sprite, but non of these seem to be geared towards fast real-time rotation...
I wouldn't like to use the larger 3D lib for something that is essentially 2D, that's why I thought about using sprites for this.
Aha!
This is pure 2D, and you're using sprites right?
In that case, no code will be fast enough for rotating your dials in realtime. Instead, you should rotate them only once with your prefered rotation routine, save the results and show the results when needed Smile
Hope the "lookup table" idea shines your lamp..
Sure, you'll be using much more memory this way, but the processing is cut to a single sprite display. Thats what you're looking for right? speed!.
If you want an example just ask. It's pretty easy though.
1) Load the sprite
2) In a routine, take the amount of rotations you'll want and calculate the angle of rotation between frame and frame.
3) Rotate the sprite, keeping each handle in an array.
4) Whenever you need to rotate the sprite, call the appropiate sprite handle at the rotation array.
Really, this is no PB fault, you'll want to take the same aproach for "real" (let's call 'em "Pure") 2D games as well.
So, cheers!.
In that case, no code will be fast enough for rotating your dials in realtime. Instead, you should rotate them only once with your prefered rotation routine, save the results and show the results when needed Smile
Hope the "lookup table" idea shines your lamp..
Sure, you'll be using much more memory this way, but the processing is cut to a single sprite display. Thats what you're looking for right? speed!.
If you want an example just ask. It's pretty easy though.
1) Load the sprite
2) In a routine, take the amount of rotations you'll want and calculate the angle of rotation between frame and frame.
3) Rotate the sprite, keeping each handle in an array.
4) Whenever you need to rotate the sprite, call the appropiate sprite handle at the rotation array.
Really, this is no PB fault, you'll want to take the same aproach for "real" (let's call 'em "Pure") 2D games as well.
So, cheers!.
I do almost all of my graphics with OpenGL. So I can't comment on the speed of PB (3D)Sprites. But as I don't how much speed you need, it wouldn't help me anyway.
What about this:
Write Procedures that handle your Graphics stuff and hide the way they do it from the rest of your Program. So you would be able to develop your program fast with 3D-Sprites, and maybe switch to OpenGL if they are to slow, without changing the Rest of your code.
Good luck,
Hades
Edit: I was too slow. dagcracks method is always possible.
What about this:
Write Procedures that handle your Graphics stuff and hide the way they do it from the rest of your Program. So you would be able to develop your program fast with 3D-Sprites, and maybe switch to OpenGL if they are to slow, without changing the Rest of your code.
Good luck,
Hades
Edit: I was too slow. dagcracks method is always possible.
-
- Enthusiast
- Posts: 767
- Joined: Sat Jan 24, 2004 6:56 pm
Re: Aha!
This is exactly what Krylar wrote in one of his entries.... Thanks for the thumbs up!dagcrack wrote:This is pure 2D, and you're using sprites right?
In that case, no code will be fast enough for rotating your dials in realtime. Instead, you should rotate them only once with your prefered rotation routine, save the results and show the results when needed Smile
Hope the "lookup table" idea shines your lamp..
-
- Enthusiast
- Posts: 767
- Joined: Sat Jan 24, 2004 6:56 pm
Splitting it up in modules is what I had in mind already, because one day, it perhaps needs to run on a (tiny) Linux board....Hades wrote:I do almost all of my graphics with OpenGL. So I can't comment on the speed of PB (3D)Sprites. But as I don't how much speed you need, it wouldn't help me anyway.
What about this:
Write Procedures that handle your Graphics stuff and hide the way they do it from the rest of your Program. So you would be able to develop your program fast with 3D-Sprites, and maybe switch to OpenGL if they are to slow, without changing the Rest of your code.
Good luck,
Hades
Edit: I was too slow. dagcracks method is always possible.
Thanks
Last edited by dell_jockey on Fri Apr 07, 2006 11:36 am, edited 1 time in total.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Ok, I mocked up a little something, is this the kind of thing you're going for?
Here's the built program, you can just run it:
http://www.networkmaestro.com/dials.exe
or, if you want to build it yourself, you need these 2 images:
http://www.networkmaestro.com/dial.bmp
http://www.networkmaestro.com/needle.bmp
Then run this:
It's not great quality, but if I could draw or program, it would be better.
Here's the built program, you can just run it:
http://www.networkmaestro.com/dials.exe
or, if you want to build it yourself, you need these 2 images:
http://www.networkmaestro.com/dial.bmp
http://www.networkmaestro.com/needle.bmp
Then run this:
Code: Select all
InitSprite():InitSprite3D():InitMouse()
OpenWindow(0,0,0,768,177,"Dial Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0,768,177,0,0,0)
LoadSprite(10,"dial.bmp")
LoadSprite(11,"dial.bmp")
LoadSprite(12,"dial.bmp")
LoadSprite(13,"dial.bmp")
LoadSprite(1,"needle.bmp",#PB_Sprite_Texture)
CopySprite(1,2)
CopySprite(2,3)
CopySprite(3,4)
TransparentSpriteColor(1,RGB(70,30,110))
CreateSprite3D(1,1)
CreateSprite3D(2,1)
CreateSprite3D(3,1)
CreateSprite3D(4,1)
Sprite3DQuality(1)
forward0=#True
forward1=#True
forward2=#True
forward3=#True
Repeat
ev=WaitWindowEvent(1)
DisplaySprite(10,0,0)
DisplaySprite(11,192,0)
DisplaySprite(12,2*192,0)
DisplaySprite(13,3*192,0)
Start3D()
n0=1
n1=2
n2=3
n3=4
If forward0
RotateSprite3D(1,n0,1)
t0+n0
If t0>=270
forward0=#False
EndIf
Else
RotateSprite3D(1,0-n0,1)
t0-n0
If t0<=0
forward0=#True
EndIf
EndIf
If forward1
RotateSprite3D(2,n1,1)
t1+n1
If t1>=270
forward1=#False
EndIf
Else
RotateSprite3D(2,0-n1,1)
t1-n1
If t1<=1
forward1=#True
EndIf
EndIf
If forward2
RotateSprite3D(3,n2,1)
t2+n2
If t2>=270
forward2=#False
EndIf
Else
RotateSprite3D(3,0-n2,1)
t2-n2
If t2<=0
forward2=#True
EndIf
EndIf
If forward3
RotateSprite3D(4,n3,1)
t3+n3
If t3>=270
forward3=#False
EndIf
Else
RotateSprite3D(4,0-n3,1)
t3-n3
If t3<=0
forward3=#True
EndIf
EndIf
DisplaySprite3D(1,31,25)
DisplaySprite3D(2,192+31,25)
DisplaySprite3D(3,192*2+31,25)
DisplaySprite3D(4,192*3+31,25)
Stop3D()
FlipBuffers()
Until ev=#PB_Event_CloseWindow
BERESHEIT
-
- Enthusiast
- Posts: 767
- Joined: Sat Jan 24, 2004 6:56 pm
Netmaestro,netmaestro wrote:It's not great quality, but if I could draw or program, it would be better.
you're being way too modest here. I like you example a lot! Thanks for sharing it, very eductional.
What I intend to create is what is called an EFIS... In programming terms you can thinks about it as a dial face that dispays multiple layers of sprites, each one of them conveying a certain information snippet. Large parts of each of these layered sprites (with the exception of the rear one) will be transparent.
EFISes come in many flavors, one of them can be seen here: http://www.interavionics.com/rockwell-c ... S-4xxx.jpg Another type of EFIS is shown here: http://www.b737.org.uk/pfd.jpg
An example of a somewhat more complete panel: http://www.janholmberg.se/airbus-panel.jpg
Thanks again!
P.S. what would I want to do with an EFIS? Check out my sig

Of course, initially I'll only be using a simulator (UDP data packets from X-Plane) for data input...
Last edited by dell_jockey on Mon Apr 10, 2006 8:25 am, edited 3 times in total.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
-
- Enthusiast
- Posts: 767
- Joined: Sat Jan 24, 2004 6:56 pm
You might be right, but it will not be because of an EFIS....netmaestro wrote:Yeeks that makes me shudder. You're gonna kill yourself in that thing!
Do you want to know some shocking facts?
- all pilots end up dead!
- so do chess players, stamp collectors and of course dairy farmers!
Why not have a bit of fun before the final touch-down?

Last edited by dell_jockey on Thu Dec 28, 2006 9:34 pm, edited 1 time in total.
-
- Enthusiast
- Posts: 767
- Joined: Sat Jan 24, 2004 6:56 pm
Netmaestro,
after playing around with your code, I have the following comments:
- Start3D() and Stop3D() can be located outside of the REPEAT-UNTIL loop
- Since you set a transparent color for the needle bitmap, I was a bit surprised that the background bitmap needs to be redrawn within the loop. Obviously, what is ultimately displayed is but a single canvas, no layering involved?
- I doubled the number of dial faces, to test how this would influence processor usage. With the original 4 dial faces, the program took some 27-29% on average. I was surprised to find that doubling everything only increased processor usage to 29-33%
EDIT:
The processor load percentages quoted above were measured on a non-HT 2.0GHz notebook.
On a HT 3.0 GhHz desktop, processor load dropped to 4-5%....
bye
after playing around with your code, I have the following comments:
- Start3D() and Stop3D() can be located outside of the REPEAT-UNTIL loop
- Since you set a transparent color for the needle bitmap, I was a bit surprised that the background bitmap needs to be redrawn within the loop. Obviously, what is ultimately displayed is but a single canvas, no layering involved?
- I doubled the number of dial faces, to test how this would influence processor usage. With the original 4 dial faces, the program took some 27-29% on average. I was surprised to find that doubling everything only increased processor usage to 29-33%
EDIT:
The processor load percentages quoted above were measured on a non-HT 2.0GHz notebook.
On a HT 3.0 GhHz desktop, processor load dropped to 4-5%....

bye
-
- Addict
- Posts: 1648
- Joined: Mon Sep 20, 2004 3:52 pm
- Contact:
You're basically looking for some very fast matrix transformation. You can go the pre-processed way but not really for what it looks like you want to do. The way you could really do it is draw the sprite yourself using Line() etc. Have the actual graphic be a sprite then draw the lines at the correct angle over the sprite.
If you really need to rotate the entire sprite then you should just do a lookup on google for matrix transformation and see if it could be implemented to apply to pb sprites.
If you really need to rotate the entire sprite then you should just do a lookup on google for matrix transformation and see if it could be implemented to apply to pb sprites.
-
- Enthusiast
- Posts: 767
- Joined: Sat Jan 24, 2004 6:56 pm
I know about 4x4 matrix manipulation to rotate/shift/translate 3D-coordination in one go. (Long ago I've done this stuff on TurboPascal.) Actually, I'd be manipulating the outside coordinates that define the object and the object proper still needs to be drawn.
Internally, this is what OpenGL/DirectX do with 3D objects, so I reckon that Dagcrack is right that I need some sort of accelleration. OpenGL would indeed be my favorite, as this is available on all platforms that PB can address.
Although the objects that need to be displayed are presented in 2D, conceptually they are independently displayed on transparent canvasses on top of each other. Perhaps going the 3D route to display 2D object might still be a valid aproach, as displaying overlapping objects would be taken care of automatically.
There only one drawback: I HAVEN'T THE FOGGIEST ABOUT OPENGL NOR ABOUT DIRECTX. Oh, well, time to purchase yet some more books...
Internally, this is what OpenGL/DirectX do with 3D objects, so I reckon that Dagcrack is right that I need some sort of accelleration. OpenGL would indeed be my favorite, as this is available on all platforms that PB can address.
Although the objects that need to be displayed are presented in 2D, conceptually they are independently displayed on transparent canvasses on top of each other. Perhaps going the 3D route to display 2D object might still be a valid aproach, as displaying overlapping objects would be taken care of automatically.
There only one drawback: I HAVEN'T THE FOGGIEST ABOUT OPENGL NOR ABOUT DIRECTX. Oh, well, time to purchase yet some more books...
Last edited by dell_jockey on Tue Apr 11, 2006 12:01 pm, edited 2 times in total.