Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BlackBerry - image 3D transform

I know how to rotate image on any angle with drawTexturePath:

int displayWidth = Display.getWidth();
int displayHeight = Display.getHeight();
int[] x = new int[] { 0, displayWidth, displayWidth, 0 };
int[] x = new int[] { 0, 0, displayHeight, displayHeight };
int angle = Fixed32.toFP( 45 );
int dux = Fixed32.cosd(angle );
int dvx = -Fixed32.sind( angle );
int duy = Fixed32.sind( angle );         
int dvy = Fixed32.cosd( angle );       
graphics.drawTexturedPath( x, y, null, null, 0, 0, dvx, dux, dvy, duy, image);

but what I need is a 3d projection of simple image with 3d transformation (something like this)

Can you please advice me how to do this with drawTexturedPath (I'm almost sure it's possible)?
Are there any alternatives?

like image 769
Maksym Gontar Avatar asked May 31 '26 13:05

Maksym Gontar


2 Answers

The method used by this function(2 walk vectors) is the same as the oldskool coding tricks used for the famous 'rotozoomer' effect. rotozoomer example video

This method is a very fast way to rotate, zoom, and skew an image. The rotation is done simply by rotating the walk vectors. The zooming is done simply by scaling the walk vectors. The skewing is done by rotating the walkvectors in respect to one another (e.g. they don't make a 90 degree angle anymore).

Nintendo had made hardware in their SNES to use the same effect on any of the sprites and or backgrounds. This made way for some very cool effects.

One big shortcoming of this technique is that one can not perspectively warp a texture. To do this, every new horizontal line, the walk vectors should be changed slightly. (hard to explain without a drawing).

On the snes they overcame this by altering every scanline the walkvectors (In those days one could set an interrupt when the monitor was drawing any scanline). This mode was later referred to as MODE 7 (since it behaved like a new virtual kind of graphics mode). The most famous games using this mode were Mario kart and F-zero

So to get this working on the blackberry, you'll have to draw your image "displayHeight" times (e.g. Every time one scanline of the image). This is the only way to achieve the desired effect. (This will undoubtedly cost you a performance hit since you are now calling the drawTexturedPath function a lot of times with new values, instead of just one time).

I guess with a bit of googling you can find some formulas (or even an implementation) how to calc the varying walkvectors. With a bit of paper (given your not too bad at math) you might deduce it yourself too. I've done it myself too when I was making games for the Gameboy Advance so I know it can be done.

Be sure to precalc everything! Speed is everything (especially on slow machines like phones)

EDIT: did some googling for you. Here's a detailed explanation how to create the mode7 effect. This will help you achieve the same with the Blackberry function. Mode 7 implementation

like image 135
Toad Avatar answered Jun 03 '26 01:06

Toad


With the following code you can skew your image and get a perspective like effect:

        int displayWidth = Display.getWidth();
        int displayHeight = Display.getHeight();
        int[] x = new int[] { 0, displayWidth, displayWidth, 0 };
        int[] y = new int[] { 0, 0, displayHeight, displayHeight };                

        int dux = Fixed32.toFP(-1);
        int dvx = Fixed32.toFP(1);
        int duy = Fixed32.toFP(1);
        int dvy = Fixed32.toFP(0);
        graphics.drawTexturedPath( x, y, null, null, 0, 0, dvx, dux, dvy, duy, image);

This will skew your image in a 45º angle, if you want a certain angle you just need to use some trigonometry to determine the lengths of your vectors.

like image 37
Lucas S. Avatar answered Jun 03 '26 03:06

Lucas S.