• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM SuperFX like 3D

I want to make a 3d system where it scales sprites to make objects and such (like what starfox 2 does), how can i do it without d3d?
(because i like it looking authentic)
 

Nocturne

Friendly Tyrant
Forum Staff
Admin

The only sprites in the game are those used for the HUD and the main UI, while the gameplay itself is all rastered polygons without any sprites being used, scaled or otherwise. Do you maybe mean something more akin to Space Harrier?

 
The only sprites in the game are those used for the HUD and the main UI, while the gameplay itself is all rastered polygons without any sprites being used, scaled or otherwise. Do you maybe mean something more akin to Space Harrier?
Mostly polygons, but there are a good number of sprites in the SNES Star Fox games, too. Things like explosions, asteroids, the Arwing's afterburner and some of the projectiles are all obviously scaled sprites. (Go to the 20min mark...the first person levels used sprites more than the rest of the game, iirc.)

The main look of the games comes from those cool untextured polygons though, yeah. And the SNES already did scaled sprites without the FX chip, so "SuperFX like graphics" definitely means polygons over "scaled sprites" to me, hahah.
 
I want to make a 3d system where it scales sprites to make objects and such (like what starfox 2 does), how can i do it without d3d?
(because i like it looking authentic)
The way I'm doing it at the moment is to give all my instances a "z" value indicating their position on the z-axis. I call mine z3D, because it turns out you also need to adjust the x and y position as well based on distance from the camera. So my instances have an x3D and y3D value as well to track the so called "real world" position of the instance. I needed to track these values separately from the built-in x and y, because I still use the x and y values to draw the actual final position of the scaled sprite.

Then, for the sprite size, each step, I scale the instances sprite by (1/z3D)

Code:
var _scale = 1 / z3D;
image_xscale = _scale;
image_yscale = _scale;
And then I need to calculate the x and y (the position on the screen I need to draw the sprite) position based on their "world position" of x3D and y3D.

Code:
x = (x3D / z3D) + global.half_screen_width;
y = (y3D / z3D) + global.half_screen_height;
Thats the basics of it. There is more to it when you have a camera that needs to move around the "world", but if your camera is static, this should work.

So in the above system, you don't update the x and y yourself to control the sprite, when doing movement of your sprites, your code should update the x3D, y3D, and z3D values only, and let the code above calculate the actual screen x and y and scale for you.

Actually, its getting to the point where I might just shift to using the built in set_matrix(matrix_world/view/projection) functions and perspective camera settings because I ended up having to calculate all this stuff in GML, where I suspect the built-in functions will be faster. My point is, you can do all this by hand, but in the end, you're just doing the stuff that the d3d functions do natively anyway.
 
The way I'm doing it at the moment is to give all my instances a "z" value indicating their position on the z-axis. I call mine z3D, because it turns out you also need to adjust the x and y position as well based on distance from the camera. So my instances have an x3D and y3D value as well to track the so called "real world" position of the instance. I needed to track these values separately from the built-in x and y, because I still use the x and y values to draw the actual final position of the scaled sprite.

Then, for the sprite size, each step, I scale the instances sprite by (1/z3D)

Code:
var _scale = 1 / z3D;
image_xscale = _scale;
image_yscale = _scale;
And then I need to calculate the x and y (the position on the screen I need to draw the sprite) position based on their "world position" of x3D and y3D.

Code:
x = (x3D / z3D) + global.half_screen_width;
y = (y3D / z3D) + global.half_screen_height;
Thats the basics of it. There is more to it when you have a camera that needs to move around the "world", but if your camera is static, this should work.

So in the above system, you don't update the x and y yourself to control the sprite, when doing movement of your sprites, your code should update the x3D, y3D, and z3D values only, and let the code above calculate the actual screen x and y and scale for you.

Actually, its getting to the point where I might just shift to using the built in set_matrix(matrix_world/view/projection) functions and perspective camera settings because I ended up having to calculate all this stuff in GML, where I suspect the built-in functions will be faster. My point is, you can do all this by hand, but in the end, you're just doing the stuff that the d3d functions do natively anyway.
the camara will move.
and rotate
 
I can't help you with camera rotations, but for movement, you just need to keep track of the cameras x, y, z.

Then you use the camera's location to calculate the position of the instance in from the camera's viewpoint, and apply that to the instance's x and y as before.

Here's what I use at the moment. This code runs in the Step Event of all my objects that I want to use the 3d scaling effect.

Code:
// Calc view position relative to camera
view_x = x_3D - o3DCamera.cam_x;
view_y = y_3D - o3DCamera.cam_y;
view_z = z_3D - o3DCamera.cam_z;

x = (view_x / view_z) + global.half_screen_width;
y = (view_y / view_z) + global.half_screen_height;
 
Top