Re: Under SDL2, how to 3D rotate a image?
T. Joseph Carter <tjcarter <at> spiritsubstance.com>
2015-07-30 08:06:56 GMT
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. :) 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. :) That means weighted averaging more pixels. And you'll probably discover quickly why old
games did their rotation in hops rather that smooth steps. :)
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. ;)
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
Sent 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. ^ ^
> SDL mailing list
> SDL <at> lists.libsdl.org
SDL mailing list
SDL <at> lists.libsdl.org