Under SDL2, how to 3D rotate a image?

3D rotate a image, but not 2D. Just like the attachment image.
Thanks. ^ ^
-------------- next part --------------
A non-text attachment was scrubbed…
Name: 3d_rotate.png
Type: application/octet-stream
Size: 23274 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20150730/347e6d0c/attachment-0001.obj

[/img]

This requires a perspective correct 3D transform for proper results,
which AFAIK, is clearly out of scope for the SDL 2D API. Thus, the
general answer would be “use OpenGL.” (SDL can set up and manage
OpenGL contexts. You only deal with the actual draw calls.)

If this is a special effect for a “retro” 2D game, it might be more
appropriate to implement it in software (see
SDL_TEXTUREACCESS_STREAMING), but of course, that’s a lot more
involved, and even more so if it’s performance critical.On Thu, Jul 30, 2015 at 5:02 AM, Nemo3773 <377307289 at qq.com> wrote:


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’

Stuff like that isn’t part of SDL per se. If you’re using OpenGL, you’d follow any number of basic tutorials on model transformations, with your model being a single flat quad (2 triangles).

If not, the way to do it is to do it yourself. And even if you decide to go the OpenGL route, I recommend you do it this way just so you understand OpenGL a little more. Create a streaming texture about 40% taller than your sample image and fill the top and bottom 20% with transparency. Draw your image in the middle and put it on the screen where you want it. (Remember to offset your Y axis by the extra 20%! Also save the surface you loaded the image into for the next step.)

Now modify your program to run a loop with a delay. Each iteration, you’ll “rotate” your texture. We’ll approach that in two separate steps and a few sub-steps.

First let’s give the illusion of distance. You’re going to lerp (linear[ly] interpolate) the column pixels to do that. For this example you’ll only be working with at most three pixels (possibly at most two) at a time and you can find formulas for it easily enough online. Basically you need to know your scale factor (at most 140%) and to figure out how much of any two pixels goes into any one pixel.

You may see weighting described as multiplying each component of a pixel by a fraction representing how much of it is in the pixel. Have your loop stretch and unstretch your image, say in 4 stages with a SDL_Delay(200) between each iteration. Not very fluid but it’ll move slow enough for you to see if there’s a noticeable delay in your scale routine and stay on screen for you to see the results.

Then go modify your scaler routine to shrink by 20% (but save your logic for the increase!)

Now modify it so it goes from squishing the image to stretching it. :slight_smile: You should be able to modify your logic so it will just scale a column up or down based on a single scale factor.

Ready to start making it rotate? To do that we first need to be able to linearly scale our scale factor. If we’re scaling an image by 5% on the left edge, we scale by -5% on the right. That means for a 100px wide image, column 0 is 105%. Column 1 is 104.9%. You should now be able to make it go from 100% to 120% then down to 80% and back to 100% on the left and the opposite direction on the right. It should still look like it’s being stretched (and it is), but you should start to get the sense of rotation being a thing.

Last step and it’s a big one. You’ve learned to lerp your columns in choppy jumps so you could see what you’re doing. Now make it happen in two dimensions around your rotation axis?except it always gets smaller on the X axis the further you get from 100%. How much smaller? Well, 120% and 80% on the vertical are 0% on the horizontal. :slight_smile: That means weighted averaging more pixels. And you’ll probably discover quickly why old games did their rotation in hops rather that smooth steps. :slight_smile:

By the way, cosine starts at 1 and drops to 0 at 90 degrees and -1 at 180, then back. If you calculate your rotation angle in radians, you can use cosine to tell you your horizontal scale (absolute value) and whether to draw the front of the image or the back (sign). From that you can calculate your vertical stretch extremes on a linear scale of 80% to 120% based in both magnitude and sign.

A common speed enhancement is for programmers to use sine/cosine tables with precalculated values based on rotation in steps. Common step values used in games are 8, 16, 256, and the not very round number of 360 for some reason. :wink:

Hope that gets you thinking. FWIW, the column-stretch for distance? That’s how Wolfenstein 3D works. They used sprites for bad guys drawn from different angles for everything but walls. That FWIW is why there are no stairs in Wolf3D, all walls are the same size and uniform so all you have to do is figure out your distance to the wall for each column. Floor and ceiling are a solid color, so you need only then stretch the wall texture accordingly.

JosephSent via mobile

On Jul 29, 2015, at 19:30, Nemo <377307289 at qq.com> wrote:

3D rotate a image, but not 2D. Just like the attachment image.
Thanks. ^ ^
<3d_rotate.png>


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org