Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Scavenger on Wed 03/11/2010 00:06:29

Title: Pseudo-3D rendering (line based)
Post by: Scavenger on Wed 03/11/2010 00:06:29
I've been working on another part of my game, and I want to create a Mode-7 type effect for a driving sequence in the game.

Unfortunately, I'm not actually that good at maths, so the render ends up looking like this:

(http://img146.imageshack.us/img146/9596/warpedroad.png)

My code is:
// room script file
DynamicSprite *roadspr;
DynamicSprite *camera;
DynamicSprite *tmpline;
int charposx = 149, charposy = 1382;
int viewwidth = 128;
int viewangle;

function room_Load()
{
 Mouse.SetBounds (131, 50, 165, 52);
SetViewport (0, 0);
}

function repeatedly_execute_always ()
{
SetViewport (0, 0);
charposx = mouse.x;
if (charposy > (viewwidth>>1) + 1) charposy-=2;
else charposy = 1400;
roadspr = DynamicSprite.CreateFromBackground ();
roadspr.Crop (charposx-viewwidth, charposy-viewwidth/2, viewwidth * 2, viewwidth);
int i;
camera = DynamicSprite.Create (320, viewwidth/2, false);
camera.ChangeCanvasSize (320, viewwidth, 0, 0);
DrawingSurface *surface = camera.GetDrawingSurface ();
while (i < viewwidth)
{
 tmpline = DynamicSprite.CreateFromExistingSprite (roadspr.Graphic, false);
 tmpline.Crop (i, i, (viewwidth * 2) - (i*2), 1);
 surface.DrawImage (0, i, tmpline.Graphic, 0, 320, 1);
 i++;
}
surface.Release ();
camera.Resize (320, 150);
oRoad.Graphic = camera.Graphic;



I know I'm probably supposed to put in a curve instead of a straight slope, but I can't for the life of me figure out how to do it. Can anyone lend a hand? I want to make the road much narrower when it goes away from the player, and the curve turn into a straight line.
Title: Re: Removing warping effect from rendered image
Post by: Gilbert on Wed 03/11/2010 08:32:44
That's mainly because the road is scaled (line-by-line) horizontally but it is not scaled in the vertical direction.

I haven't read your codes thoroughly, but to my understanding it's something like this (Behold my great M$Pain masterpiece :=):
(http://i488.photobucket.com/albums/rr249/gilbot/tiltroad.png)
What you do is the top one, but in fact to give a correct sense of perspective it should be something like the bottom one. Of course, what you're doing is a bit different as you scale horizontal strips 1 pixel tall for the effect, and in that case the correct behaviour would be something like skipping more and more lines of the source when the y-coordinate goes up (i.e. farther and farther away from the viewer) and even possibly repeating some of the lines at the bottom of the screen.

An alternative (and possibly easier) way of faking this is, if you don't care about the perspective issue that you don't need to scale in the vertical direction, you need to derive some formula for the original width of a strip at a certain y-position (to be scaled to 320 pixels) instead of your current linear one, so that the resultant road will look straight.

I don't have the time to check these atm but I may attempt if I have the time, or else some other wizards could help you solve this.
Title: Re: Removing warping effect from rendered image
Post by: GarageGothic on Wed 03/11/2010 09:32:02
I worked on a half-finished project with a similar effect and found some really good explanations of various pseudo-3D effects used in racing games on this website (http://www.gorenfeld.net/lou/pseudo/). Not sure it will help with your specific problem, but I found it very useful.
Title: Re: Removing warping effect from rendered image
Post by: abstauber on Wed 03/11/2010 10:00:02
Awesome! I always wanted to code something similar myself to create remake of TechnoCop http://www.lemonamiga.com/reviews/view.php?id=336

I desperately hope, your minigame finds it's way back as a module after you've released Disk2 ;)

Anyway, I did some research back then and here are the links.

RickJ started with something similar, called DemoCycle.
http://demo.agspace.ws/project/archive/DemoCycle-A0100.zip

Unfortunately it doesn't feature hills, curves or different roads.

For a nice mode7 effect, you should take a look at AGS3d, which does a beautiful job.
Title: Re: Removing warping effect from rendered image
Post by: Scavenger on Sat 06/11/2010 20:39:14
Quote from: GarageGothic on Wed 03/11/2010 09:32:02
I worked on a half-finished project with a similar effect and found some really good explanations of various pseudo-3D effects used in racing games on this website (http://www.gorenfeld.net/lou/pseudo/). Not sure it will help with your specific problem, but I found it very useful.

Man, this is exactly the kind of thing I was trying to emulate. I especially like the effect used in Street Fighter II, too. I'd love to use that effect. Very awesome.  It makes my head ache so badly, though. It's kind of like a simpler raycasted environment thingy - should be pretty fast on ags since it works on lines rather than pixels. (and the pre-rendered perspective texture is better than the forced-mode 7 I was using previously) I can visualise the effect in my head but I just can't program it. I've never been very good at 3D stuff. x3 But if I can make AGS render on the Z plane that would probably be enough. Perhaps the fault lay with me using a flat top down image and trying to stretch it out rather than an using an already rendered perspective image and narrowing it down/shifting it.


Quote from: abstauber on Wed 03/11/2010 10:00:02
I desperately hope, your minigame finds it's way back as a module after you've released Disk2 ;)
I plan to release all the non-game specific code alongside my game, so everyone can use the effects I used in my game. :)
Quote
Anyway, I did some research back then and here are the links.

RickJ started with something similar, called DemoCycle.
http://demo.agspace.ws/project/archive/DemoCycle-A0100.zip

Unfortunately it doesn't feature hills, curves or different roads.
I had a look at it. It's a really nice faked effect of a faked effect.  Had just about the gameplay I was looking for, but the road is a static animation. And the 2.72 code looks so clunky in comparison with 3.xes code now! I can't believe I held off learning 3.x so long.

Quote
For a nice mode7 effect, you should take a look at AGS3d, which does a beautiful job.

Unfortunately, that would require me to use a plugin, and as much as I'd like to put real 3D rendering in my game, I just don't feel like using a plugin for something like this is necessary. I want to tax AGS to it's limits using only the features presented in AGS.
Title: Re: Removing warping effect from rendered image
Post by: Kweepa on Sun 07/11/2010 03:45:39
Quote from: Scavenger on Sat 06/11/2010 20:39:14
Quote
For a nice mode7 effect, you should take a look at AGS3d, which does a beautiful job.
Unfortunately, that would require me to use a plugin
I think he meant to say Easy3d, which takes the room background and draws it in perspective with the objects and characters standing up like cardboard cutouts. Almost perfect for your needs! Search the tech forum for the module.

EDIT:
Quote from: Scavenger on Sat 06/11/2010 20:39:14
Perhaps the fault lay with me using a flat top down image and trying to stretch it out rather than an using an already rendered perspective image and narrowing it down/shifting it.
No, the reason that those games used the "perspective" image was that it's cheaper to have the road slice already scaled.
Title: Re: Pseudo-3D rendering (line based)
Post by: Kweepa on Sun 07/11/2010 17:39:49
I put together a small demo:

(http://www.kweepa.com/step/ags/tech/AGSPolePosition.png)

Here's the project (source & compiled):

http://www.kweepa.com/step/ags/tech/AGSPolePosition7Nov2010.zip

The meat is in RenderRoad:

function RenderRoad()
{
  // render a road (with a curve later)
  DrawingSurface *ds = Room.GetDrawingSurfaceForBackground();

  ds.DrawImage(0, 0, bg.Graphic);
  int i = FloatToInt(horizony) + 1;
  while (i < 200)
  {
    float fz = nearZ * (neary - horizony) / (IntToFloat(i) - horizony);
    float fw = roadwidth * (nearZ / fz);
    fz += zoff;
    fz = modFloat(fz, spriteZ[0], spriteZ[16]);
    // convert to sprite y
    int y = 150 - FloatToInt(horizony + nearZ * (neary - horizony) / fz);
    // clamp
    if (y >= 16) y = 15; else if (y < 0) y = 0;
   
    int w = FloatToInt(fw);
    int x = 160 - FloatToInt(fw / 2.0);
    ds.DrawImage(x, i, dsRoad[y].Graphic, 0, w, 1);
    i++;
  }
 
  ds.Release();
}


The "convert to sprite y" code you may not need - I have it here because the road texture is just 16 lines from the original photograph, so I need to undo the perspective projection in my road texture.
Title: Re: Pseudo-3D rendering (line based)
Post by: Dualnames on Sun 07/11/2010 17:45:14
Steve "TheMachine" McCrea!!

OMG, I wanted that kind of effect, but i thought it wasn't possible. I love you Steve!!! :D
Title: Re: Pseudo-3D rendering (line based)
Post by: Scavenger on Sun 07/11/2010 18:46:44
This is EXACTLY what I was imagining when designing this part of my game. Thanks again Steve! You're absolutely amazing at this. I can't wait to get stuck in modding it for my game. I have just the way to design triggers for when curves and hills appear, too! (by syncing it to the soundtrack)

Unfortunately the only AGS version I have on me is 3.1.2 (I haven't upgraded my game to 3.2 simply because I didn't need the new functions yet) and the studio computers I'm using don't allow me to use the 3.2 installer! Woe. So I'll have to wait until I get my laptop/PC back before I can mess around with this code!
Title: Re: Pseudo-3D rendering (line based)
Post by: Sslaxx on Sun 07/11/2010 19:08:05
Where does it say it's 3.2 only?
Title: Re: Pseudo-3D rendering (line based)
Post by: Scavenger on Sun 07/11/2010 19:42:44
Quote from: Sslaxx on Sun 07/11/2010 19:08:05
Where does it say it's 3.2 only?

Opening the demo in 3.1.2 says so. Since it was probably made in 3.2. The code could most probably work in 3.1.2 (I would install 3.2 but I physically cannot on the computer I'm using, since I don't have admin privileges), but I can't open the demo in 3.1.2 to test it out and I didn't want to manually rip the code.
Title: Re: Pseudo-3D rendering (line based)
Post by: Khris on Sun 07/11/2010 20:21:21
Here's 3.2 as rar: http://db.tt/92dNOg8
Title: Re: Pseudo-3D rendering (line based)
Post by: Wyz on Sun 07/11/2010 23:32:53
That looks amazing Steve! :D

Actually your 'flawed' version Scavenger also looks kind of cool. Looks like you're driving down hill. Anyhow, great stuff to put in a game as mini game. Thanks for this!
Title: Re: Pseudo-3D rendering (line based)
Post by: Ryan Timothy B on Sun 07/11/2010 23:36:25
If I were the one who wrote this (it would take me much longer than it did you :P), I would do the road first then I would do the lines on the road.
That way you can do proper AA with the lines and not have them look as chunky. That's the only thing really holding this work back.

Since the road is mainly just one color, the lines are the only things that need that special touch.

Actually, the outside lines aren't so bad. It's mostly the center line. Perhaps it's mostly the image itself?
Title: Re: Pseudo-3D rendering (line based)
Post by: Khris on Mon 08/11/2010 10:46:08
Here's my take on that:

(http://img51.imageshack.us/img51/1940/scrnshotv.png)

http://dl.dropbox.com/u/995571/Racer.rar

Tried to build Laguna Seca. In the desert :)

Edit: Btw, it's WASD, Esc to quit.
Title: Re: Pseudo-3D rendering (line based)
Post by: Dualnames on Mon 08/11/2010 10:49:56
YAY!!! WASD controls, just never felt better!! Reminds me of Lotus. Well, damn everything reminds me of Lotus.
Title: Re: Pseudo-3D rendering (line based)
Post by: Calin Leafshade on Mon 08/11/2010 10:51:19
You know, they used to employ *teams* for this shit.
Title: Re: Pseudo-3D rendering (line based)
Post by: abstauber on Mon 08/11/2010 10:59:18
Argh, I can't get the Outrun theme out of my head... again.

Terrific work, Steve & Khris.

Title: Re: Pseudo-3D rendering (line based)
Post by: Monsieur OUXX on Mon 08/11/2010 12:10:37
I demand all the source codes to be released, every single one of them.
Title: Re: Pseudo-3D rendering (line based)
Post by: RickJ on Mon 08/11/2010 13:11:14
Quote
RickJ started with something similar, called DemoCycle.

Actually DemoCycle was originally created by Spyros and others (as far as I was able to determine) when DemoQuest was upgraded to include the games factory.  Many years later I updated the source code to be compatible whit a more recent version of AGS.  AGS didn't have modules at the time.

I have been thinking about upgrading DemoCycle for sometime now.   The two things I want to accomplish are

1) refactoring the main part of the code into one or more reuseable modules.
2) what Khris and Steve done ;D

Khris, if you don't mind contributing what you have done (or are doing) I would use that as a basis for upgrading DemoCycle.  Thanks Khris and Steve...
Title: Re: Pseudo-3D rendering (line based)
Post by: Khris on Mon 08/11/2010 13:41:55
The code is pretty messy right now; I might have a go and rewrite some of it. Whether I do or not, I'll post the source soon.
Title: Re: Pseudo-3D rendering (line based)
Post by: Monsieur OUXX on Mon 08/11/2010 15:08:32
Quote from: Khris on Mon 08/11/2010 13:41:55
The code is pretty messy right now; I might have a go and rewrite some of it. Whether I do or not, I'll post the source soon.

I've heard that before! :-D
A zip, an upload, or I'll kill your dog, rape your family, and burn your house.
Title: Re: Pseudo-3D rendering (line based)
Post by: Kweepa on Mon 08/11/2010 15:18:34
Nice job!
Now we "just" need some AI for the other cars!
Oh, and hills I suppose.
Chase HQ, here we come.
Title: Re: Pseudo-3D rendering (line based)
Post by: abstauber on Mon 08/11/2010 15:38:33
(http://shatten.sonores.de/wp-content/uploads/2010/11/newspaper.jpg)
Title: Re: Pseudo-3D rendering (line based)
Post by: RickJ on Mon 08/11/2010 16:01:45
Hehehe!   

abstauber, you should have pasted his thumb-nail into your article.    ;D


Btw, apparently I am mor patient and less  violent than Mr OUXX
Title: Re: Pseudo-3D rendering (line based)
Post by: Khris on Mon 08/11/2010 20:28:03
Well, the code is like a zombie with lots of makeup and band-aids trying to pose as a human. I'm not going to release it in its current form.
The driving physics also still needs a lot of work.

On the subject of hills: I guess some 2D raycasting would be needed for that; the main problem for me is to come up with a nice way of implementing smooth hills. I've thought of using bézier curves or parabolas, both are a nightmare to raycast though.

Btw, the car sprite and music are ripped from Lotus III on the Amiga (http://www.mobygames.com/game/amiga/lotus-the-ultimate-challenge/screenshots) and a Lotus III gameplay vid on youtube (http://www.youtube.com/watch?v=jlYAohY7wYA), respectively.
Title: Re: Pseudo-3D rendering (line based)
Post by: Alan v.Drake on Mon 08/11/2010 21:12:09
Quote from: Khris on Mon 08/11/2010 20:28:03
[...] Lotus III on the Amiga [...]

Lotus III intro song is now playing on your mind
Title: Re: Pseudo-3D rendering (line based)
Post by: Kweepa on Mon 08/11/2010 21:14:41
Quote from: Khris on Mon 08/11/2010 20:28:03
On the subject of hills: I guess some 2D raycasting would be needed for that; the main problem for me is to come up with a nice way of implementing smooth hills. I've thought of using bézier curves or parabolas, both are a nightmare to raycast though.

My thoughts exactly!
However, have you looked at Chase HQ on the Spectrum? http://www.youtube.com/watch?v=onhV55pUejk
This looks awesome, and presumably is doing something relatively cheap...
Title: Re: Pseudo-3D rendering (line based)
Post by: Dualnames on Mon 08/11/2010 21:20:24
Me and my brother used to spent HOURS on Lotus. One of the best games of my childhood.  :D
Title: Re: Pseudo-3D rendering (line based)
Post by: abstauber on Tue 09/11/2010 08:53:02
The internet never forgets :D

http://web.archive.org/web/20071109204800/http://www.gorenfeld.net/lou/pseudo/


Lou's version has hills and the archive has the code :=
Title: Re: Pseudo-3D rendering (line based)
Post by: Scavenger on Tue 09/11/2010 10:24:43
OutRun seems within our grasp now! Seriously, I didn't expect this much of a response. The code people are coming up with is truly a marvel.

Quote from: abstauber on Tue 09/11/2010 08:53:02
The internet never forgets :D

http://web.archive.org/web/20071109204800/http://www.gorenfeld.net/lou/pseudo/


Lou's version has hills and the archive has the code :=

It also seems to have double roads! Awesome. Great for nonlinear paths. This should be an invaluable resource. I wonder why he removed the code, though.
Title: Re: Pseudo-3D rendering (line based)
Post by: Kweepa on Tue 09/11/2010 14:45:17
Quote from: Scavenger on Tue 09/11/2010 10:24:43
I wonder why he removed the code, though.

He was probably looking for a programming job and didn't want this old code to be representative of his work.
Nicely restored, abs!

EDIT: Hmm, I looked at the code... I don't see any support for double roads. It's not pretty, but that's typical of Allegro and straight C I guess.
Title: Re: Pseudo-3D rendering (line based)
Post by: abstauber on Tue 09/11/2010 15:03:32
Avoiding work is my forte ;)
Title: Re: Pseudo-3D rendering (line based)
Post by: Shane 'ProgZmax' Stevens on Tue 09/11/2010 23:54:48
Hah Khris, that's cute ^_^.  The car reminds me of the wayback days when I played Rad Racer for the Nintendo World Championships (I got second place in the 12-17 group).
Title: Re: Pseudo-3D rendering (line based)
Post by: Wonkyth on Fri 12/11/2010 12:15:13
Quote from: Khris on Mon 08/11/2010 20:28:03
On the subject of hills: I guess some 2D raycasting would be needed for that; the main problem for me is to come up with a nice way of implementing smooth hills. I've thought of using bézier curves or parabolas, both are a nightmare to raycast though.
Out of curiousity, what makes bézier curves/surfaces so difficult to raycast?
I've spent a great deal of time recently working with  bézier curves for 2D physics, and would be interested to know what problems occur when using the in graphics.
Title: Re: Pseudo-3D rendering (line based)
Post by: Khris on Fri 12/11/2010 12:25:18
It's actually not as bad as I had expected, on the contrary in fact. I'm in the middle of implementing hills and a few other things, it's just that my fast and dirty code still sometimes tumbles over its own feet.

I think I've also come up with a fast way of handling the z-sorting that became necessary when moving away from a flat track.